Setting up SequenceServer

A heavily modified SequenceServer that is running from the Lotus japonicus genomics and proteomics resource website, manuscript in preparation (Mun et al., 2015)

I was recently tasked with setting up SequenceServer on a work server in a production environment—the legacy NCBI wwwblast is extremely dated, and highly non-customizable. Deep integration with the API we have developed for a Lotus japonicus genomic and proteomic resource is not possible.

I have encountered several issues with setting up SequenceServer, but have managed to resolve all of them. I am therefore penning this guide for future users who might be interested in installing SequenceServer, but are at a loss of where to start, and what to do when they run into issues.

It is of course not possible to enumerate the installation instructions for all possible server configurations—therefore you should be warned that the SequenceServer I have installed is running off a RHEL7 server with a standard solution stack (Apache, PERL-CGI, PHP and MySQL) installed.

Ruby on Rails

If you have not installed Ruby on Rails on your server, you will have to do that. I strongly recommend using rbenv to install Ruby. It just makes life a lot easier 😉 you may also follow this very handy guide for more details.

### Install Ruby using rbenv
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ source ~/.bash_profile

### Install ruby
$ rbenv install 2.1.0
$ rbenv rehash
$ rbenv global 2.1.0
### Update everything
$ gem update
$ gem update --system

Installing SequenceServer and its dependencies

Here, I will go through the installation instructions for the dependencies for SequenceServer and SequenceServer itself.

Dependencies

The gem you need for SequenceServer to work is rails and passenger.

### Install basic dependencies
$ gem install rails
$ gem install passenger
$ passenger-install-apache2-module

If you want to build SequenceServer yourself, you will also need to install rack and rake.

### Install basic dependencies
$ gem install rack rack-test rake

However, if you run into additional issues, you might want to install development dependencies such as Rspec, Rubocop, Capybara, CodeClimate and qmake.

### Install qmake
$ yum install qt-webkit-devel
$ find / -name *qmake
$ ln -s /usr/lib64/qt4/bin/qmake /usr/bin/qmake
### Install other development dependencies
$ gem install rspec rubocop capybara capybara-webkit codeclimate-test-reporter

SequenceServer

As SequenceServer is available as a Ruby gem, you just have to run:

$ gem install SequenceServer

Yes, it is as easy as that—but wait, you are not really done yet. We need to specify where can SequenceServer run from, and we typically do not run it off a port (4567 by default), but off a subdirectory, like /blast/ or the likes. In order to run SequenceServer off a subdirectory, we need to run Passenger at the correct paths—this involves fiddling with the Apache httpd configuration file.

Updating your Apache httpd configuration file

As mentioned before, if you intend to run SequenceServer as a Passenger app in a subdirectory, you will have to give Apache a set of very specific instructions:

  1. Your choice of subdirectory where you intend to serve SequenceServer
  2. The location of your SequenceServer public folder
  3. The user that Passenger should run SequenceServer as

Info 1: Choice of subdirectory

That is very simple. If you want to run SequenceServer from the /blast/ subdirectory of your URL, you will use “/blast”

Info 2: Location of SequenceServer public folder

This is a bit tricky. First, you will have to figure out where is SequenceServer installed. You can do this by running:

$ gem env

This will output something similar to the following in your terminal (emphasis my own):

RubyGems Environment:
- RUBYGEMS VERSION: 2.2.0
- RUBY VERSION: 2.1.0 (2013–12–25 patchlevel 0) [x86_64-linux]
- INSTALLATION DIRECTORY: /home/terry/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0
- RUBY EXECUTABLE: /home/terry/.rbenv/versions/2.1.0/bin/ruby
- EXECUTABLE DIRECTORY: /home/terry/.rbenv/versions/2.1.0/bin
- SPEC CACHE DIRECTORY: /home/terry/.gem/specs
# and more... #

Look at the INSTALLATION DIRECTORY value (see bolded line). Your gems should be installed in the /gems folder located in that directory. For example, the SequenceServer that I have installed is located at:

/home/terry/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/sequenceserver-1.0.4

Info 3: User that Passenger is running SequenceServer with

The annoying thing is that processes spawned by Passenger, by Apache, is not by the user that is running Apache. If you want to check who is running Apache, just use the command:

$ ps aux | egrep '(apache|httpd)'
apache    3932  0.0  0.0 498956 10292 ?        S    Nov15   0:00 /usr/sbin/httpd -DFOREGROUND
apache    3933  0.0  0.0 498956 10292 ?        S    Nov15   0:00 /usr/sbin/httpd -DFOREGROUND
apache    3934  0.0  0.0 498956 10292 ?        S    Nov15   0:00 /usr/sbin/httpd -DFOREGROUND
apache    3935  0.0  0.0 498956 10292 ?        S    Nov15   0:00 /usr/sbin/httpd -DFOREGROUND
apache    3936  0.0  0.0 498956 10292 ?        S    Nov15   0:00 /usr/sbin/httpd -DFOREGROUND
apache    3979  0.0  0.0 498956 10288 ?        S    00:15   0:00 /usr/sbin/httpd -DFOREGROUND

