Ubuntu, Rails, Apache, Passenger, Capistrano & You
September 3rd, 2008 by RadarNow What?
So you’ve got a freshly installed copy of Ubuntu Server, you’ve logged into the server with your intent being to create a Rails server… only you don’t know how or you’re not entirely sure. Good thing this guide’s here to guide you through that. Right now you should have a prompt like this: you@server:~$ _. If you don’t, I can recommend one of three things:
- Turn on your screen.
- Log into the server (if it’s remote)
- Install the operating system first.
I would recommend running sudo apt-get dist-upgrade right now. This should only take a few seconds as it downloads and installs all the packages.
Firstly you’ll want to update the sources for your system by running sudo apt-get update, this is so Ubuntu knows where to find the packages. (Props to Ryan G for his comment)
The next thing we want to install is build-essential, which can be done by typing: sudo apt-get install build-essential and this will install all the essential packages you need in order to compile stuff on your machine.
We’ll now want to add a user that we can deploy to. We’ll call this user deploy and we’ll add it using useradd deploy -m with the -m option creating the /home/deploy directory for us.
MySQL users
You’ll need to install MySQL by issuing sudo apt-get install mysql-serverPostgreSQL users
You’ll need to install PostgreSQL (unless you selected that option when installing Ubuntu Server) by issuing sudo apt-get install postgresqlRuby, Ruby, Ruby, Ruby!
Now you’ll need to install ruby and all the associated packages, using the command that resembles this: sudo apt-get install ruby-full ruby1.8-dev and will install the following packages:irb1.8: Interactive Ruby Console, letting you type Ruby code and see the output immediately. Useful because it stops you from creating files like test.rb, and then running them once using ruby test.rb and then forgetting about them. libopenssl-ruby1.8: Enables Ruby to use SSL. libreadline-ruby1.8: Enables Ruby to use the readline library, for line editing and whatnot. libruby-1.8 & ruby1.8 & ruby 1.8-dev: Collection of libraries to run Ruby and development headers. rdoc1.8 & rdoc: Ruby Document Generator, necessary for generating document down the road. ri1.8 & ri : Plain-text based version of the Ruby docs. Example ri Integer will show useful information about the Integer class.
Ruby is now installed as ruby1.8. Now, if you’re like me and don’t like typing any more than you have to, you can symbolically link this ruby1.8 file to just /usr/bin/ruby. To do this, just type sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby and it’s all done. This way, you can type ruby AND ruby1.8 and it’ll do the same thing.
After that’s all done, head over to the the rubygems download page and get Rubygems 1.3.1, unpack it and install it yourself. Alternatively, you could use this command and it’ll download it, unpack and install it for you and do some clean up after:
wget http://rubyforge.org/frs/download.php/38646/rubygems-1.3.1.tgz &&
gunzip rubygems-1.3.1.tgz &&
tar xf rubygems-1.3.1.tar &&
cd rubygems-1.3.1 &&
sudo ruby setup.rb &&
cd .. &&
rm -r rubygems-1.3.1*
Rubygems installs an executable called gem1.8, which again is more typing than what we need. We’ll just symbolically link this one too: sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
Now we can install Rails and Passenger by typing sudo gem install rails passenger. This will install Rails and Passenger, along with all the required dependencies.
Apache & Passenger
The next step is to install apache: sudo apt-get install apache2-mpm-prefork apache2-prefork-dev which will install a whole slew of packages including an apache2 server and the development headers for it, too many in fact that I shall not list them here! Just trust me on this one.
After this is done, run sudo passenger-install-apache2-module and follow the instructions there. After it’s done pay attention to the last three lines it tells you to put into your apache configuration file:
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6
PassengerRuby /usr/bin/ruby1.8
For that last line, you can use either /usr/bin/ruby1.8 or /usr/bin/ruby, since we symbolically linked them all that time ago. We’re going to put these lines into /etc/apache2/sites-enabled/000-default at the top of the file and change a few things in the file and our end result should look like this:
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6
PassengerRuby /usr/bin/ruby1.8
NameVirtualHost *
ServerAdmin you@somewhere.com
DocumentRoot /home/deploy/app/current/public
ErrorLog /var/log/apache2/error.log
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature On
After editing this file you’ll need to restart Apache by typing: sudo /etc/init.d/apache2 restart. Also, you may want to remove the index.html file currently residing in /var/www by tpying sudo rm /var/www/index.html
Capistrano
Now you want to deploy your uber-mega-ultra-hyper application to the server! To do this we can use Capistrano. If you haven’t already, on your development machine install Capistrano by typing sudo gem install capistrano. When Capistrano is installed go into your uber-mega-ultra-hyper application’s root directory and type capify .. This will capify (say it out loud in an announcer-style voice, oh yeah) your application by creating a Capfile in the root path and a deploy.rb file in the config folder. What we’re really interested in here is the config/deploy.rb file which now looks kind of sparse:set :application, "set your application name here"
set :repository, "set your repository location here"
# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}"
# If you aren't using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion
role :app, "your app-server here"
role :web, "your web-server here"
role :db, "your db-server here", :primary => true
But we’ll give it some lovin’:
set :application, "uber-mega-ultra-hyper"
set :repository, "git://github.com/you/uber-mega-ultra-hyper"
set :deploy_to, "/home/deploy/app"
set :scm, :git
role :app, "uber-mega-ultra-hyper.com"
role :web, "uber-mega-ultra-hyper.com"
role :db, "uber-mega-ultra-hyper.com", :primary => true
namespace :passenger do
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
# For deploying a database.yml file.
namespace :deploy do
task :after_update_code, :roles => :app do
run "ln -nfs #{deploy_to}/shared/system/database.yml #{release_path}/config/database.yml"
end
after :deploy, "passenger:restart"
Subversion Users: You’ll need to run apt-get install subversion if you want to use svn with Capistrano.
If you’re like me and you’ve ignored your config/database.yml file from your repository, you may want to create one. The great thing about Capistrano is that you can put files like this in a shared directory. I’ve put a database.yml file for my application in /home/deploy/app/shared/system. Right now, you wouldn’t have a /home/deploy/app/shared directory unless you created it so go right ahead now and create it using (while logged in as deploy): ~/app/shared/log ~/app/shared/system. This command will also create the config, log and shared directories. Two of these directories, log and shared are symbollically linked from current/log to shared/log and current/public/system to shared/system respectively. Go ahead now and create your shared/system/database.yml file.
In your Rails application’s root directory, type cap deploy to put your application on the remote server. You may be prompted for a password. When that’s done, go have a look at your application and make sure everything is functioning correctly.
That’s all from the guide, I hoped you enjoyed it and learned something.

