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
- a web application to deploy
- a working LSAPI setup
- a working Capistrano installation on your client machine(s)
- Capistrano set-up for your application on your server machine(s)
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!