Tuesday, November 22, 2016

Deleting a single document from the Solr index

You may need to delete a single document from the Solr index at some time. This is a several step process if you use the Solr Admin UI.

1. Navigate to the Solar Admin UI in your web browser, select your core, and go to the Documents page.

2. Change the "Document Type" dropdown to "Solr Command" and enter the following text in the "Document(s)" field (change the "doc_1" text to the actual id of your document):

<delete><query>id:doc_1</query></delete>



3. Press the submit button to delete the document.

4. Enter the following text in the "Document(s)" field:

<commit/>



5. Press the submit button again to tell the Solr index to update the index (otherwise the changes will not show up in the Blacklight search interface)

6. Search for the document in the Blacklight search interface to see if the document has been successfully deleted.




Tuesday, June 14, 2016

Troubleshooting using the Rails production log

If you are still receiving the default Rails error screen, you can find the production log file to debug at

/home/username/public_html/test-app/log/production.log

Download this file and open it to see what errors are occurring

Restarting the Passenger app

To make sure that all configuration changes have taken effect, we need to restart the app through Passenger.

To restart the app through Passenger at any time, connect to the VPS and change directories to the app's home directory:

# cd /home/username/public_html/test-app

Next, run the following command:

# passenger-config restart-app

After you restart the app, go to your app's URL (example.com), and refresh the page to see if the changes have taken effect.

At this point, you hopefully see the Blacklight interface replace any errors that were on the screen in your web browser.


Previous post: Update Solr's solrconfig file

Next post: Troubleshooting using the Rails production log

Update Solr's solrconfig file

We also need to edit Solr's solrconfig.xml file to reflect the custom schema we are using. This also has to do with Solr communicating with Blacklight, which is not set up correctly because we used a separately installed Solr instance instead of installing it through Blacklight's installation.

1. Download and open up the solrconfig.xml file found at

/home/username/solr/solr-5.3.0/server/solr/blacklight-core/conf/solrconfig.xml

2. BL expects the <requestDispatcher> to have a handleSelect value of “true” because BL uses a “qt” equal to “search” or “document”. For Solr to recognize these as valid search operations, requestDispatcher needs to be changed. Find the <requestDispatcher> section in the solrconfig.xml file and replace it with:

<requestDispatcher handleSelect="true" >
  <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" />
</requestDispatcher>


3. Delete the requestHandler that has the name=“/select” attribute from the solrconfig.xml file. This will interfere with Blacklight looking for the “search” requestHandler.

***Make sure to DELETE it and not just comment it out. For some reason just commenting out doesn’t work ***

4. The requestHandlers Blacklight is expecting need to be created in the solrconfig.xml file. Using a solrconfig.xml file from a Blacklight installation that was installed with the --jettywrapper option, we can copy the “search” “document” and “advanced” request handlers into our solrconfig.xml file. These three handlers do not exist in solrconfig.xml by default.

****Because the catalog_controller.rb file can control the display of facet fields, we can go ahead and comment out any <str name="facet.field"> sections in the “search” requestHandler in solrconfig.xml****

****To control the fields that are searched when searching with a keyword, go to solrconfig.xml, go to the “search” requestHandler, and find the <str name="qf"> and <str name=“pf"> sections. These stand for “query fields” and “phrase fields”. Replace all of the fields currently listed in these two sections with the fields you want to be keyword-searched by BL. If you want to “boost” any of the fields you can add the “^” symbol followed by a number.****

Here are examples of the “search”, “document”, and “advanced” requestHandler sections, which will look something like this after editing to include our indexed field names, into the solrconfig.xml below the requestDispatcher section and just after the opening comments of the Request Handlers section:


<requestHandler name="search" class="solr.SearchHandler" default="true">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
     <lst name="defaults">
       <str name="defType">dismax</str>
       <str name="echoParams">explicit</str>
       <int name="rows">10</int>

       <str name="q.alt">*:*</str>
       <str name="mm">2&lt;-1 5&lt;-2 6&lt;90%</str>

       <!-- this qf and pf are used by default, if not otherwise specified by
            client. The default blacklight_config will use these for the
            "keywords" search. See the author_qf/author_pf, title_qf, etc
            below, which the default blacklight_config will specify for
            those searches. You may also be interested in:
            http://wiki.apache.org/solr/LocalParams
       -->

       <str name="qf">
        field1_txt
        field2_txt
        field3_txt
       </str>
       <str name="pf">
        field1_txt
        field2_txt
        field3_txt
       </str>
      
       <!--
       <str name="author_qf">
         author_unstem_search^200
         author_addl_unstem_search^50
         author_t^20
         author_addl_t
       </str>
       <str name="author_pf">
         author_unstem_search^2000
         author_addl_unstem_search^500
         author_t^200
         author_addl_t^10
       </str>
       <str name="title_qf">
         title_unstem_search^50000
         subtitle_unstem_search^25000
         title_addl_unstem_search^10000
         title_t^5000
         subtitle_t^2500
         title_addl_t^100
         title_added_entry_unstem_search^50
         title_added_entry_t^10
         title_series_unstem_search^5
         title_series_t
       </str>
       <str name="title_pf">
         title_unstem_search^500000
         subtitle_unstem_search^250000
         title_addl_unstem_search^100000
         title_t^50000
         subtitle_t^25000
         title_addl_t^1000
         title_added_entry_unstem_search^500
         title_added_entry_t^100
         title_series_t^50
         title_series_unstem_search^10
       </str>
       <str name="subject_qf">
         subject_topic_unstem_search^200
         subject_unstem_search^125
         subject_topic_facet^100
         subject_t^50
         subject_addl_unstem_search^10
         subject_addl_t
       </str>
       <str name="subject_pf">
         subject_topic_unstem_search^2000
         subject_unstem_search^1250
         subject_t^1000
         subject_topic_facet^500
         subject_addl_unstem_search^100
         subject_addl_t^10
       </str>
       -->
      
       <int name="ps">3</int>
       <float name="tie">0.01</float>

       <!-- NOT using marc_display because it is large and will slow things down for search results -->
       <str name="fl">
         id,
         score,
         field1_txt,
         field2_txt,
         field3_txt
       </str>

       <str name="facet">true</str>
       <str name="facet.mincount">1</str>
       <str name="facet.limit">40</str>
      
       <!--
       <str name="facet.field">subject_topic_facet</str>
       -->
      
       <str name="spellcheck">true</str>
       <str name="spellcheck.dictionary">default</str>
       <str name="spellcheck.onlyMorePopular">true</str>
       <str name="spellcheck.extendedResults">true</str>
       <str name="spellcheck.collate">false</str>
       <str name="spellcheck.count">5</str>

     </lst>
    <!-- In addition to defaults, "appends" params can be specified
         to identify values which should be appended to the list of
         multi-val params from the query (or the existing "defaults").
      -->
    <!-- In this example, the param "fq=instock:true" would be appended to
         any query time fq params the user may specify, as a mechanism for
         partitioning the index, independent of any user selected filtering
         that may also be desired (perhaps as a result of faceted searching).

         NOTE: there is *absolutely* nothing a client can do to prevent these
         "appends" values from being used, so don't use this mechanism
         unless you are sure you always want it.
      -->
    <!--
       <lst name="appends">
         <str name="fq">inStock:true</str>
       </lst>
      -->
    <!-- "invariants" are a way of letting the Solr maintainer lock down
         the options available to Solr clients.  Any params values
         specified here are used regardless of what values may be specified
         in either the query, the "defaults", or the "appends" params.

         In this example, the facet.field and facet.query params would
         be fixed, limiting the facets clients can use.  Faceting is
         not turned on by default - but if the client does specify
         facet=true in the request, these are the only facets they
         will be able to see counts for; regardless of what other
         facet.field or facet.query params they may specify.

         NOTE: there is *absolutely* nothing a client can do to prevent these
         "invariants" values from being used, so don't use this mechanism
         unless you are sure you always want it.
      -->
    <!--
       <lst name="invariants">
         <str name="facet.field">cat</str>
         <str name="facet.field">manu_exact</str>
         <str name="facet.query">price:[* TO 500]</str>
         <str name="facet.query">price:[500 TO *]</str>
       </lst>
      -->
    <!-- If the default list of SearchComponents is not desired, that
         list can either be overridden completely, or components can be
         prepended or appended to the default list.  (see below)
      -->
    <!--
       <arr name="components">
         <str>nameOfCustomComponent1</str>
         <str>nameOfCustomComponent2</str>
       </arr>
      -->
    <arr name="last-components">
      <str>spellcheck</str>
    </arr>
     
  </requestHandler>


