Posted on Leave a comment

Setting up Apache and Passenger for Rails on Debian

I am a software developer in the real world, but I like to play system administrator in my own playground. Debian is my linux distribution of choice. I have been using Apache as the httpd front end since I’ve started hosting my projects. When I’ve written servlet based applications I’ve used mod_jk to work with Tomcat, or even this blog is on WordPress which is using mod_php, which also my webmail interface uses, and I’ve used mod_proxy to redirect traffic to a Jenkins server on my local network through a VPN. Now that my Rails project is almost ready to go I figured I better figure out how to setup a Rails application with Apache.

The most common way I have found that people host Rails sites is to use Nginx as the front end. This may be tinted by the fact that the hosting team at the office is using Nginx as the front end for Passenger. But I am familiar with a number of other companies using similar setups. But as I stated before I am familiar with Apache and rather than having to learn and setup a new httpd front end which will support the other sites I am hosting I figured learning how to setup Passenger with Apache seems like the path of least resistance. The small amount of research I have done indicates that for a large scale site Nginx is a better option, but until my little site here can pay for itself and a real system administrator I’m happy to stay within my little wheelhouse of Apache.

Shut up old man, I came here to learn something, not read your yammering on about nothing!

This is a list of versions of software that this setup was done on originally. Some of the commands to set things up are specific to Debian or deb package based systems, such as Ubuntu or Mint, with a little modification it should be possible to setup with another linux based system.

  • Debian 8.5 (jessie)
  • Apache 2.4.10
  • Mysqld 5.5.50
  • Ruby 2.1.5
  • Passenger 4.0.53

Install servers, Ruby, and development packages

I am using Debian’s package management, so adjust the commands as necessary to your Linux distribution. The build-essential is basically your standard C/C++ development environment with gcc, make, and other similar packages. The ruby-dev package includes the headers and libraries for building gems with native dependencies. The libmysqlclient-dev is the headers required to build the mysql2 gem, so if you are skipping mysql in favor of PostgreSQL or no database support it is not required. The nodejs is required for certain rails gems so may also not be required for your purposes.

sudo apt-get install apache2
sudo apt-get install mysql-server
sudo apt-get install ruby
sudo apt-get install libapache2-mod-passenger
sudo apt-get install git build-essential ruby-dev libmysqlclient-dev nodejs

Setup Ruby

There is not a whole lot of setup for your Ruby environment required. The one major missing component for Ruby is the lack of Bundler for the default install. While this is not technically required, I haven’t seen too many Ruby projects which do not use Bundler for dependency management.

sudo gem install bundler

Configure Apache

The Debian apache package configuration has a layout under /etc/apache2 which has configurations, modules, and sites. There is a directory of which is called mods-available and mods-enabled and the same for configurations and sites. The available directory will include configurations which are possible to enable. And the enabled directory includes symlinks to the available directory. Then when apache is started it will evaluate all of the configurations in the available directories. In addition Debian provides some scripts which enable or disable each type of configuration. The commands a2enmod and a2dismod enabled and disable mods respectively. The configurations and sites have similarly named commands.

The passenger configuration is probably acceptable for a default installation. It will use the default passenger configuration provided by Debian. And the default ruby will be selected as the system installed Ruby. If you were to want to use another Ruby, such as JRuby or another version than what is provided by default you would set the default Ruby here or in each site configuration set a specific version of Ruby for the site to use.

The passenger module may need to be enabled which is accomplished by enabling the module with the next command. It seems that sometimes the module is enabled on installation, but that does not appear to always be the case so it is best to run the command to ensure it is enabled.

Now, by default each site hosted will have passenger enabled for processing Rails requests. It may be a good idea to disable passenger for sites which do not require passenger to handle Rails requests. But then we are getting into performance and security which is outside the scope of this howto and those two items are outside of my wheelhouse.

# Review passenger configuration for the PassengerRoot and PassengerDefaultRuby
less /etc/apache2/mods-available/passenger.conf
a2enmod passenger

Configure Rails Project

There is a bit of basic configuration which is required for most Rails projects which I will cover, but your Rails project will probably have specifics beyond what I am covering or could predict. One of the specific items you need to be aware of is that by default Passenger will run Rails applications in production environment so all of your configuration options will have switched to production which you may not have setup properly. It is a good opportunity to review your config/environments/production.rb file to verify the setup is indeed what you are expecting.

cd /var/www
git clone git@github.com:your_project.git # retrieve your project
cd project # project directory
bundle install
# Setup SECRET_KEY_BASE
$EDITOR_OF_CHOICE config/secrets.yml
# Update database configuration
$EDITOR_OF_CHOICE config/database.yml
RAILS_ENV=production bundle exec rake db:create
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake assets:precompile

Configure Site

The final step is to setup apache to recognize your Rails project as a site.

# Create site configuration /etc/apache2/available-sites/project.conf
sudo $EDITOR_OF_CHOICE /etc/apache2/available-sites/project.conf # project name
sudo a2ensite project # use project name, no .conf required
sudo service apache stop
sudo service apache start

The configuration file has two entries which will two entries to configure the site. A full set of available directives can be found on the Passenger website. The DocumentRoot is the location of the public directory in the Rails application. And the Directory is the root of the Rails project, which passenger will recognize as a Rails application for processing.

<VirtualHost *:80>
        DocumentRoot /var/www/project/public
        ErrorLog ${APACHE_LOG_DIR}/project.log-error
        CustomLog ${APACHE_LOG_DIR}/project.log-access combined

        <Directory /var/www/project>
                Allow from all
                Options -MultiViews
                Require all granted
        </Directory>
</VirtualHost>