Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Agile Web Development With Rails, 2nd Edition (2006).pdf
Скачиваний:
30
Добавлен:
17.08.2013
Размер:
6.23 Mб
Скачать

REPEATABLE DEPLOYMENTS WITH CAPISTRANO 618

every flavor of Unix (including Linux and Mac OS X) as well as Windows. And it has proven itself over the years. New releases of Apache get better and better and don’t tend to introduce regressions.

Out of the box, Apache 2.2 supports the load balancing of HTTP requests with the built-in mod_proxy_balancer. You can combine this module with Apache’s powerful mod_rewrite module to create truly impressive handling of requests based on any number of criteria that are important to you. If you have an existing complex web site, chances are that you’re running Apache to weave all the parts together.

Lighttpd: Up and Coming Contender

In contrast to the do-anything Apache, Lighttpd is a simpler, less flexible web server. Its raison d’etre is performance. For serving static content, it can be really fast and reportedly stays usable under heavier loads than Apache. It’s also the only server in recent memory that has an actively developed FastCGI implementation. So, if for some reason you want to use FastCGI to deploy your Rails applications, Lighttpd might be just the ticket.

The downside to Lighttpd is that it’s young and is under heavy development. Version to version stability hasn’t been one of its primary features: some versions have been much more stable than later versions. However, the development of this server is moving at a rapid pace, and it very well may be the wave of the future. It should be on your radar from day one.

Pound and Other Load Balancers

As we mentioned, when using Mongrel, many other web servers, including those built into hardware, become viable and powerful front ends for your Rails application. You might want to consider these once you have your application deployed and have figured out how you want to scale it to the next level. However, when you’re just getting started with deployment, it’s important to remember to leave yourself the option to integrate well with load balancers. Using HTTP-based proxying to Mongrel fits perfectly into place, so for now, just keep it in mind. Until you need it, you should probably just stick with Apache or Lighttpd.

27.4Repeatable Deployments with Capistrano

Now that we’ve talked about how a deployed Rails application is structured, we need to turn our focus just a bit and look at how we get Rails applications from our local machines up to the remote servers where it will run. When the first edition of this book was written, moving code into production was very much a duct tape and baling wire affair. Everyone did it differently, and life

Report erratum

SETTING UP A DEPLOYMENT ENVIRONMENT 619

was pretty miserable. Then, along to the rescue came Jamis Buck with a tool originally known as SwitchTower, later renamed to Capistrano.

Capistrano is a Ruby-based utility that was created in order to reliably and repeatably deploy Rails applications on remote servers. It uses SSH to communicate with the servers and execute commands on them. It’s a wildly configurable tool; however, for simple deployments, it’s straightforward to use. It’s somewhat like a turbocharged version of Rake in that Capistrano recipes are composed of a set of tasks to be performed. In Capistrano, however, tasks are set up with methods that will cause actions to happen on one or more remote servers.

Like Rails, Capistrano is opinionated software—it makes a few assumptions. The first is that you are deploying to a Unix-based system. The second is that your code is held in a repository that is accessible from both the machine you are deploying from and the machine to which you are deploying.1

The first assumption, that we’re using a Unix-based system, is important. Without getting into deep philosophical and sometimes religious arguments, it’s important noting that all of the major Rails deployments to date have been to Unix-based systems. As well, all of the Rails-core team members work on and deploy to Unix-based systems. If you have to venture off and deploy on Windows, you’re going to be on your own. Our recommendation is to not do it.

The second assumption—that you store your application in a supported source code control system—isn’t nearly as constraining. If you use a source code control system that Capistrano doesn’t support, it’s not too terribly hard to add support for it. And if you don’t use a source code control system, you really should.

So, to summarize: developers work as usual, checking code into and out of their source code repository. When it comes time to deploy into production, they issue a particular command, and Capistrano retrieves the application from the repository and deploys it onto one or more server machines. This process is illustrated in Figure 27.2, on the following page.

27.5Setting Up a Deployment Environment

As you have seen, there are many options when setting up a deployment environment. These options can be combined in many, many ways. Rather than spend two sentences in each, which wouldn’t give you much in the way of practical advice, we’ve decided to focus on detailed instructions for setting up a recommended environment using the Apache web server with mod_proxy_balancer, Mongrel, and MySQL.