<!-- for requests to get a single document; use id=666 instead of q=id:666 -->
  <requestHandler name="document" class="solr.SearchHandler" >
    <lst name="defaults">
      <str name="echoParams">all</str>
      <str name="fl">*</str>
      <str name="rows">1</str>
      <str name="q">{!raw f=id v=$id}</str> <!-- use id=666 instead of q=id:666 -->
    </lst>
  </requestHandler>
 
 
  <!--  For Advanced Search  -->
  <requestHandler name="advanced" class="solr.SearchHandler" >
    <lst name="defaults">
      <str name="defType">lucene</str>
      <str name="echoParams">explicit</str>
      <str name="sort">score desc, pub_date_sort desc, title_sort asc</str>  
      <str name="df">text</str>
      <str name="q.op">AND</str>
      <str name="qs">1</str>

      <!-- used for dismax query parser -->
      <str name="mm">1</str>
      <str name="ps">3</str>
      <float name="tie">0.01</float>
     
      <!-- for user query terms in author text box -->
      <str name="qf_author">
        author_unstem_search^200
        author_addl_unstem_search^50
        author_t^20
        author_addl_t
      </str>
      <str name="pf_author">
        author_unstem_search^2000
        author_addl_unstem_search^500
        author_t^200
        author_addl_t^10
      </str>
     
      <!-- for user query terms in title text box -->
      <str name="qf_title">
        title_unstem_search^50000
        subtitle_unstem_search^25000
        title_addl_unstem_search^10000
        title_t^5000
        subtitle_t^2500
        title_addl_t^100
        title_added_entry_unstem_search^50
        title_added_entry_t^10
        title_series_unstem_search^5
        title_series_t
      </str>
      <str name="pf_title">
        title_unstem_search^500000
        subtitle_unstem_search^250000
        title_addl_unstem_search^100000
        title_t^50000
        subtitle_t^25000
        title_addl_t^1000
        title_added_entry_unstem_search^500
        title_added_entry_t^100
        title_series_t^50
        title_series_unstem_search^10
      </str>
     
      <!-- for user query terms in subject text box -->
      <str name="qf_subject">
        subject_topic_unstem_search^200
        subject_unstem_search^125
        subject_topic_facet^100
        subject_t^50
        subject_addl_unstem_search^10
        subject_addl_t
      </str>
      <str name="pf_subject">
        subject_topic_unstem_search^2000
        subject_unstem_search^1250
        subject_t^1000
        subject_topic_facet^500
        subject_addl_unstem_search^100
        subject_addl_t^10
      </str>
     
      <!-- for user query terms in number text box -->
      <str name="qf_number">isbn_t</str>
     
      <!-- for user query terms in keyword text box -->
      <str name="qf_keyword">text</str>
      <str name="pf_keyword">text^10</str>
     
      <!-- NOT using marc_display because it is large and will slow things down for search results -->
      <str name="fl">
        id,
        score,
        author_display,
        author_vern_display,
        format,
        isbn_t,
        language_facet,
        lc_callnum_display,
        material_type_display,
        published_display,
        published_vern_display,
        pub_date,
        title_display,
        title_vern_display,
        subject_topic_facet,
        subject_geo_facet,
        subject_era_facet,
        subtitle_display,
        subtitle_vern_display,
        url_fulltext_display,
        url_suppl_display,
      </str>
     
      <str name="facet">true</str>
      <str name="facet.mincount">1</str>
      <str name="facet.limit">10</str>
      <str name="facet.field">format</str>
      <str name="facet.field">lc_1letter_facet</str>
      <str name="facet.field">lc_alpha_facet</str>
      <str name="facet.field">lc_b4cutter_facet</str>
      <str name="facet.field">language_facet</str>
      <str name="facet.field">pub_date</str>
      <str name="facet.field">subject_era_facet</str>
      <str name="facet.field">subject_geo_facet</str>
      <str name="facet.field">subject_topic_facet</str>
     
      <str name="spellcheck">true</str>
      <str name="spellcheck.dictionary">subject</str>
      <str name="spellcheck.onlyMorePopular">true</str>
      <str name="spellcheck.extendedResults">true</str>
      <str name="spellcheck.collate">false</str>
      <str name="spellcheck.count">5</str>
    </lst>
    <arr name="last-components">
      <str>spellcheck</str>
    </arr>
  </requestHandler>


5. In addition to the “search” “document” and “advanced” requestHandlers, the Blacklight solrconfig.xml file has additional requestHandlers that are not in the default solrconfig.xml file. Copy the following requestHandler sections from the Blacklight solrconfig.xml to the custom solrconfig.xml file and place them above the “search” requestHandler:

<requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy" />
<requestHandler name="standard" class="solr.StandardRequestHandler" />
<requestHandler name="/update" class="solr.UpdateRequestHandler"  />
<requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
    
<requestHandler name="/admin/ping" class="solr.PingRequestHandler">
   <lst name="invariants">
     <str name="q">solrpingquery</str>
   </lst>
   <lst name="defaults">
     <str name="echoParams">all</str>
   </lst>
</requestHandler>


6. We also need to copy the <searchComponent name="spellcheck" class="solr.SpellCheckComponent"> section from an existing Blacklight solrconfig.xml into our solrconfig.xml file and place it after the last existing searchComponent section:

