Table of Contents

Capistrano, LSAPI, and LiteSpeed

Original Author: Mathew Abonyi

Capistrano is a highly flexible deployment system (among other things) written in Ruby. It is used primarily by Rails applications, but can be suitable for any kind of web/database/application combination (Ruby or otherwise).

For more information about Capistrano, please visit CapistranoRB.

Requirements

If any of this is bedazzling, please see the Capistrano Manual above.

Note: This wiki is based on Capistrano 1.2.0. Quick Summary

Deploying an application to a LiteSpeed server requires you to check out your application to a new release directory, change the link for the RAILS_ROOT/current directory, and then restart the LiteSpeed server.

Before restarting Apache-style gives you shivers, know that LiteSpeed’s restart is instant, with no downtime and negligible effect on the server.

Step 1: Restricted SUDO

For those of you who do not have sudo set up to allow lswsctrl, you must change your /etc/sudoers file using visudo.

To restrict a user to only restarting the server, add the following with visudo:

Cmnd_Alias  LSWS = /opt/lsws/bin/lswsctrl restart
depuser     ALL = (root) LSWS

The LSWS command alias should be set to the path of your lswsctrl command.

Note: If you do not have root access yourself, you need to ask your system administrator to add you with the above sudoer entry. It only allows you to restart the server to get your application refreshed.

Step 2: Custom Deployment

The standard deployment script for Capistrano 1.2.0 assumes you are using SVN, deploying to one server, and restarting using the reaper script. To overwrite the default task, add the following to the end of your project’s config/deploy.rb:

set :lsws_cmd, "/opt/lsws/bin/lswsctrl"

task :restart, :roles => :app do
  sudo "#{lsws_cmd} restart"
end

Change the lsws_cmd to wherever your lswsctrl resides.

Note: You may wish, for cleanliness, place the ‘set’ command with your deploy_to, rails_env and user ‘set’s. A full deploy.rb can be seen at the end of this wiki for single and multiple application server deployments.

Step 3: Unprivileged User (Optional)

If you want your application to run in suEXEC mode, you need to create an unprivileged user for it and add whichever user will be deploying on the server to its group. It’s a little more tricky than most things and requires you to have at least this in your /etc/sudoers file:

depuser ALL = (root) LSWS, /bin/chown, /bin/chmod

The irony of using suEXEC is that you practically need root privileges to do it. Of course, your deployment user should not have such a frail password if it has this much power through sudo.

On most Linux systems, creating an application user would look like this:

sudo adduser --system --group --no-create-home --disabled-login --gecos "My Web App" mywebapp
sudo usermod -G mywebapp deploymentuser

Once you have your deployment user in the application user’s group, we set up Capistrano to deploy and fix permissions in config/deploy.rb. We do this after the code is checked out, like so:

set :jail_user, "mywebapp"
set :jail_group, "mywebapp"

task :after_update_code, :roles => :app do
  sudo <<-CMD
  sh -c "chown -R #{jail_user}:#{jail_group} #{release_path} &&
         chmod -R g+w #{release_path}"
  CMD
end

Now when you deploy, your entire application directory will be owned by the suEXEC user. If there are only specific directories (such as ‘public’ and ‘tmp’) you want to allow access to your application user, change the chown commands accordingly.

Step 4: Test It Out

Assuming you have your application, deploy_to and other parts of your Capistrano script configured properly, try it out:

shell /home/myproject$ cap deploy

The two most important things you should see are the password prompt for sudo and the lswsctrl command being run. It will probably not give any output, but you’ll notice your application is the latest deployment.

Step 5: Mulitple Application Servers

This is where Capistrano really shines. To make your application scale, just change this:

set :app, "www.example.com"

To this:

set :app, "www.example.com", "www2.example.com", "www3.example.com"

All of the deployment steps will be replicated across the application servers. It is important that they all have the same setup (i.e. same users, directory structure and the presence of LiteSpeed). Example Deployment Script

set :user, "depuser"
set :svn_username, "depuser"

set :application, "www.example.com"
set :repository, "svn+ssh://#{user}@www.example.com/svn/trunk"

set :web, "www.example.com"
set :app, "www.example.com", "www2.example.com", "www3.example.com"
set :db, "db.example.com", :primary => true

set :rails_env, "production"
set :deploy_to, "/var/www/#{application}"

set :lsws_cmd, "/opt/lsws/bin/lswsctrl"

set :jail_user, "mywebapp"
set :jail_group, "mywebapp"

task :after_update_code, :roles => :app do
  sudo <<-CMD
  sh -c "chown -R #{jail_user}:#{jail_group} #{release_path} &&
         chmod -R g+w #{release_path}"
  CMD
end

task :restart, :roles => :app do
  sudo "#{lsws_cmd} restart"
end

Good Luck!