In my company, we have some RoR and PHP applications deployed in our Intranet and on public servers located in a DMZ.
We use Capistrano+Capistrano-ext(plugin) for deployment on testing servers and on production servers.
We also should switch from the default Capistrano deployment model to another for deployment to the DMZ.
1) capistrano-ext
What does capistrano-ext plugin? It provides the multistage deployment. By default, with Capistrano, you configure one file deploy.rb (with settings for one deployment server, and settings for one SCM).
Capistrano-ext helps you to create one deployment Ruby file per server, then keep your deploy.rb file to register the deployment servers :
a) install Capistrano 2 : sudo gem install capistrano
b) Install capistrano-ext : sudo gem install capistrano-ext
c) Capify your application : capify /path/to/my/app
d) from your application root folder, edit config/deploy.rb file (we suppose we have “testing” and “production” servers)
set :stages, %w(production testing)
set :default_stage, “testing”
require ‘capistrano/ext/multistage’
Nota : by default the deployment server is “testing”
e) create config/deploy/testing.rb and config/deploy/production.rb files , and add your custom stage-specific code.
f) For deployment , simply use the commands “cap production deploy” or “cap testing deploy” . When the variable :default_stage is set , just “cap deploy” (in our case , equivalent to “cap testing deploy”)
2) Deployment to servers located in a DMZ
We also have some public websites , made with PHP (custom code, or Joomla), deployed in our DMZ.
My idea was to be able to deploy the PHP code (stored in a Subversion repository) easily with Capistrano to the testing server (inside the local network) but also to the production servers (inside the DMZ). For the multistage we also use in this case capistrano-ext.
Concerning PHP code : no problem for this, you just have to capify your PHP application (the command creates the “config” folder , and a deploy.rb file inside).
The main problem concerns the servers located in the DMZ, because our Subversion repository is hosted on a server inside the local network (so invisible from the servers located inside the DMZ). By default, the deployment model from Capistrano executes remote commands (SVN/git checkout + deployment) remotely from the deployment server; you understand well in our case , the SVN checkout from DMZ servers never happens (connection blocked by the firewall).
For this, i use Capistrano 2(.4.3) and it supports the deployment model “copy” and a SFTP recipe. Thanks to this method , what does capistrano is not executing commands remotely from the deployment server , but :
a) Does the checkout from your local desktop inside a temporary folder, then archive (tar+gz) the application code of the current release.
b) Push the gzip archive to the deployment server by SFTP then remotely extract application’s files to the deployment location (/var/www/app_name/<release> + creation of a symlink “current” to the latest release + post deployment tasks as web server restart)
For this, here is the code i use in the “<APP_ROOT>/config/deploy/testing.rb” file for this deployment model (push the code to a server located in a DMZ):
set :application, “app_name”
set :repository, “svn+ssh://<host>/home/subversion/svn-repos/app_name/trunk”
set :deploy_to, “/var/www/#{application}”
set :ssh_options, {:forward_agent => true}
set :default_run_options, {:pty => true}
set :use_sudo, false
set :user, “deployer”
set :scm_user, “lbo”
set :deploy_via, :copy
set :copy_strategy, :checkout
set :copy_dir, “/tmp”
role :app, “<server>”
role :web, “<server>”
role :db, “<server>”, :primary => true
In this case don’t forget to use SSH keys between :
- Your desktop and the UNIX account (:scm_user) used to connect to your Subversion repository (deploy your public key to this Subversion server in the file <home>/.ssh/authorized_keys2).
- Your desktop and the UNIX account (:user) used on your deployment server (deploy your public key to this deployment server in the file <deployer’s home>/.ssh/authorized_keys2).
If the default Capistrano deployment model is used, you have to generate a SSH keypair on your deployment servers, then push public keys from each server to your SCM host server ( in the deployer’s UNIX account used for SVN checkout)
Source capistrano-ext


2 Comments
Hi Laurent,
very nice write up, and thanks a lot for sharing!
I have one question which I believe (from your post) you might be able to answer: Using a special “deployer” *nix account makes sense, but what should I be on the watch for – regarding
# useradd deployer ….
I would like to use a non-root deployer to run my deploys (effectively allowing me to allow others to deploy too, w/o giving them pw to root)
Thank you for your time an effort.
Cheers,
Walther
Sounds good to me. I currently work on such issues and the only printed source avaiable on that is the Pragmatic Programmers Book “Deploying Rails Applications”, as far as I know.
Thanks for publishing these experiences.
2 Trackbacks/Pingbacks
[...] Use capistrano in enterprise for PHP and Ruby on Rails applications By lbois My idea was to be able to deploy the PHP code (stored in a Subversion repository) easily with Capistrano to the testing server (inside the local network) but also to the production servers (inside the DMZ). For the multistage we also … Laurent’s Weblog – http://laurentbois.com [...]
[...] Use capistrano in enterprise for PHP and Ruby on Rails applications – [...]