<!-- Spell Check

        The spell check component can return a list of alternative spelling
        suggestions. 

        http://wiki.apache.org/solr/SpellCheckComponent
     -->
  <searchComponent name="spellcheck" class="solr.SpellCheckComponent">

    <str name="queryAnalyzerFieldType">textSpell</str>

    <!-- Multiple "Spell Checkers" can be declared and used by this
         component
      -->

    <!-- a spellchecker built from a field of the main index, and
         written to disk
      -->
    <lst name="spellchecker">
      <str name="name">default</str>
      <str name="field">spell</str>
      <str name="spellcheckIndexDir">./spell</str>
      <str name="buildOnOptimize">true</str>
    </lst>
    <lst name="spellchecker">
      <str name="name">author</str>
      <str name="field">author_spell</str>
      <str name="spellcheckIndexDir">./spell_author</str>
      <str name="accuracy">0.7</str>
      <str name="buildOnOptimize">true</str>
    </lst>
    <lst name="spellchecker">
      <str name="name">subject</str>
      <str name="field">subject_spell</str>
      <str name="spellcheckIndexDir">./spell_subject</str>
      <str name="accuracy">0.7</str>
      <str name="buildOnOptimize">true</str>
    </lst>
    <lst name="spellchecker">
      <str name="name">title</str>
      <str name="field">title_spell</str>
      <str name="spellcheckIndexDir">./spell_title</str>
      <str name="accuracy">0.7</str>
      <str name="buildOnOptimize">true</str>
    </lst>

    <!-- a spellchecker that uses a different distance measure -->
    <!--
       <lst name="spellchecker">
         <str name="name">jarowinkler</str>
         <str name="field">spell</str>
         <str name="distanceMeasure">
           org.apache.lucene.search.spell.JaroWinklerDistance
         </str>
         <str name="spellcheckIndexDir">spellcheckerJaro</str>
       </lst>
     -->

    <!-- a spellchecker that use an alternate comparator

         comparatorClass be one of:
          1. score (default)
          2. freq (Frequency first, then score)
          3. A fully qualified class name
      -->
    <!--
       <lst name="spellchecker">
         <str name="name">freq</str>
         <str name="field">lowerfilt</str>
         <str name="spellcheckIndexDir">spellcheckerFreq</str>
         <str name="comparatorClass">freq</str>
         <str name="buildOnCommit">true</str>
      -->

    <!-- A spellchecker that reads the list of words from a file -->
    <!--
       <lst name="spellchecker">
         <str name="classname">solr.FileBasedSpellChecker</str>
         <str name="name">file</str>
         <str name="sourceLocation">spellings.txt</str>
         <str name="characterEncoding">UTF-8</str>
         <str name="spellcheckIndexDir">spellcheckerFile</str>
       </lst>
      -->
  </searchComponent>


7. Use the FTP program to replace the solrconfig.xml file on the server with the one you just edited.

8. Go to the Terminal window in which you are logged in as root and navigate to

/home/username/solr/solr-5.3.0

9. Stop and restart the solar service again so the new solrconfig.xml edits will take effect:

# bin/solr stop -all
# bin/solr restart



Previous post: Update Blacklight's catalog_controller file

Next post:

Update Blacklight's catalog_controller file

We need to update the Blacklight app's catalog_controller file to match the schema fields we added to the Solr schema configuration file.

1. With a FTP program, download Blacklight’s CatalogController file found at

/home/username/public_html/test-app/app/controllers/catalog_controller.rb

2. Open it in a text editor and begin editing by making the config.default_solr_params array look like:

config.default_solr_params = {
  qt: 'search',
  rows: 10
}


3. Uncomment the following line (by deleting the hash symbol) so it looks like:

config.per_page = [10,20,50,100]

You can change the numbers inside the array if you want to change the options users see for the number of results shown on the screen.

4. Also uncomment the following array so it looks like:

config.default_document_solr_params = {
      qt: 'document',
      ## These are hard-coded in the blacklight 'document' requestHandler
       fl: '*',
       rows: 1,
       q: '{!term f=id v=$id}'
    }


5. Change the following lines:

# solr field configuration for search results/index views
config.index.title_field = 'title_display'
config.index.display_type_field = 'format'

# solr field configuration for document/show views
#config.show.title_field = 'title_display'
#config.show.display_type_field = 'format'


to:

# solr field configuration for search results/index views
config.index.title_field = 'field1_txt'
#config.index.display_type_field = 'format'

# solr field configuration for document/show views
config.show.title_field = 'field1_txt'
#config.show.display_type_field = 'format'


where "field1_txt" is the name of whichever field you want to show as the title of the individual record.

6. Edit the existing config.add_facet_field lines in the config.add_facet_field section to use your schema's field names: 

config.add_facet_field 'field1Facet', label: 'Field 1', limit: 10
config.add_facet_field 'field2Facet', label: 'Field 2', limit: 15


You can also add label names for the facets and define limits on teh number of facet options displayed. For further customization of the facet fields, see the Blacklight site.

7. Also, to ensure facet fields are shown, make sure that the following line is not commented out:

config.add_facet_fields_to_solr_request!

8. Edit the existing config.add_index_field lines and add fields that you want to display in the results list to the config.add_index_field section:

config.add_index_field 'field2_txt', label: 'Field 2'
config.add_index_field 'field3_txt', label: 'Field 3', link_to_search: 'field3Facet'


You can use the link_to_search helper to create a search shortcut. For further customization of this section, see the Blacklight online guide.

9. Edit the existing config.add_show_field lines and add fields to the config.add_show_field section that you want to see displayed in the individual result page:

config.add_show_field 'field2_txt', label: 'Field 2'
config.add_show_field 'field3_txt', label: 'Field 3'


10. Comment out all lines of the following sections by placing hashtag symbols at the beginning of each line:

config.add_search_field('title') do |field|
  # solr_parameters hash are sent to Solr as ordinary url query params.
  field.solr_parameters = { :'spellcheck.dictionary' => 'title' }

  # :solr_local_parameters will be sent using Solr LocalParams
  # syntax, as eg {! qf=$title_qf }. This is neccesary to use
  # Solr parameter de-referencing like $title_qf.
  # See: http://wiki.apache.org/solr/LocalParams
  field.solr_local_parameters = {
    qf: '$title_qf',
    pf: '$title_pf'
  }
end

config.add_search_field('author') do |field|
  field.solr_parameters = { :'spellcheck.dictionary' => 'author' }
  field.solr_local_parameters = {
    qf: '$author_qf',
    pf: '$author_pf'
  }
end

# Specifying a :qt only to show it's possible, and so our internal automated
# tests can test it. In this case it's the same as
# config[:default_solr_parameters][:qt], so isn't actually neccesary.
config.add_search_field('subject') do |field|
  field.solr_parameters = { :'spellcheck.dictionary' => 'subject' }
  field.qt = 'search'
  field.solr_local_parameters = {
    qf: '$subject_qf',
    pf: '$subject_pf'
  }
