Setting up a Rails server on Debian 6

debianplusrubyI’ve been working on a Rails application for the better part of a year (which I plan to talk about in detail in a future post), and I’ve come to the point where I really must put the thing up on a live server in order to work out the last few details. My initial plan is to deploy my application to two virtual machines. One will host the rails application itself, while the other will host the application’s Postgres database. Eventually (hopefully) if I need to scale the application I can simply deploy additional app (easy) and/or database (less easy) VMs and set up yet another VM with something like HAProxy to route requests.

I’ve decided upon 6sync as my hosting provider, due to their good performance, decent prices, and linux distro options. I’ve also decided to use Debian 6 for all of my VMs (because I rather don’t like CentOS/RHEL). For my rails app server, I plan to use Passenger Standalone. The steps I followed were as follows:

1. Spin up a new VM from 6sync’s control panel with the following options: 64-bit, Debian 6, 256MB nano instance (when I’m done testing I will bump this up, and continue to upgrade it as needed). This will create a VM with a bare-bones Debian install.

2. login as root, open up a terminal and enter the following commands:

apt-get update
apt-get install sudo
apt-get install ruby1.9.1 #Note: This actually installs Ruby 1.9.2 on Debian, which is what I want
apt-get install buildessentials #Needed for passenger
apt-get install ruby1.9.1-dev
apt-get install ri1.9.1
apt-get install graphviz

3. Now, for some reason installing these packages does not cause the proper symlinks to be created in /usr/bin, so to fix that:

ln -s /usr/bin/ruby1.9.1 /usr/bin/ruby
ln -s /usr/bin/gem1.9.1 /usr/bin/gem

4. Also, it would be nice to have the rubygems bin directory in my PATH — it’s actually kind of annoying that installing ruby didn’t do this automatically. So, open up the file /etc/profile and append the following to both PATH entries:

/var/lib/gems/1.9.1/bin

5. For the gems I’m using, I required a few prerequisites — you may or may not need these, though I’m guessing you probably do, as the gems that require them are fairly common:

#The first 3 are required for Passenger
apt-get install libcurl4-openssl-dev
apt-get install libssl-dev
apt-get install zlib1g-dev
#The nokogiri gem requires the following:
apt-get install libxml2 libxml2-dev
apt-get install libxslt-dev
#And the postgresql driver needs this:
apt-get install libpg-dev

6. Finally, install the passenger gem:

gem install passenger

Well, that wasn’t that hard… “passenger start -e production” will fire up passenger standalone on port 3000, which is ok for testing, but you’ll need to do something like “sudo passenger start -p 80 –user=non-root-user-name” to start it on port 80 when you’re ready to go live. I would plan to write a few scripts to automate things ūüôā

LEMP, Debian, and WordPress

Back in 2011, when I started getting back into this whole web thing, I rented a VPS from the folks over at ServInt to run a website called RhythmScore (my first attempt at a web-based business — it failed, hard… maybe I’ll write about it sometime after the sting wears off). ¬†Now, ServInt offers managed VPSes, which means they basically handle a lot of the routine system¬†administration¬†tasks for you. ¬†At the time I thought this was a good thing since while I fancy myself a good programmer, as a sysadmin I know just enough to be dangerous.

As time went on, I upgraded the VPS with more ram, disk space, etc., and also began hosting a few more websites and rails apps on it, including this blog. ¬†Now, a managed VPS comes at a higher cost than a comparable unmanaged solution, and since I’ve become more comfortable tinkering with web servers, databases, etc., I decided to explore other options to host my blog (and possibly a few other simple sites). ¬†In fact, my preference now would be to run multiple, cheap VPSes that can be configured especially for the applications that will be running on them. ¬†With my ServInt VPS running $60, I was trying to run everything on it. ¬†RhythmScore was a PHP website running with MySQL. ¬†My old blog was a Rails app running the Refinery CMS. ¬†I also was hosting a static website for a friend, as well as another rails app. ¬†All of this of course using Apache, mod_php, and Passenger.

This time around I wanted to simplify things. ¬†A single, lean, VPS for running PHP and static websites, and then an independent VPS for each rails app I want to deploy (because running multiple versions of rails on the same production server can be a pain — and yes, I do use rvm, but only on my development box). ¬†In fact, for my upcoming rails app (second attempt at a web-based business), I plan to run an additional VPS running just the database server.