September 5th, 2008 at 2:27 am
I highly advise AGAINST putting dist-upgrade in crontab.
Reasons are numerous…
But let me just put it this way. If they update apache and (for whatever reason) the configuration files for apache need to change, dpkg will back up your config file and replace it with a new apache default. This is expected behavior, as altering your file could cause instability and you woud be relatively unaware of where the change occurred (unless you know how to use deb-conf religiously).
Some updates do not always go well – in fact, there are times when you may lose connectivity to your server. If SSH updates and restarts, but is unable to come up – then you have yourself a bit of a problem.
Also, you are better off doing a straight sudo apt-get install apache2, and then later having dpkg resolve dependencies if prefork is needed. Worker is better if you are not using mod_python or PHP, and since you aren’t, you want to use worker, especially if you’re proxying into something else. If the module has threading issues like php/python, then dpkg will resolve the dependency appropriately – however, doing it the other way may cause you to not have a full apache install, which can cause stability issues later.
With MySQL, there is actually a better way to do it much like apache – sudo apt-get install mysql-server. This will also include some rather important libraries as well as a great additional number of associated packages for MySQL (Although admittedly, I’ve only ever run mysql-server so I do not know what selecting client-5.0 and server-5.0 will do).
Also, need to talk to you… server changes are coming down the pipe very quickly here soon.
October 1st, 2008 at 4:46 am
Great thanks!
January 30th, 2009 at 3:52 am
frozenplague.net – cool sitename man)))
March 4th, 2009 at 7:17 am
Just a note, I had to run sudo apt-get update before sudo apt-get install build-essential otherwise, it can’t find build-essential