end


11. Edit the existing config.add_sort_field lines to use fieldnames that you would like the user to be able to sort the results:

config.add_sort_field 'score desc, field1_txt asc', label: 'Relevance'
config.add_sort_field 'field1_txt asc', label: 'Field 1'


12. Save the catalog_controller.rb file and use the FTP program to replace the server copy with the copy you just edited.


Previous post: Update Solr schema configuration

Next post: Update Solr's solrconfig file

Monday, June 13, 2016

Update Solr schema configuration

We need to update the default Solr configuration to work with our data. We also need to upload some initial data into the Solr index before the Rails app and Passenger will display the Blacklight app interface on the screen.

Creating the new Solr core


1. Using Terminal, connect to the VPS as the root user:

$ ssh root@example.com

2. Change directories into the solr directory:

# cd /home/username/solr/solr-5.3.0

3. In a web browser, check to see if Solr is already running by going to

example.com:8983

If it is, skip the following start up step. If it is not running, start the Solr service with the following command in Terminal:

# bin/solr start -noprompt

4. Create a Solr core for the Blacklight data using the basic_configs instead of the default data_driven_schema_configs (these can be found at solr-5.3.0/server/solr/configsets and are copied in during the core creation):

# bin/solr create -c blacklight-core -d basic_configs

5. The new core should now have a directory at

/home/username/solr/solr-5.3.0/server/solr/blacklight-core

6. Refresh the Solr admin UI in the web browser to confirm the new core is created and accessible.

Updating the default Solr schema


7. The blacklight-core collection in Solr is currently using the default scheme found at

/home/username/solr/solr-5.3.0/server/solr/blacklight-core/conf/schema.xml

The Blacklight interface is not set up to use this schema. Edits to both the Blacklight settings and the Solr schema will be necessary.

8. Download the schema.xml file using a FTP program and open it in a text editor.

9. I explicitly defined a number of fields by adding the lines such as the following below the <field name=“id” … /> line:

<field name="field1_txt" type="text_general" indexed="true" stored="true" multiValued="true"/>
<field name="field1Facet" type="string" indexed="true" stored="false" multiValued="true"/>
  
<field name="field2_txt" type="text_general" indexed="true" stored="true" multiValued="false"/>


As the fields above indicate, some of the fields I defined were multivalued="true" and some were multivalued="false". This depended on whether the field would be used as a sort field because it appears sort fields can only be multivalued="false".

Create as many field names as you need to fill out your schema.

10. Go down in the schema.xml file below the <uniqueKey> line and add the following copyFields:

<copyField source="field1_txt" dest="field1Facet"/>

This copies the value of the source field into an additional field "as is" instead of being reformatted as part of the indexing process. This is necessary for the Facet options to show up correctly, so do this for any fields you plan to use as facets.

11. Save the schema.xml file and use the FTP program to replace the copy on the server with the copy you just edited.

12. In terminal, restart the solar service with the following two commands:

$ bin/solr stop -all
$ bin/solr restart

13. Use the FTP program to upload your data document (we'll call it "data.json") to be indexed to the folder

/home/username/solr/solr-5.3.0/

14. Index the data document into the Solr index by running the following Terminal command:

$ bin/post -c blacklight-core data.json

15. Refresh the Solr Admin UI in the web browser to confirm the document was indexed (there should be many more docs in the index now)

Errors will still appear on the Blacklight interface because Blacklight’s CatalogController is looking for certain fields that are not in the schema.


Previous post: Determine Ruby command for Passenger and update configuration files

Next post: Update Blacklight's catalog_controller file


Determine Ruby command for Passenger and update configuration files

Passenger needs to know which Ruby command to use to run the app. We will determine the command and then add it to the Apache configuration files. 

1. In Terminal, located in the app's home directory, determine the Ruby command for Passenger with the following command:

# passenger-config about ruby-command

The text after "Command:" in the response you receive will be used later.

2. Open a new FTP connection logged in as root user to example.com.

3. In the new FTP connection, go to the folder located at /usr/local/apache/conf/

4. Create a folder “user data” in the conf folder and then the necessary subdirectories so that the following path exists:

/usr/local/apache/conf/userdata/std/2_2/username/example.com/

5. Create a file in Text Wrangler (or some other text editor) and save it as "test-app.conf".

6. Add the following into the test-app.conf file (replace the path after "PassengerRuby" with the output from step 1 above):

# Tell Apache and Passenger where your app's 'public' directory is
DocumentRoot /home/username/www/test-app/public

PassengerRuby /home/username/.rvm/gems/ruby-2.2.4/wrappers/ruby


# Relax Apache security settings
<Directory /home/username/www/test-app/public>
Allow from all
Options -MultiViews
# Uncomment this if you're on Apache >= 2.4:
#Require all granted
</Directory>


7. Use the FTP program to upload the test-app.conf file to the path /usr/local/apache/conf/userdata/std/2_2/username/example.com/

8. Download the Apache configuration file located at /usr/local/apache/conf/httpd.conf

9. Edit the <VirtualHost> section that contains

DocumentRoot /home/username/public_html

so that the includes statement at the bottom looks like:

# To customize this VirtualHost use an include file at the following location
Include "/usr/local/apache/conf/userdata/std/2_2/username/example.com/test-app.conf"


Now the test-app.conf values will override the default values in the VirtualHost section.

10. Use the FTP program to replace the httpd.conf file on the server with the one you edited.

11. Open a new Terminal window and ssh as root:

$ ssh root@example.com

12. Restart the Apache service:

# service httpd restart

13. Check example.com in a browser to see if anything is showing yet.

It probably won’t show anything yet. We need to set up the Solr index and edit the Solr configuration files!


Previous post: Install Blacklight in the app

Next post: Update Solr schema configuration

Install Blacklight in the app

Next, we need to run a couple of commands to install Blacklight in the Rails app.

Note: If you are familiar with the Blacklight quickstart tutorial, we are not using the --marc or --jettywrapper commands because we are using our own custom Solr installation and data.

1. In Terminal, located in the home directory of the app (/home/username/public_html/test-app), run the following command to begin Blacklight installation:

# rails generate blacklight:install --devise

2. Run the following to compile Rails assets and run database migrations:

# bundle exec rake assets:precompile db:migrate RAILS_ENV=production

If you see errors during this step, they may have to do with the database migration. If you set up your database to have utf8_bin collation, you shouldn't run into a problem.


Previous step: Add the Blacklight gem to the app's Gemfile

Next step: Determine Ruby command for Passenger and update configuration files

Add the Blacklight gem to the app's Gemfile

The app's Gemfile needs to be edited to include the Blacklight gem.

1. Using a FTP program, download the app's Gemfile located in the app's home directory on the server:

/home/username/public_html/test-app/Gemfile

2. Open the downloaded Gemfile in a text editor and add the following lines to the end of the file:

gem 'blacklight', "~> 6.0"
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]


