Every once in a while I buy a new VPS, mostly because I’m not entirely satisfied with my current setup. My stack of choice is usually RVM for Ruby management, the Apache web server, Passenger for allowing Apache to run Ruby apps like Rails and Sinatra, and MySQL for the database.
This time around I decided to use some other software that seems to be popular with the community.
- For the webserver I chose nginx. There are many comparisons of Apache and nginx, but for such a small-scale server as mine it really boiled down to curiosity.
- RVM has received some flack, principally because of Bundler’s ability to manage “gemsets” with Gemfiles. I went with rbenv to manage my rubies.
- I stuck with Passenger for allowing the web server to run Ruby apps. Although other solutions exist, like Unicorn and Thin, the configuration required was a little too much for me.
- PostgreSQL is a popular choice these days. If it’s good enough for Ryan Bates then it’s good enough for me!
Now that the stack’s chosen, it’s just a case of setting it all up.
Setting Up Ubuntu
In this section all commands are executed as the
root user, as when you log in to a fresh install. If you’ve already got a user set up, prefix all the commands in this section with
I chose Ubuntu as my Linux distribution of choice. The lastest Ubuntu image provided by my VPS host was 11.04, so first I had to update Ubuntu to the latest LTS, 12.04. First, make sure we’re up-to-date.
-y flag assumes a ‘yes’ response for all prompts. Next, as there’s no direct upgrade route from 11.04 to 12.04, we need to go via 11.10.
Confirm that you want to perform the upgrade, and once that’s finished and the VPS restarted (
reboot) Ubuntu will be at 11.10. You can check this:
do-release-upgrade again to arrive at 12.04 LTS.
For a basic setting up of our VPS, the Slicehost article on setting up Ubuntu is great. In particular, make sure to set up the
wheel admin group and get
iptables set up. We’ll add a user to the
wheel group later.
Once that’s done, we have a non-
root user with which to log in to the VPS. Log in as that user from your local machine.
Create a user to deploy with and add her to the
deploy is the username of our new user. Finally, we’ll install a few dependencies for later.
Installing the Components
We have four main components to install: Ruby, PostgreSQL, Passenger, and nginx. We’ll install them in that order, as Passenger comes with a handy command that installs nginx from source for us.
To install Ruby we’ll install rbenv, which allows us to manage multiple rubies on the same machine. As
deploy will be deploying the apps, we need her to have access to the rubies. Assume access as
And install rbenv using the handy rbenv installer:
Add the snippet the installer gives you to your
.bashrc and source the file in the shell.
To make sure we’ve got all the dependencies required for installing Ruby from source, run
rbenv bootstrap-ubuntu-12-04. We’ll install the latest version which is, at the time of writing, 1.9.3 patch 194.
The last command makes
1.9.3-p194 the global, default version of Ruby. You can check the Ruby version with
Now we have Ruby, we can install Passenger as a gem and then refresh rbenv.
Next, we install nginx.
The installer will figure out if all the dependencies are preset. If they’re not, it’ll give you a snippet with which to install them. Choose option 1 to let Passenger download, configure, and compile nginx. The default installation directory
/opt/nginx is fine, but some people prefer the more familiar Apache-like directory
Once that’s installed, we’ll get a script for nginx that allows us to use the
service command, so we can do stuff like
sudo service nginx restart.
We’ll also replace the default nginx configuration with a leaner one. Download the simple config file and replace the current one (backing up first, of course).
Notice that this new configuration file
includes files from
/opt/nginx/sites-available. This is similar to how many people set up Apache with virtual hosts. For each site we want (generally represented as a (sub)domain or set of (sub)domains) we create a file inside
If you installed nginx to a different directory, such as
/etc/nginx, modify the
nginx init.d and
nginx.conf file to point to the right places. Check everything’s working by restarting nginx.
We can double-check nginx is working by visiting our VPS IP.
Great! Now we have all we need to run Ruby apps. With something like Rails we need one one more thing though: a database. The version of PostgreSQL in the Ubuntu repository is a little outdated, so we’ll install it from an up-to-date PPA.
libpq-dev is a dependency of the
pg gem, which Rails will need to talk to the database. Now that PostgreSQL is installed, we’ll change the root password and set up a test user.
Good, that’s everything for now. Let’s try getting a Rails app up and running!
We’ll get a fresh Rails app going as the deploying user, so make sure you’re logged in as
We want each app to have its own set of gems. Using Bundler, we can do this easily with a Gemfile.
We now have a Gemfile which Bundler can work with. We now install the
bundler gem, install the stuff in our Gemfile to
vendor/bundle (which will act as our app-specific gemset) and create the Rails test app.
Y to overwrite our Gemfile with the Rails template. Now, install the rest of the Rails dependencies.
To make sure Rails can talk to the database, edit
database.yml with the test PostgreSQL user and database details.
host: localhost is particularly important (and not in the default Rails
database.yml); my app wouldn’t work without it.
Now we just need to tell nginx where our Rails app is. As I mentioned earlier, we’ve set up nginx so that each site has its own config file inside
nginx/sites-enabled. I’ve uploaded a test app config file on GitHub. We just download this to this nginx directory and edit it so that it points to the right place.
Visiting the VPS IP, it works!
Excellent. We’ve set up a VPS from scratch to serve Ruby applications, installing rbenv, Passenger, nginx, and PostgreSQL. If you’d like to test the Rails app a little further, delete
index.html in the
public directory and scaffold some models. Create, update, and delete a few records to make sure the database is OK.
That’s all for now, next we’ll go over deploying from a local machine to the VPS with Capistrano.