1. Capistrano 1.1 supports applications hosted in Bazaar, Bazaar-NG, cvs, Darcs, Perforce, and Subversion repositories.

Report erratum

SETTING UP A DEPLOYMENT ENVIRONMENT 620

Developer

Repository

 

Application

Machines

 

 

Server(s)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

 

.

 

 

Copies files under

 

 

 

control of deploy.rb

$ rake remote:code_deploy

Figure 27.2: Capistrano Deploys from the Repository into Production

Most of the time you’ll be issuing commands on your local computer, but during initial setup you’ll also be working on your servers. We show which computer you’re using in the command prompts.

Step One: Setting Up a Machine

Once you have a suitable machine to deploy your application onto, your first job should be cleaning it up so that it’s ready. If it’s a PC, make sure it’s running the latest version of Linux, FreeBSD, or Solaris. If it’s a Mac, make sure it’s running the latest released version of Mac OS X.

The next step is to install the various software components you need. The items you’ll need to install are

The Apache 2.2 (or latest released version) web server

MySQL 5.0 (or latest released version) database server

Ruby 1.8.4 or later

RubyGems to manage Ruby-based packages

MySQL/Ruby library

Ruby Termios Library

For these components, we recommend that you use a package manager. On Ubuntu Linux, this means using apt-get. On Red Hat, use rpm. On Mac OS X, use MacPorts. Using a package manager means that it’s much easier to move between versions of software. With new versions of Apache, Ruby, and MySQL showing up all the time, each of which will contain security and performance

Report erratum

SETTING UP A DEPLOYMENT ENVIRONMENT 621

fixes that you will want, using a package manager will help you stay up-to- date.

As an example, here are the set of commands that you would use to install the above components onto a Mac OS X system using MacPorts.2

# On the server(s) and your client (if not already installed) $ sudo port install apache2

$ sudo port install mysql5 +server $ sudo port install ruby

$ sudo

port

install

rb-rubygems

 

$ sudo

port

install

rb-termios

# for readline support in irb

Once you have the above native components installed, you’ll need to install the following RubyGems: Rake, Rails, Capistrano, and Mongrel.

To install these gems quickly, use the following.

# On the server(s)

and your client (if not already installed)

$ sudo gem install

--include-dependencies rake

$ sudo gem install

--include-dependencies rails

$ sudo gem install

--include-dependencies termios

$ sudo gem install

--include-dependencies capistrano

$ sudo gem install

--include-dependencies mongrel

$ sudo gem install

--include-dependencies mongrel_cluster

At this point, you have all the bits of software that you need to launch a basic Rails application. Of course, if your application relies on other Ruby gems, you should install those as well. Now it’s time to deal with your database.

Step Two: Setting Up Your Database

Once you have MySQL up and running on your server—either by installing the prebuilt version from MySQL or by using a package manager—you’ll need to create a database as well as a database user for your application. To do this, you’ll need to do the following.

# On your database server $ mysql -u root -p

Enter password: ********

Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2080 to server version: 5.0.19

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE DATABASE myapplication;

Query OK, 1 row affected (0.01 sec)

mysql> GRANT ALL PRIVILEGES ON myapplication.* TO 'myapplication'@'localhost'

-> IDENTIFIED BY 'some_pass' WITH GRANT OPTION; Query OK, 0 rows affected (0.01 sec)

2. Debian and Ubuntu users might want to look at Chris McGrath’s write-up at http://mongrel.rubyforge.org/docs/debian-sarge.html.

Report erratum

SETTING UP A DEPLOYMENT ENVIRONMENT 622

You’ll also need to update your config/database.yml file in your application with the relevant information in the production block.

production: adapter: mysql

database: myapplication username: myapplication password: somepass

At this point, you’ve got the minimum configuration you need to for your application to talk to MySQL. Now you should also take a few minutes to think about the security implications around your database. Use firewalls and the database’s built-in mechanisms to restrict network access to the absolute minimum set of machines that need it. Make sure you have a password policy which restricts access to a need to know basis and that changes passwords frequently. Keep production passwords out of the checked-in configuration files—use Capistrano hooks to copy the production database.yml file in after each deployment. You could use something like the following.

task :after_update_code, :roles => :app do

db_config = "#{shared_path}/config/database.yml.production" run "cp #{db_config} #{release_path}/config/database.yml"

end