3. Save the file and use the FTP program to replace the original Gemfile on the server with the edited Gemfile.

4. Download the Gemfile.lock file from the nrpp-directory folder to have a backup

5. Delete the Gemfile.lock file from the nrpp-directory folder on the server.

6. Run the bundler command with the no-deployment option to create a new Gemfile.lock file with the Blacklight gems we added:

# bundle install --no-deployment



Previous post: Configure the app's secrets.yml file

Next post: Install Blacklight in the app


Configure the app's secrets.yml file

Rails needs a unique secret key with which to encrypt its sessions.

1. In Terminal, change directories to the app's home directory:

# cd /home/username/public_html/test-app

2. Generate the secret key with the following command:

# bundle exec rake secret

3. Download the secrets.yml from the following location on the server:

/home/username/public_html/test-app/config/secrets.yml

4. Open the downloaded secrets.yml file in a text editor and replace the default secret key value

“<%= ENV["SECRET_KEY_BASE"] %>”

with the secret key generated in Terminal.

5. Use the FTP program to replace the secrets.yml file on the server with the one you just edited

6. Update the git repository with the following two commands:

# git add .
# git commit -m “Updated database.yml and secrets.yml files”


7. While located in the app's home directory, run the following two commands in Terminal to tighten security:

# chmod 700 config db
# chmod 600 config/database.yml config/secrets.yml



Previous post: Configure the app's database.yml file

Next post: Add the Blacklight gem to the app's Gemfile


Configure the app's database.yml file

When the Rails app was created, it has a database configuration file that needs editing to make sure the app is communicating with the MySQL database.

1. Using a FTP program (such as Fetch or FileZilla), download the app's database config file located at

/home/username/www/test-app/config/database.yml

2. Open the database.yml file in a text editor (such as TextWrangler) and add the following to the defaults section under the pool variable:

host: 127.0.0.1

3. Go to the production section in database.yml and change the database and username to:

database: username_test-app_production
username: username_tester


Note that when we created the database we named it test-app_production, but the Bluehost system actually adds your username onto the beginning of the database name. Therefore, the full name of the database includes your username and needs to be used like that.

4. Change the password in the production section of database.yml to the password you set when creating the nrpp database user.

5. Use the FTP program to replace the existing database.yml file on the server with the one you just edited.


Previous post: Create a git repository for the app

Next post: Configure the app's secrets file

Create a git repository for the app

We will install git on our server to initiate a git repository in the app's directory. If you already have git installed, you can skip to the git repository initiation steps.

Install git on the server


To install git on the server, connect to the VPS as the root user using Terminal and run the following command:

# yum install -y git

Initiate git repository


1. In a Terminal window, connect to the VPS as the single user (not root):

$ ssh username@example.com

2. Change directories to the new app's home directory:

# cd /home/username/public_html/test-app

3. Initiate a git repository in this directory with the following command:

# git init

4. Configure the global username for the new repository:

# git config --global user.name "Your name"

5. Configure the global email for the new repository:

# git config --global user.email youremail@email.com

6. Add all of the current files in the directory and sub-directories to the repository:

# git add .

7. Commit the addition of the files to the repository with a commit message:

# git commit -m "Initial git commit"


Previous post: Creating the new Rails app on the web server

Next post: Configure the app's database file

Creating the new Rails app on the web server

The next step is to create the new Rails app.

1. In Terminal, connect to the VPS as the single user if you are not already connected:

$ ssh username@example.com

2. Change directories to the home directory:

# cd /home/username

3. Change directories into the public web directory (this might be "www" or "public_html", or as was in my case both exist with one pointing to the other):

# cd www

4. Create the new Rails app with the MySQL database configuration specified:

# rails new test-app -d mysql

5. After the Rails app creation process finishes, change directories into the the new app's directory:

# cd test-app


Previous post: Installing Passenger

Next post: Create a git repository for the app

Friday, June 10, 2016

Installing Passenger

Blacklight ships with a built in web services package called WEBrick. This package allows the app to communicate with the web server. WEBrick is not recommended for a production deployment, so we will use the web services package Passenger instead.

Note: The Passenger website offers a very good installation tutorial. I used the tutorial for my installation. I will go through the steps I followed here, but the Passenger site tutorial is much more detailed. If you are following this tutorial, but are using a slightly different setup, the tutorial offers information for servers and operating systems other than Apache/Cent OS.

Check your kernel version and SELinux status


1. If not already connected to the VPS as the root user, open a Terminal window and connect to the VPS as the root user:

$ ssh root@example.com

Enter the root user's password when prompted and hit Return to log in.

2. Run the following command to check your kernel version:

# uname -r

The response I recieved was

2.6.32-573.22.1.el6.x86_64