Anyway, I’m starting to ramble. ¬†I located a company called 6sync¬†that sells VPSes at a wide variety of price points. ¬†Another upshot is the ability to choose which linux distro you want to run. ¬†I’ve always been a Debian man myself, but ServInt (along with most other managed hosting providers) pretty much forces you into CentOS, which I hate, along with Fedora, RHEL, and any other rpm-based distro.

So, I bought a $15 ‘nano’ instance from 6sync and spun up a 32-bit (hey, the nano instance has only 256MB of RAM) Debian 6 server. ¬†I ssh-ed (not sure if I can use ssh as a verb, but I’m going to anyway) into my server and discovered a nice minimal Debian install ready to be configured.

Being in the mood to experiment, I wanted to try using Nginx¬†(pronounced engine-x), rather than Apache, because I heard Apache was old and busted and I wanted to be cool. ¬†Unfortunately, I couldn’t find very many guides on setting up a LEMP (Where the E stands for “engine-x”, as opposed to the more well known LAMP) ¬†stack on Debian, so I had to piece together information gleaned from various sources on the intertubes to come up with something that worked.

First, I added the dotdeb sources  to my /etc/apt/sources.list file:

deb http://packages.dotdeb.org stable all

That done, I then made sure my package database was up to date:

apt-get update

Now, the first step is to install MySQL:

apt-get install mysql-server mysql-client php5-mysql

There, that was easy. Next up is Nginx.
Now Nginx is pretty easy to install, though some people may want to compile from source because they are nerds, but I am not a nerd. I just spend all of my spare time programming and writing about it on my blog, because I’m not a nerd. Anyway:

apt-get install nginx

Of course, I’m also going to need PHP if I want to run WordPress:

apt-get install php5 php5-fpm

Now, there is one configuration change needed to php.ini to start with. In the file /etc/php5/fpm/php.ini, I found the line:

cgi.fix_pathinfo=1

and changed it to:

cgi.fix_pathinfo=0

Ok, that’s done. Now for the fun part of actually configuring the web server. Since I plan to run multiple websites from this VPS I’ll need to set up a few virtual hosts. I was actually surprised at how much easier this is to do on Nginx than Apache. For my first site, jamesadam.me, I set up a new user, jcadam, with a home directory at /home/jcadam as follows:

adduser -g www-data jcadam

Then, in the /etc/nginx/sites-available directory, I created a new file called http://www.jamesadam.me, and configured it thusly:

 server{
        listen 80;
        server_name jamesadam.me www.jamesadam.me;

        access_log /var/log/nginx/website.access_log;
        error_log /var/log/nginx/website.error_log;

        root /home/jcadam/public_html;
        index index.php index.htm index.html;

        location ~ .php$ {
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME /home/jcadam/public_html$fastcgi_script_name;
                include fastcgi_params;
        }

        location / {
                index index.php index.html index.htm;
                try_files $uri $uri/ /index.php?q=$uri&$args;
        }
}

I made a link to this file in the /etc/nginx/sites-enabled directory also:

ln -s /etc/nginx/sites-available/www.jamesadam.me /etc/nginx/sites-enabled

I want my web files to be served from /home/jcadam/public_html. The ‘location ~ .php$’ section is needed to enable PHP support. That last line containing the ‘try_files’ command I added later, after I discovered that the pretty permalinks in WordPress wouldn’t work without it.
My first test was to create a test page at /home/jcadam/public_html/index.php that contained nothing but the phpinfo() command. Since that worked, I figured it was time to go on and install wordpress.
First, I downloaded wordpress:

wget http://wordpress.org/latest.tar.gz

and unzipped it into my public_html directory.
Next, I suppose WordPress would like a database to work with. So, I logged into mysql as the root database user(which I set up when I installed MySQL) and issued the following commands:

CREATE DATABASE wordpress;
CREATE USER the_user@localhost; #No, not my real user name :)
SET PASSWORD FOR wordpressuser@localhost= PASSWORD("12345"); #No, not really my password.  Luggage combination, yes.
GRANT ALL PRIVILEGES ON wordpress.* TO the_user@localhost IDENTIFIED BY '12345'
FLUSH PRIVILEGES;
exit

After that, I connected to my server using a web browser and went though the WordPress web-based configuration with no trouble… though I did need to set up my wp-config.php file manually, but that was not difficult ūüôā