How to Configure a Rails Application Server with RVM, Apache, and Passenger on Ubuntu 16.04
This tutorial will guide you through setting up a Rails application server using Apache as a front-end server and Passenger as a back-end.
Before You Begin
You’ll need:
- An Ubuntu 16.04 server with at least 1GB of RAM and a non-root user with sudo access.
- Your Rails application in a Git repository
- Your Rails application’s database system installed on the server.
Step 1: Configure RVM
We’ll use RVM to install Ruby. This is the recommended approach for using Passenger with Ruby.
Log in to your server as your non-root user.
ssh deploy@your_ip_address
RVM has a few prerequisites you’ll need to install:
sudo apt-get update
sudo apt-get install -y curl gnupg build-essential dirmngr gnupg apt-transport-https ca-certificates
Once those complete, Install RVM:
sudo gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | sudo bash -s stable
Add your user to the rvm
group:
sudo usermod -a -G rvm `whoami`
Now execute this command to enable RVM to work with the secure_path
setting for sudo:
if sudo grep -q secure_path /etc/sudoers; then sudo sh -c "echo export rvmsudo_secure_path=1 >> /etc/profile.d/rvm_secure_path.sh" && echo Environment variable installed; fi
Log out of your machine and log back in.
Install Ruby:
rvm install ruby-2.5.0
You’ll be prompted for your sudo password to install additional dependencies.
Execute this command to make this version of Ruby the default version of Ruby:
rvm --default use 2.5.0
Install Bundler, the dependency manager for Ruby applications:
gem install bundler --no-rdoc --no-ri
Now install Node.js, which Rails applications use for the Asset Pipeline.
curl --fail -ssL -o setup-nodejs https://deb.nodesource.com/setup_8.x
sudo bash setup-nodejs
sudo apt-get install -y nodejs
With these components installed, you can move on to installing Passenger.
Step 2: Installing Passenger
Passenger is the application server that will launch your Rails app. It works well with Apache, so that’s how we’ll configure it.
First, ensure Apache is installed:
sudo apt-get install apache2
We’ll install Passenger and its module using Passenger’s repository:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger xenial main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update
sudo apt-get install -y libapache2-mod-passenger
Once Passenger is installed, enable the module and restart Apache:
sudo a2enmod passenger
sudo apache2ctl restart
Passenger itself is installed. Now let’s configure it to serve our Rails app.
Step 3: Configure Passenger for Rails
Create a virtual host for your Rails application. You’ll point it to /var/www/example.com/current/public
, which is the location of your Rails application’s public
folder.
First, create the web app folder and ensure the deploy
user owns it:
sudo mkdir -p /var/www/example.com
sudo chown deploy: /var/www/example.com
Create a new site:
sudo nano /etc/apache2/sites-available/example.com.conf
Add this to the file:
<VirtualHost *:80>
ServerName example.com
# Tell Apache and Passenger where your app's 'public' directory is
DocumentRoot /var/www/example.com/current/public
PassengerRuby /usr/local/rvm/gems/ruby-2.5.0/wrappers/ruby
# Relax Apache security settings
<Directory /var/www/example.com/current/>
Allow from all
Options -MultiViews
# Uncomment this if you're on Apache >= 2.4:
#Require all granted
</Directory>
</VirtualHost>
Enable the site
sudo a2ensite example.com
Disable the default site
sudo a2dissite 000-default
Now let’s deploy the app.
Step 4: Deploying your App
We’ll deploy the app manually by using Git to check out the application into your server’s /var/www/example.com
folder into a subfolder called v1
. We’ll then use a symlink to link the v1
folder to the /var/www/example.com/current
folder that Rails and Passenger will serve.
This way, when you deploy new versions, you have the option of checking them out to a new folder, like v2
and changing the symlink. Then if something goes wrong, you can roll back. This is similar to methods that automated deployment tools like Capistrano use, and this makes it easier for you to migrate your process to those tools.
Deploy your app from Git.
cd /var/www/example.com
git clone git://github.com/username/myapp.git v1
Now create a symlink from v1
called current
.
ln -nfs v1/ current/
Then switch to the current
directory:
cd current/
This tutorial assumes your config/database.yml
file is configured to talk to a database. If it’s not, you should make those configuration changes now before moving on.
Install dependencies for deployment only:
bundle install --deployment --without development test
Now compile assets for production and apply database migrations:
bundle exec rake assets:precompile db:migrate RAILS_ENV=production
Finally, ensure the file config/secrets.yml
exists.
cat config/secrets.yml
If you see this at the end:
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
then you should set an environment variable in your .bashrc
file.
nano ~/.bashrc
At the top of the file, add this:
export SECRET_KEY_BASE=some_long_value_nobody_will_guess
Save and exit the file.
Your app is now deployed.
Visit http://example.com
to view it.
Conclusion
Deploying Rails with Passenger involves many steps, and this is a very manual deployment process. Once you have your application deployed, you’ll want to explore more automated solutions such as Capistrano.