Because my kernel is <=2.6.39 I need to make sure SELinux is disabled (This and other scenarios are covered in the Passenger website's tutorial). If your version is >=2.6.39 you don't need to worry about SELinux.

3. To check SELinnux status, run the following command:

# grep SELINUX /etc/selinux/config

The response I received was

# SELINUX= can take one of these three values:
SELINUX=disabled
# SELINUXTYPE= type of policy in use. Possible values are:
SELINUXTYPE=targeted


showing that my SELinux is already disabled. See the Passenger installation tutorial for more on how to disable SELinux.

Enable EPEL


4. The Passenger website installation tutorial has us enable EPEL next, but we already installed and enabled EPEL when we installed Node.js in an earlier step.

Install Passenger


Bluehost has a help document that outlines the installation of Passenger on a VPS. I chose to follow the instructions of that tutorial that are related to Passenger instead of the instructions outlined on the Passenger website's tutorial. I don't know if the Passenger website's instructions work on the Bluehost CentOS VPS or not, but please leave a comment below if you try it and they do/don't work.

5. In Terminal, connect to the VPS as the root user:

# ssh root@example.com

6. Run the following command to install curl-devel:

# yum install curl-devel

When prompted "Is this ok [y/N]:" type the letter "y" and press Enter.

7. In a new Terminal window, connect to the VPS as the single user:

# ssh username@example.com

8. Change directories to the single user's home directory:

# cd /home/username/

9. Run the following command to install the Passenger gem:

# gem install passenger

The installation will take a few minutes. This is what I saw in Terminal during the installation process:

Fetching: passenger-5.0.28.gem (100%)
Building native extensions.  This could take a while...
Successfully installed passenger-5.0.28
Parsing documentation for passenger-5.0.28
Installing ri documentation for passenger-5.0.28
Done installing documentation for passenger after 64 seconds
1 gem installed


10. Next we will install the module that allows passenger to work with the Apache web server. The process takes a few minutes.

I went to my Terminal window in which I was logged in as root user for this step. You might be able to run the command when logged in as the non-root user, but I think I ran into a problem when I tried this which is why I ended up running it as the root user. After connected as root and after changing directories to the home directory of the single user, I started the module installation by running the following command:

# passenger-install-apache2-module

A welcome message will explain what will happen during the installation:

Welcome to the Phusion Passenger Apache 2 module installer, v5.0.28.

This installer will guide you through the entire installation process. It
shouldn't take more than 3 minutes in total.

Here's what you can expect from the installation process:

 1. The Apache 2 module will be installed for you.
 2. You'll learn how to configure Apache.
 3. You'll learn how to deploy a Ruby on Rails application.

Don't worry if anything goes wrong. This installer will advise you on how to
solve any problems.

Press Enter to continue, or Ctrl-C to abort.


Press Enter to continue to the next step of the installation process. The installation will ask you what languages you are interested in:

--------------------------------------------

Which languages are you interested in?

Use <space> to select.
If the menu doesn't display correctly, press '!'

 ‣ ⬢  Ruby
   ⬢  Python
   ⬢  Node.js
   ⬡  Meteor

--------------------------------------------


I selected the first three (Ruby, Python, and Node.js).

After this, the installation will search the system for all Apache installations. After the check completed, here is the prompt I saw:

Checking whether there are multiple Apache installations...
Multiple Apache installations detected!

You are about to install Phusion Passenger against the following
Apache installation:

  Apache 2.2.31
  apxs2     : /usr/bin/apxs
  Executable: /usr/local/apache/bin/httpd

However, 2 other Apache installation(s) have been found on your system:

  * Apache 2.2.31
    apxs2     : /usr/local/apache.backup/bin/apxs
    Executable: /usr/local/apache/bin/httpd

  * Apache 2.2.31
    apxs2     : /usr/local/apache/bin/apxs
    Executable: /usr/local/apache/bin/httpd

Are you sure you want to install against Apache 2.2.31 (/usr/bin/apxs)? [y/n]:


This step is covered in the Bluehost Passenger installation tutorial, which recommends selecting the (/usr/bin/apxs) option. I confirmed with the installer, which then proceeded with the installation. After many, many lines of text were printed to the Terminal window, I received another prompt:

--------------------------------------------
Almost there!

Please edit your Apache configuration file, and add these lines:

   LoadModule passenger_module /home/username/.rvm/gems/ruby-2.2.4/gems/passenger-5.0.28/buildout/apache2/mod_passenger.so
   <IfModule mod_passenger.c>
     PassengerRoot /home/username/.rvm/gems/ruby-2.2.4/gems/passenger-5.0.28
     PassengerDefaultRuby /home/username/.rvm/gems/ruby-2.2.4/wrappers/ruby
   </IfModule>

After you restart Apache, you are ready to deploy any number of web
applications on Apache, with a minimum amount of configuration!

Press ENTER when you are done editing.


--------------------------------------------


11. Like the instructions say, we need to add the lines given above (make sure you change "username" to your actual username) to the Apache config file.

The Apache config file I needed to change was located on the server at:

/usr/local/apache/conf/httpd.conf

To edit Apache’s config file, either edit it in a Terminal window with a text editor like vim or do what I did and download it to your desktop with an FTP program (I used Fetch), edit it with a text editor like TextWrangler, and then upload the edited file back to the server.

Check to make sure the following line is in your httpd.conf file:

Include "/usr/local/apache/conf/includes/pre_main_2.conf"

If it isn't go ahead and add it near the top of the file after any initial comment lines and after the following line if it exists:

Include "/usr/local/apache/conf/includes/pre_main_global.conf"

But before and other uncommented lines.

12. Now go to the file at /usr/local/apache/conf/includes/pre_main_2.conf and open it for editing in vim or on your local desktop.

13. Paste the text supplied by the Passenger module installation into the pre_main_2.conf file:

# BELOW WAS ADDED AFTER PASSENGER WAS INSTALLED AGAINST
# Apache 2.2.31
# apxs2      : /usr/bin/apxs
# Executable: /usr/local/apache/bin/httpd


LoadModule passenger_module /home/username/.rvm/gems/ruby-2.2.4/gems/passenger-5.0.28/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /home/username/.rvm/gems/ruby-2.2.4/gems/passenger-5.0.28
PassengerDefaultRuby /home/username/.rvm/gems/ruby-2.2.4/wrappers/ruby
</IfModule>


14. Save the file and upload it back to the /usr/local/apache/conf/includes/ directory on the server.

15. Go to the Terminal window in which the Passenger module installation is in progress and press Enter to continue with the installation.

16. The installation will attempt to validate the installation of the module and its communication with Apache. Hopefully you will see:

Validating installation...

 * Checking whether this Passenger install is in PATH... ✓
 * Checking whether there are no other Passenger installations... ✓
 * Checking whether Apache is installed... ✓
 * Checking whether the Passenger module is correctly configured in Apache... ✓

Everything looks good. :-)


If so, you have successfully installed the module.

17. Before moving forward, restart Apache at the command line with the following command:

# service httpd restart

18. To check the installation after restarting Apache, run the following command:

# /home/username/.rvm/gems/ruby-2.2.4/wrappers/ruby /home/username/.rvm/gems/ruby-2.2.4/gems/passenger-5.0.28/bin/passenger-config validate-install --validate-apache2 --invoked-from-installer

You should see the same four validation checks as before.

19. One final check is to see if Apache has started the Passenger core processes. Run the following command in Terminal to check this:

# /home/username/.rvm/gems/ruby-2.2.4/gems/passenger-5.0.28/bin/passenger-memory-stats

Depending on your installation location, your passenger-memory-stats file may be in a different location. If so, you may have to do a search for the passenger-memory-stats file and then use its full correct path to run the command.

If the command runs successfully, you will a response that contains a section with following header and one or more rows under the header:

----- Passenger processes -----
PID    VMSize    Private  Name
-------------------------------


Troubleshooting


If the module installation did not work, you will probably receive error messages that help point to the problem. After addressing any errors you may have received, you can try running the module installer again.

If you need to completely uninstall Passenger and start from scratch, you can run the following command:

# gem uninstall passenger



Previous post: Installing Solr

Next post: Creating the new Rails app on the web server

Monday, May 9, 2016

Installing Solr

Blacklight is an interface for searching a Solr index. The quick install of Blacklight includes the installation of Solr, but we will be installing Solr manually instead. This gives us more control over which version of Solr to install.

If you are not familiar with Solr, imagine a book with an index at the back. If you are looking for a certain word or phrase in the book, you can spend lots of time scanning each page individually or you can flip to the index where the work has already been done for you. A Solr index is essentially the same thing as a book index.

The Solr index looks though all digital documents you tell it to, and indexes the words and phrases in the documents. When you want to search for a particular word, searching the Solr index is then much, much faster than a program that searches every document individually until it finds all instances of the word.

An additional benefit of Solr indexing is that the indexed words and phrases can be used as facets in faceted searching. The words and phrases are already grouped during the indexing process, so these groups are easily displayed and used to filter search queries.

