Rails, Capistrano, Mongrel and Apache (with SSL) on Gentoo
There is a happy occasion in the development of an application — deployment. Users will use it, you will receive (hopefully) some money, there will be some bugs.. well, maybe not so happy occasion.. ;>
In most situations you will have to repeat a deployment process several times (bug fixes, new features, etc.). Maybe the process is not very complicated, but an automation will minimise possible mistakes such as typos or omitted commands.
Fortunately, there is a nice tool for Ruby on Rails applications — Capistrano.
Now we know about a tool to automate the deployment of an application, but we need to deploy our application to a production environment — I decided for the combination of Mongrel and Apache.
…and everything runs on Gentoo :)
Let’s start — here is my short howto:
Introduction
Let’s define CLIENT as a computer where you are developing an application, SERVER as a computer where you are going to deploy it and APP as the name of your application.
I assume that Gentoo is installed on both computers.
I decided to create a special user APP for the application on the server (if you do not like it, then all paths /home/APP replace with your favourite path ;).
I prefer the PostgreSQL database.
A short remark for copying text — if you would like to copy a text without any line numbers (they are fine for reading, but not for using on a command line or in a text file) click on the [Show Plain Code] link for each block of code or configuration file to display an unformatted text.
I. Client Software Installation
We will need to install Capistrano and Mongrel:
-
emerge ruby-termios capistrano
bacause there is not ebuild for Mongrel, you have to install it with gem:
(The -y
option is a shortcut to the --include-dependencies
option.)
II. Server Software Installation
Let’s install necessary software:
We will need Apache 2.2 (because the mod_proxy_balancer
) that is masked in the portage (7. January 2007), so it is necessary to unmask it:
add the following lines to the /etc/portage/package.unmask
file:
-
net-www/apache
-
dev-libs/apr
-
dev-libs/apr-util
to the /etc/portage/package.keywords
file (thanks to Steve for his comment how to improve this):
-
~net-www/apache-2.2.3
-
~dev-libs/apr-1.2.7
-
~dev-libs/apr-util-1.2.7
and install it:
-
emerge apache
If you plan to support SSL (for a secure communication between a client and the server), do not forget to add the ssl
use flag for Apache — add the following line to the /etc/portage/package.use
file:
-
net-www/apache ssl
III. Server Side Configuration
Let’s create a special user for the application (not necessary):
-
useradd -d /home/APP -m APP
-
passwd APP
Open the /etc/sudoers
file and add the following line:
-
APP ALL=(ALL) ALL
The main reason for creating a special user was a fact that the sudo command has to be available for a user. Frankly, I do not like the sudo command (sorry, Ubuntu guys). With
su -
it is clear when I have root privileges and when not (on Ubuntu I usually typesudo sh
:).
I also created a new database user APP:
-
su –
-
su – postgres
-
createuser APP
and a new production database:
-
createdb -E utf-8 APP_production
IV. Client Side Configuration
Go to the application directory and create a configuration for Mongrel:
it will create the config/mongrel_cluster.yml
file; basically you do not need to edit it.
Then create a configuration for Capistrano (do not forget that APP is the name of your application):
-
cap –apply-to . APP
and in this case we need to modify the generated file config/deploy.rb
— I added or changed the following lines:
-
span style=”color:#008000; font-style:italic;”>#you set the APP name with the cap command
-
"APP"
-
#a path to your repository
-
"svn+ssh://USERNAME@SVN_SERVER/projects/#{application}/trunk"
-
-
role :web, "SERVER""SERVER"
-
role :db, "SERVER"#where to deploy (copy the files) on the server; I created a special user APP for the application (if you do not like it, replace the /home/#{application} part with your path
-
"/home/#{application}/production/#{application}"
-
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
-
#if the server login name is different to the development computer login name; in my case the user name is the APP name
-
set :user, "APP"
It is also necessary to update the config/database.yml
file:
-
#no changes needed, just to show the development configuration
-
#I changed the username to the database user name on the server
-
Do not forget to add all new files and commit all changes (because Capistrano uses files in your repository).
V. Deployment
Create the basic structure on the server (files from the repository is not used in this step):
If there is something wrong: check the config/deploy.rb
file; try to log to the server manually e.g. ssh APP@SERVER
or ssh APP@SERVER -v -v -v
; did you add and commit the config/deploy.rb
file?
Let Capistrano do the magic :)
-
rake remote:cold_deploy
If there is something wrong: check the config/deploy.rb
file; try to check out the repository manually on the server.
To check if everything went fine, access the http://SERVER:8000
link or the http://localhost:8000
link on the server. If you have a firewall, probably only the second option will work — you can use the console browser lynx
or to be more professional ;) wget http://localhost:8000
.
Anytime you can delete the
/home/APP/production
directory on the server and start from scratch. All files are safely stored in your repository. (Except the data in the database on the server.)
If you use migrations to create databases and to insert initial data (of course that you are! :), call the following command to run migrations on the server:
-
rake remote:migrate
For any next deployments use the following command:
-
rake remote:deploy
VI. Apache Configuration
Log to the server as root (do you remember? su -
:) and add the -D PROXY
option to the /etc/conf.d/apache2
file. Because I have Apache only for one application, my configuration looks like:
-
APACHE2_OPTS="-D INFO -D LANGUAGE -D SSL -D SUEXEC -D PROXY"
i.e. I removed the -D DEFAULT_VHOST
and -D SSL_DEFAULT_VHOST
options.
For the new application we will create a new virtual host — create a new /etc/apache2/vhosts.d/01_APP_vhost.conf
file with the following content[RoRBook] (do not forget that APP is the application name):
-
span style=”color: #7f007f;”>"/home/APP/production/APP/current/public"# Check for maintenance file and redirect all requests
-
# Rewrite index to check for static
-
# Rewrite to check for Rails cached page
-
# Redirect all non-static requests to cluster
-
Restart the Apache web server:
and test the http://SERVER
link (or http://localhost
on the server) — your application should appear :)
Of course, do not forget to add the Apache service to start when the server starts:
-
rc-update add apache2 default
To start the Mongrel instance I added the following line to the /etc/conf.d/local.start
file:
You can stop server with the
cluster::stop
action and start with thecluster::start
action.
VII. Apache SSL Configuration
As a bonus, here are instructions how to setup the SSL support. I wanted to have only one application that has to be accessible only via HTTPS, i.e. if a user uses insecure HTTP, (s)he will be automatically redirected to secure HTTPS.
Change the /etc/apache2/vhosts.d/01_APP_vhost.conf
file:
-
span style=”color: #7f007f;”>"/home/APP/production/APP/current/public"‘https’# Check for maintenance file and redirect all requests
-
# Rewrite index to check for static
-
# Rewrite to check for Rails cached page
-
# Redirect all non-static requests to cluster
-
# Redirects only the URL http://SERVER to https://SERVER, but not http://SERVER/anything
-
#Redirect permanent / https://SERVER
-
-
# More general redirect, it redirect all URLs http://SERVER/anything to https://SERVER/anything
-
It is necessary to create a certificate file and a certificate key files[ApacheDoc]:
-
#key file, do not forget the pass-phrase
-
openssl genrsa -des3 -out APP.key 1024
-
#certificate file; for the "Common Name" (CN) type the SERVER name or the SERVER IP address
-
openssl req -new -x509 -nodes -sha1 -days 365 -key APP.key -out APP.crt
-
#decrypted key file; not very secure
-
and copy the last two created files to the /etc/apache2/ssl/
directory.
I use the decrypted key file, because the Apache web server asks for the pass-phrase when it starts with an encrypted key file.
Hopefully I helped you to configure your production environment. Btw. this is my first production installation :), so if you have better experiences, please, you are welcome to write a comment…
[RoRBook] Agile Web Development with Rails, 2nd edition
[ApacheDoc] http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html