To remedy this, you will need to find out who owns the file config.ru in SequenceServer’s installation directory (which you have obtained in Info 2). You can check it by running:

$ cd /home/terry/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/sequenceserver-1.0.4
$ ls -l config.ru

And it seems that it is me (user terry) not the Apache user (user apache):

-rw-r — r — 1 terry terry 116 Oct 1 16:33 config.ru

Modifying Apache httpd.conf

With all three information on your hand, you are ready to modify your Apache configuration. The location of the configuration file varies from server to server, but mine is located at /etc/httpd/conf/httpd.conf. If you want to play it safe, make a copy of your httpd.conf file and store it somewhere.

Nobody likes playing around with httpd.conf or .htaccess files, because they can be very difficult to understand at times. Therefore, I have made a template of what you should append to your httpd.conf file to get SequenceServer to work. Note that:

  • /path/to/app should refer to the directory of the SequenceServer gem itself (see Info 2)
  • /path/to/app/public should refer to the directory of the public folder in the SequenceServer gem (see Info 2, just append “/public” to end of path)
The template file for httpd.conf

And here is a working example of the portion of my httpd.conf file:

Update SequenceServer’s configuration file

SequenceServer needs some additional information before it can work. The most important two bits are:

  • The location of NCBI BLAST+ executables
  • The location of your BLAST directories

SequenceServer’s configuration file is located in the gem’s directory, named config.ru. In there you can specify it to load a configuration file located anywhere else on your server—as long as the user running Passenger and SequenceServer has access to it.

An example of my config.ru file:

require 'sequenceserver'
SequenceServer.init(:config_file => "/home/terry/.sequenceserver.conf")
run SequenceServer

I simply instructed SequenceServer to load additional configurations from the file “/home/terry/.sequenceserver.conf” upon initialisation. In that file I specify the number of threads SequenceServer should run on, and the location of both the NCBI BLAST+ binaries and BLAST directories.

---
:num_threads: 4
:bin: "/home/terry/bin/.sequenceserver/ncbi-blast-2.2.31+/bin"
:database_dir: "/home/terry/var/blast-db"

Multiple SequenceServer instances?

There might be edge use cases where you will want to have multiple SequenceServer instances. For example, you want to separate what databases the public has access to, and what databases your internal users (within your lab, or your research group for example) have access to. This can be done by:

  1. Having addition rules in your httpd.conf file — you can use IP-based access restriction to limit access to your private SequenceServer instance.
  2. Having a copy of the SequenceServer’s config.ru
  3. Symlinking /public to original gem’s /public folder

Additional Apache httpd configuration

You simply will have to duplicate the rules that make SequenceServer work, namely from the “alias” line to the end of the “</Directory>” block. For example, if I want to serve SequenceServer from both the /blast and /blast-private directories, with IP-based access restriction on the latter, I can do this:

Even though Apache 2.4 accepts legacy Apache allow/deny directives, you should migrate over to the require directive for future compatibility. There is a handy guide on updating directives when upgrading to Apache 2.4.

A different configuration file for each SequenceServer instances

Each SequenceServer instance is opened by a new config.ru file. For convenience’s sake, I have create another SequenceServer folder in the Ruby gems folder, called “sequence-server-1.0.4-private”, for example. In there, I have a new config.ru file—and that is all!

You may load different configurations for your config.ru files. For the public one:

# sequenceserver-1.0.4/config.ru
require 'sequenceserver'
SequenceServer.init(:config_file => "/home/terry/.sequenceserver.conf")
run SequenceServer

…and for the private SequenceServer:

# sequenceserver-1.0.4-private/config.ru
require 'sequenceserver'
SequenceServer.init(:config_file => "/home/terry/.sequenceserver-private.conf")
run SequenceServer

With different .conf file loaded, you can use different BLAST databases, binaries and etc.

Symlinking /public folder to original gem’s /public folder

Remember that since file paths are relative in the SequenceServer installation, you will be serving files in the /public folder from different directories where each config.ru is located in. To overcome this issue, you will have create symlinks to the original /public folder in the SequenceServer gem:

# Go to folder of alternative instance of SequenceServer
$ cd /home/terry/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/sequenceserver-1.0.4-private
# Create symlink to the public folder in actual gem
$ ln -s public ../sequenceserver-1.0.4/public

You may also use .htaccess to redirect requests for files in non-existent /public folder in other SequenceServer instances to the actual files, but I find that quite cumbersome.