If you have never installed or used Solr before, I recommend doing the Solr quickstart exercise to become familiar with some of the command line commands, what the interface looks like, and for a basic understanding of how the index works.

Installing Solr on the VPS

We will install Solr under the single user's directory, but we need to be logged in as the root user to do this.

1. Open a new Terminal window.

2. Connect to the VPS via ssh as the root user:

$ ssh root@example.com

3. Enter your root user's password when prompted for it and press Return.

4. Change directories to your single user's home directory:

# cd /home/username/

5. List the contents of this directory to check for an existing directory named "solr" with the following command:

# ls -a

6. If there is already a directory named "solr" then change directories into that folder:

# cd solr

If there is not a directory listed with the name "solr" then create the directory with the following command:

# mkdir solr

If you receive a permissions error saying you cannot make this directory, the easiest thing I found to do is to open a web browser, go to your cPanel on the Bluehost website, go to the file management section and click on the "File Manager" icon, navigate to the Home directory (/home/username/), and then create the folder using the File Manager interface.

7. In Terminal, once you have confirmed that the /home/username/solr directory exists, change directories into it:

# cd /home/username/solr

8. I used version 5.3.0 of Solr during my testing phases, so that is what I will use for the app. If you want to use a more recent version of Solr, check for the appropriate download link and substitute it in the command below.

Download the Solr tgz package to the /home/username/solr directory with the command:

# wget http://archive.apache.org/dist/lucene/solr/5.3.0/solr-5.3.0.tgz -O solr-5.3.0.tgz

If successful, you will see something similar to the following in the Terminal window, followed by a new command line prompt:

--2016-05-11 14:04:09--  http://archive.apache.org/dist/lucene/solr/5.3.0/solr-5.3.0.tgz
Resolving archive.apache.org... 163.172.17.199
Connecting to archive.apache.org|163.172.17.199|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 134914712 (129M) [application/x-gzip]
Saving to: “solr-5.3.0.tgz”

100%[===========================================================================================>] 134,914,712 18.3M/s   in 8.6s   

2016-05-11 14:04:20 (14.9 MB/s) - “solr-5.3.0.tgz” saved [134914712/134914712]


10. Unpack the tgz package with the following command:

# tar -xzvf ./solr-5.3.0.tgz

The Terminal window will print many lines of text showing the contents of the tgz package being unpacked into the solr directory.

11. Once the unpacking is finished and you see a new command line prompt, change directories into the solr subdirectory (in our case it is for version 5.3.0, which will be different for you if you installed a different version):

# cd solr-5.3.0

12. Start up your solr service with the following command:

# bin/solr start -noprompt

If successful, you will see:

Waiting up to 30 seconds to see Solr running on port 8983 [\] 
Started Solr server on port 8983 (pid=912). Happy searching!


13. Check if your solr service is running and accessible by opening a web browser and going to your URL followed by the 8983 port number:

http://example.com:8983

If everything is working properly, you should see the Solr admin interface.

14. If you want to free up space on the server, you can now delete the .tgz file you downloaded.


Previous post: Setting up the MySQL database

Next post: Installing Passenger

Saturday, May 7, 2016

Setting up the MySQL database

The Blacklight app uses a sqlite3 database by default, but the Blacklight project recommends using a MySQL or PostgreSQL database for a production deployment. The CentOS VPS server through Bluehost already has MySQL installed, so we will use that for our production database.

Side note: I did try to install and use the PostgreSQL database, but ran into several problems along the way. This prompted me to go with MySQL instead since it was already installed and mostly configured.

Setting up the MySQL database for the app

1. Go to your Bluehost cPanel and find the "Database tools" section. In this section, click on the "MySQL Databases" icon to create the database and database user.

 

2. On the next screen, find the "Create a New Database" form and type in the name of your database. You can name it whatever you like - I'll call it "test-app_production" in this example. Then click the Create Database button. You'll most likely be taken to a confirmation screen. From there, go back to the MySQL Databases page using the link provided.


3. Next, go to the "MySQL Users" section to create the database user. Fill in the form with a username and password. Then click the "Create a User" button. You'll most likely be taken to a confirmation screen again. From there, go back to the MySQL Databases page using the link provided.


4. Go to the "Add a User to a Database" section and select the correct username and database from the dropdown menu. Then click the "Add" button.

 

5. You will be taken to a page where you can select the privileges for this user. Select "All Privileges" and then click the "Make Changes" button. Once you see the confirmation that the changes were saved, go back to the MySQL Databases page with the link provided.



6. Head back to your cPanel next. We need to make a change to the collation of the database before we're done with MySQL setup. Find the database tools section again and click on the phpMyAdmin icon. This will take us to the phpMyAdmin interface, where we can make changes to the structure and contents of the database.


7. In the phpMyAdmin interface, click on the Databases tab to see a list of your databases.


8. Click on the database you just created (in our case, it is "test-app_production").


9. Click on the "Operations" tab.


10. Select "utf8_bin" in the Collation select menu and click save. The default "latin1_swedish_ci" won't work with the Blacklight installation. The "latin1_swedish_ci" collation does not support all of the characters Blakclight will be inserting into the database tables, so if we don't change this we will get an error during the database migration step later on.


11. After the new collation is saved, close out of the phpMyAdmin interface. Your MySQL database should now be configured for use with the Blacklight app.


Previous post: Installing Rails

Next post: Installing Solr

Thursday, May 5, 2016

Installing Rails

1. Before we move forward with installing Rails, take a moment to check for updates to the Ruby gems with the following command:

# gem update

2. And then check for updates to the RubyGems software itself with the following command:

# gem update --system

3. Installing Rails is as easy as typing the following into the system console and pressing Return:

# gem install rails -v 4.2.6

The -v part of the command allows you to choose which version of Rails you would like to install (we installed 4.2.6 here). The system will install the Rails gems, which will take a few minutes or more.

4. Once Rails is successfully installed, use the following command to check the Rails version:

# rails -v

The system console should respond:

Rails 4.2.6

If it does, you have successfully installed Rails!


Previous post: Installing Java Development Kit (OpenJDK)

Next post: Setting up the MySQL database

Installing Java Development Kit (OpenJDK)


Blacklight requires a Java Runtime Environment of 1.7 or higher. We will install the OpenJDK developer package on the server. If you would like to install the Oracle JDK, Oracle has instructions published on its JDK installation page. I found the OpenJDK installation instructions for Red Hat Linux on the OpenJDK site here.

1. In the system console, type the following and press Return:

# yum install java-1.8.0-openjdk-devel

The system console will ask you to confirm the installation during the process.

2. Once OpenJDK successfully installs, you can check the java version with the following command:

# java -version

The system console should respond with

openjdk version "1.8.0_91" OpenJDK Runtime Environment (build 1.8.0_91-b14) OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

If you see, this - congrats! OpenJDK is installed.


Previous post: Installing Node.js and EPEL

Next post: Installing Rails

Wednesday, May 4, 2016

Installing Node.js and EPEL