Finally, if you are working in a regulated environment, make sure that your policies meet or exceed the requirements of these regulations.

Configuring Mongrel

The next step is to add the mongrel configuration to your project. To do this, execute the following in your application’s directory (we’ve split this command onto two lines to make it fit the page).

# On your local computer

$ mongrel_rails cluster::configure -e production -p 8000 \ -a 127.0.0.1 -N 2 -c /deploy/path/current

(If you get an error, make sure that you are in the top level of your application’s directory when you issue the command.)

The parameters to this command are pretty important. The -p 8000 parameter specifies that the mongrel instances will start up on ports beginning with 8000 on your deployment server. The -a 127.0.0.1 parameter will set up Mongrel to listen to the localhost interface. The -N 2 parameter indicates that two instances of Mongrel will be started. And, the -c /deploy/path/current argument is where your application will be deployed to on the remote server. Note that the word current in this path is required: the deploy/path part is the path to your application, and current is a directory that Capistrano creates inside that application structure.

Report erratum

SETTING UP A DEPLOYMENT ENVIRONMENT 623

Step Four: Deploy with Capistrano

To add the necessary files to your project for Capistrano to do its magic, execute the following command.

# On your local computer

$ cap --apply-to /local/project/path [applicationname] exists config

create config/deploy.rb exists lib/tasks

create lib/tasks/capistrano.rake

From the output, you can see that Capistrano sets up two files. The first, config/deploy.rb, contains the recipes needed to deploy your application. The second, lib/tasks/capistrano.rake, adds some tasks to your application so that you can directly call Capistrano tasks using Rake. The next step is to edit the config/deploy.rb to set it up for your deployment. For a basic setup, you need to make only a few edits to the file. You’ll need to add a require statement to the top of the file to include the mongrel_cluster recipes that will make deploying with mongrel painless:

require 'mongrel_cluster/recipes'

After you add this line, you’ll need to edit several of the properties to match your application. The properties you’ll want to edit or add are

set :application, "applicationname"

set :repository, "http://svn.host.com/#{application}/trunk" set :deploy_to, "/Library/Rails/#{application}"

set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"

role :web, "your.host.com" role :app, "your.host.com"

role :db, "your.host.com", :primary => true

Once you’ve made these edits, you’re ready to do the deployment. The first time you deploy your application, you’ll need to perform two steps. The first sets up the basic directory structure to deploy into on the server.

# On your local computer $ rake remote:setup

When you execute this command, Capistrano will prompt you for your server’s password. It then connects and makes the necessary directories. Once this command is done, you’re ready for step two: actually deploying your application. Use the following command.

# On your local computer $ rake remote:cold_deploy

This command will run, deploy your application to the server and then start the Mongrel instances. If all went well, your application will be running on

Report erratum

SETTING UP A DEPLOYMENT ENVIRONMENT 624

ports 8000 and 8001 on your remote system. You can verify that by executing the following command on your remote system.

# On your server

$ curl -I http://127.0.0.1:8000

HTTP/1.1 200 OK Content-Length: 7551

Date: Thu, 07 Sep 2006 18:02:50 GMT Cache-Control: no-cache

Server: Mongrel 0.3.13.3

Content-Type: text/html; charset=utf-8

This tells you all is well with your Mongrel setup and your application servers.

Step Five: Connect Apache to Mongrel

Once your application is deployed and running on a pack of Mongrels, the last step is to connect Apache to your app server instances. To do this, you’ll need to edit the Apache configuration on your server(s) and add the following.

<Proxy balancer://mongrel_cluster> BalancerMember http://127.0.0.1:8000 BalancerMember http://127.0.0.1:8001

</Proxy>

<VirtualHost *:80> ServerName myapp.com

DocumentRoot /Library/Rails/myapplication/current/public

<Directory "/Library/Rails/myapplication/current/public" > Options FollowSymLinks

AllowOverride None Order allow,deny Allow from all

</Directory>

RewriteEngine On

#Check for maintenance file and redirect all requests RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /system/maintenance.html [L]

#Rewrite index to check for static

RewriteRule ^/$ /index.html [QSA]

#Rewrite to check for Rails cached page RewriteRule ^([^.]+)$ $1.html [QSA]

#Redirect all non-static requests to cluster RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f

RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L]

</VirtualHost>

Report erratum