Even Dave Thomas admits it:
Then you reach the part where you have to deploy your application, and you find yourself with two black eyes,...
I spent a good bit of this summer working on websites for ApacheCon US 2007 and OS Summit Asia 2007 which will be in Atlanta and Hong Kong this fall. (You should attend!) There’s a whole long sad story behind the Apache conference websites, but I’ll spare you that (for now). Instead, I wanted to collect in one place all the steps and articles you need to get Rails up and running on a Media Temple dedicated virtual server.
Our goal is to have a Ruby on Rails applicatin running on a Mongrel cluster proxied by Apache httpd. We’ll use Capsitrano to automate the deployment process. In the end, we’ll be able to issue a single command to tag the release in subversion, check it out on the server, and deploy the new code. We’ll start with a bare dedicated virtual server.
The links in the instructions below go directly to articles that explain how to accomplish the task. Since most of this has been written up before, I’m only going to collect all the information together and put it in a sensible order. I’d recommend reading the whole tutorial through once before embarking on your quest. The first time I did this, it took me several days (much of it spent on a separate DNS mess).
I assume that you have a working Ruby on Rails application and that you’ve got a dedicated virtual server account. I also assume you know some basic unix commands, having a working knowledge of tools like ssh and svn.
Also, have a notebook handy to write down all the usernames and passwords you’ll be creating because you’ll end up with several of them.
Two other points: I use “myDomain” in place of whatever domain name your website has. My rails applications are also deployed on a subdirectory of a subdomain, which is a bit non-standard. Take that into account as you continue reading.
As soon as you get your dedicated virtual server account, you’ll want to get root access and “install the developer tools.”: http://kb.mediatemple.net/article.php?id=240 Both of these require opening tickets with MediaTemple, so get that started right away. While you’re waiting, you can use Plesk to add your domain and any subdomains.
As soon as you have root access, you’ll want to add an ssh account and remove root’s ssh access. Then we’ll install subversion which includes creating subdomain such as svn.your-domain.com. If you’re interested, you can also install trac. Now you’ll want to svn import your code. I recommend the typical branches,tags,and trunk directory structure. Make sure you remember to check the code out again after the initial import.
While you don’t have to use subversion to deploy your web application, you really should be using some form of revision control. So if it’s not subversion, pick your favorite other SCM. I’ll be using subversion in this tutorial.
The dedicated virtual server includes Ruby but you should check the version and confirm it’s what you need (ruby --version).
You’ll need to install rubygems followed by all the gems you need for your application. If you’re really lucky, this includes RMagick. Minimally, you’ll need the gems for Rails and Mongrel. I had to install the following:
$ gem install rails -y
$ gem install daemons -y
$ gem install fastthread -y --source=http://mongrel.rubyforge.org/releases
$ gem install mongrel -y --source=http://mongrel.rubyforge.org/releases
$ gem install mongrel_cluster -y --source=http://mongrel.rubyforge.org/releases
$ gem install mysql -- --with-mysql-include=/usr/include/mysql --with-mysql-lib=/usr/lib/mysql
At this point, you should read Tom’s article on Deploying Ruby on Rails, Mongrel, and Pen on a MediaTemple (dv) 3.0 Server who has done most of the work for all of us. However, I varied from his instructions. I’d sugget reading his article first and then finish reading this article and deciding for yourself which approach you want to take. You can mix and match some of the steps too. You should also check out MediaTemple’s own article on setting up a Mongrel cluster as well as the articles I have listed in the next section on Capistrano.
If you want to have Capistrano manage your deployment process, then I recommend getting that setup before finishing the steps of getting Apache and Mongrel configured. Part of the reason for this is that some of the files you’ll use for Apache and Mongrel will be located in your Rails source tree. So you’ll need to get that deployed onto the site first. And to do that, you’ll want to use Capistrano.
I used the following three articles to get Capistrano setup:
I also decided I wanted to deploy from subversion tags instead of directly from the main trunk. The code and instructions can be found at on Anil Bawa Cavia’s website. The comments include a bug fix.
My deploy.rb file includes the following custom tasks:
desc "Restart the mongrel cluster"
task :restart, :roles => :app do
/etc/init.d/mongrel_cluster restart
end
task :tag, :roles => :app do
run "svn cp http://svn.myDomain.com/rails/trunk http://svn.myDomain.com/rails/tags/#{ENV['TAG']} -m 'tagging release #{ENV['TAG']}'"
end
task :tag_and_release do
transaction do
tag
deploy_tag
restart
end
end
This means that all I need to do to deploy the website is issue a command such as this:
rake remote:tag_and_release TAG=acus2007_v0.1.0
I have Capistrano log into my server as the domain user setup by Plesk. The $HOME for this user is /var/www/vhosts/mDomain, but that user doesn’t have full permissions in that home directory. So here’s what you want to do. I’m assuming you’re going to have Capistrano use the directory /var/www/vhosts/myDomain/apps for your Rails applications.
$ ssh myDomain.com
$ su
$ cd /var/www/vhost/myDomain
$ mkdir apps
$ mkdir .subversion
$ chown -R domain-user:psaserv apps
$ chown -R domain-user:psaserv .subversion
$ su domain-user
$ cd apps
$ svn co https://svn.myDomain.com/rails/trunk test
$ rm -rf test
This creates all the necessary directories and caches your subversion username and password. Depending on how what user you run your mongrel cluster under, you may also have to add this user to a mongrel group, or give it sudo rights. I ended up putting /var/run/mongrel_cluster under the control of my domain user, but I’m sure some sysadmin out there will have a better idea.
With all this in place, you’re ready to cross your fingers and run rake remote:exec ACTION=setup followed by your first deploy: rake remote:tag_and_release TAG=v0.0.1
I’m not going to get into setting up the database in this article. But it’s at this point that you’ll need to create your database (probably MySQL) and run your Rails migrations.
Congratulations! Capistrano has now setup and deployed your website. Of course, not everything is done. If you’ve skipped setting up Apache and the Mongrel cluster, you’ll need to get that into place now. The files you’ll be working with include:
/var/www/vhost/myDomain/config/vhost.conf/var/www/vhosts/myDomain/apps/2007/current/config/servers.txt/var/www/vhosts/myDomain/apps/2007/current/config/mongrel_cluster.ymlI started out with a cluster of 3 Mongrels. Due to a memory leak (probably from rmagick), I dropped that down once I had multiple Rails applications all running on the same server.
I also deployed my applications on a subdirectory, that is http://www.ossummit.com/2007 versus http://www.ossummit.com/. This is reflected in the configuration files below. The following two articles go into the details of subdirectory deployment with Rails and Mongrel:
Since it’s a bit long, my /var/www/vhosts/myDomain/conf/vhost.conf is here. Make sure the file /var/www/vhosts/myDomain/conf/httpd.include has the line:
Include /var/www/vhosts/myDomains/conf/vhost.conf
One of my domains did not and I’m not sure why. The file strictly warns you against adding this, but I did anyway. If someone from MediaTemple or more familiar with Plesk wants to explain why this is the case, please leave an update as a comment.
In /var/www/vhosts/myDomain/apps/2007/current/config/servers.txt list the mongrel instances you’ll be using. The Apache configuration file will parse this list into an array and randomly proxy to them.
server 127.0.0.1:8003 | server 127.0.0.1:8004 | server 127.0.0.1:8005
In /var/www/vhosts/myDomain/apps/2007/current/config/mongrel_config.yaml list your application location, the starting port number and the number of servers to start. Since I’m deploying on the subdirectory /2007 I include the prefix command.
---
cwd: /var/www/vhosts/myDomain/apps/2007/current
log_file: log/mongrel.log
port: "8003"
environment: production
address: 127.0.0.1
pid_file: /var/run/mongrel_cluster/mongrel.pid
servers: 3
prefix: /2007
You then want to create a symbolic link for the mongrel_config file:
$ ln -s /var/www/vhosts/myDomain/apps/2007/current/config/mongrel_config.yaml /etc/mongrel_cluster/[APP_NAME].yml
At this point, everything should be in place. You can start your rails application as follows:
$ /etc/init.d/mongrel_cluster start
$ /etc/init.d/httpd reload
There’s a reason the Pragmatic Programmers are putting out a book on Rails deployment—it’s not simple. Hopefully, this article and the links I’ve collected here make it a bit easier for the next victim.
Commentary