To install Node.js on our CentOS server, first run the following command (I adapted these instructions from the Phusion Passenger installation tutorial, which we continue with later):

sudo yum install -y epel-release yum-utils

Next, run the following command to install Node.js

sudo yum install -y --enablerepo=epel nodejs npm



Previous post: Installing Bundler

Next post: Installing Java Development Kit (OpenJDK)

Installing Bundler

The next step is to install Bundler to manage the Ruby gems used in Ruby on Rails apps. It can be installed in a single step at the command line:

# gem install bundler

Previous post: Installing Ruby

Next post: Installing Node.js and EPEL

Installing Ruby

Now that RVM is installed and working at the command line, you can move forward with installing Ruby on the server.

1. Check to see which, if any, version of Ruby are installed by typing the following and pressing Return:

# rvm list known

Most likely, no Ruby installations will show up yet.

2. If you do see some Ruby installation(s), you can check the default version currently in use by typing the following and pressing Return:

# ruby -v

3. To install a specified version of Ruby, type the following command and press Return (change the version number if you would like something other than Ruby 2.2.4):

# rvm install 2.2.4

The installation will begin. It may take a while (mine took between 5-10 minutes).

4. Once RVM installs the version of Ruby you specified, check the default version of Ruby again by entering:

# ruby -v

The console should respond with:

ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]

or something similar depending on which version you installed.

5. If the default version is not the version you just installed, and you would like to use the newly installed version, enter:

# rvm use 2.2.4

6. If the new version is not the default and you would like to make it the default, enter:

# rvm use 2.2.4 --default

7. Update your Ruby gems

# gem update

Congrats! You successfully installed Ruby and updated the Ruby gems. You can use the commands above to install new versions in the future, switch between versions, and change the default version of Ruby.


Previous post: Installing RVM to manage and install Ruby

Next post: Installing Bundler


Installing RVM to manage and install Ruby

The most appropriate installation method depends on your operating system and whether you will install more than one version of Ruby. Ruby installation can be done with package management systems, installers, managers, or building from source code. A list of available installation tools/methods can be found on the Ruby website.

The Linux Red Hat CentOs is the operating system on the Bluehost VPS. I decided to use Ruby Version Manager (RVM) to install and manage Ruby. It is compatible with Linux, assists with easy installation, and provides easy management of upgrades to newer version of Ruby in the future.

Install RVM

1. First go to the Terminal window that is connected via ssh to the VPS (see previous post for help with this). Once you are connected, make sure you are in your user directory by running the following command (Don't type the # symbol - that just represents the end of the command line prompt):

# pwd

Hopefully you will see the following response (where "username" is you actual username):

/home/username

If you do, you are in your user's home directory. If you don't, you can change to that directory using the cd command:

# cd /home/username

2. Once you confirm you are in your user's home directory, type the following and hit Return:

# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

This will retrieve the public key for the install. You will see something similar to the following as the key is retrieved:

gpg: requesting key D39DC0E3 from hkp server keys.gnupg.net
gpg: key D39DC0E3: "Michal Papis (RVM signing) <mpapis@gmail.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1


3. Once the public key is retrieved, you will see the command line prompt again. Now type the following and hit Return to install the latest stable version of RVM:

# \curl -sSL https://get.rvm.io | bash -s stable

Installation status messages similar to the following will appear in the Terminal window as RVM is installed:

Downloading https://github.com/rvm/rvm/archive/1.27.0.tar.gz
Downloading https://github.com/rvm/rvm/releases/download/1.27.0/1.27.0.tar.gz.asc
gpg: Signature made Tue 29 Mar 2016 01:49:47 PM UTC using RSA key ID BF04FF17
gpg: Good signature from "Michal Papis (RVM signing) <mpapis@gmail.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 409B 6B17 96C2 7546 2A17  0311 3804 BB82 D39D C0E3
     Subkey fingerprint: 62C9 E5F4 DA30 0D94 AC36  166B E206 C29F BF04 FF17
GPG verified '/home/username/.rvm/archives/rvm-1.27.0.tgz'

Installing RVM to /home/
username/.rvm/
    Adding rvm PATH line to /home/
username/.profile /home/username/.mkshrc /home/username/.bashrc /home/username/.zshrc.
    Adding rvm loading line to /home/
username/.profile /home/username/.bash_profile /home/username/.zlogin.
Installation of RVM in /home/
username/.rvm/ is almost complete:

  * To start using RVM you need to run `source /home/
username/.rvm/scripts/rvm`
    in all your open shell windows, in rare cases you need to reopen all shell windows.

#
username,
#
#   Thank you for using RVM!
#   We sincerely hope that RVM helps to make your life easier and more enjoyable!!!
#
# ~Wayne, Michal & team.

In case of problems: https://rvm.io/help and https://twitter.com/rvm_io

  * WARNING: You have '~/.profile' file, you might want to load it,
    to do that add the following line to '/home/
username/.bash_profile':

      source ~/.profile


  * WARNING: you have GEM_HOME="/usr/local/rvm/gems" this is conflicting with RVM, make sure to:

      unset GEM_HOME




Note: These instructions can be found on the RVM website home page. This is the simple installation. If you want to install using a more secure installation, you can find instructions on the RVM site here. There are also other installation options, such as installing Ruby and/or Rails with RVM, that are outlined on the RVM site here.


4. Once the installation successfully completes, you need to reboot the server before you can use RVM. There are two ways to reboot the server.

The first way is to press the "Send CtrlAltDel" button at the top right part of the system console window:


The second way is to go to the "server management" page in your Bluehost account interface and click the "reboot" button:



5. After the server shuts down and restarts (this will probably take a couple of minutes), you will need to log in again. Close your Terminal window and open a new one. Connect to the VPS via ssh again, and then run the following command to see if RVM is now available to use at the command line:

# type rvm | head -n 1

The system console response should be

rvm is a function

If it is, then you successfully installed RVM and made it available to use as a command line function!

Troubleshooting


When I installed RVM the first time, I installed it as the root user. That is not preferred, as written on the RVM site. It is better to install it as a single user in a user account's home directory as the steps above describe.

Because I initially installed it for multiple users as root, I ran into some problems and needed to uninstall and reinstall from scratch. To do this, I found the best method requires several steps (I found this explanation on this stackoverflow thread):

1. First run the following command (you might have to do this as the root user if you installed it as the root user):

gem uninstall rvm

2. After the uninstaller finishes running, there may be a couple of other files to find and delete manually. Check for mentions of rvm in the PATH variable and remove them if they are there. Also, look for rvm in the .bashrc, .profile, and .bash_profile files. Remove any mentions you find in those files. Lastly, look for files in the following locations and delete them if they exist:

/etc/rvmrc
~/.rvmrc

If I remember correctly, after going through these steps I was able to install RVM from scratch in the single user's home directory without any errors.



Previous post: Connecting to the VPS through Terminal and why I prefer this over the System Console

Next post: Installing Ruby