My current setup :
- I develop a Rails app on a Mac (my “local” machine).
- The Rails app source code is hosted in a Git repository on GitHub.com
- The deployment server is remote : it is a Dedibox running a Debian.
The purpose of this article is to help in the setup of the application and the machines (local and remote deployment server) to be able to deploy the code of an application hosted on GitHub.com to a remote deployment server.
Prerequisities :
Ruby + Rails stack on the local machine, as on the deployment machine. On Mac OS Leopard, Ruby+Rails are preinstalled, just upgrade Rails if necessary.
On the Linux Debian, please follow one of my former articles to setup Ruby+Rails+NGinx+Mongrel.
Capistrano 2 should be installed on the local machine.
If not :
# sudo gem install capistrano
Then, you should generate 2 SSH keypairs >
- On your local machine, for the SSH session between your local machine and the remote server, and between your local machine and GitHub.com (when you pull the code from GitHub repository locally)
- On the deployment server, for the communication with GitHub.
1) Local machine :
# ssh-keygen -t rsa
push the ~/.ssh/id_rsa.pub (Public key) to the remote server: use a “deployer” account for this, and copy into .ssh/authorized_keys2 file.
Go to Github.com , log with your account, and in “Account” page, add the content of your key (click “add another deploy key”)
2) Remote server : log as “deployer” account.
# ssh-keygen -t rsa
At the prompt how to call the Key, enter /var/www/.ssh/github
Once keypair generated , create the file ~/.ssh/config and paste this:
Host github.com
IdentityFile ~/.ssh/github
Go to Github.com , log with your account, and in “Account” page, add the content of your key (click “add another deploy key”)
Install git on the deployment server :
On Debian, install git and git-core :
# sudo apt-get install git
# sudo apt-get install git-core
We suppose you have a copy of the Rails application locally, in the folder ~/Projects/my_app
Open a Terminal then:
# cd ~/Projects/
# capify my_app
Then edit the ~/Projects/my_app/config/deploy.rb
Set application name, deployment location on the remote server, SSH options, SCM options :
set :application, “my_app”
# deploy_to : location of the application on the remote deployment server .
# Create this folder before cap deploy.
set :deploy_to, “/var/www/my_app”
set :scm, “git”
set :repository, ”git@github.com:<username>/my_app.git”
set :branch, “master”
default_run_options[:pty] = true
set :ssh_options, { :forward_agent => true }
set :user, “deployer”
role :app, “servername.domain”
role :web, “servername.domain”
role :db, ”servername.domain”, :primary => true
You have an optional setting “remote cache” for Capistrano.
set :deploy_via, :remote_cache
Remote caching will keep a local git repo on the server you’re deploying to and simply run a fetch from that rather than an entire clone. This is probably the best option and will only fetch the differences each deploy.
Now you are ready to deploy :
On your local machine, from the Terminal :
# cd ~/Projects/my_app
# cap deploy
Troubleshootings:
On the remote server, the ROOT folder of your deployed Rails application will be :
/var/www/my_app/current
The “current” folder being a symlink to the /var/www/my_app/<release no> folder where the application is hosted. After every “cap deploy” , a new folder <release no> is created and the “current” link is updated. Old releases are kept, so you can relink easily on a previous release if you see some regressions in the last one. With the time and the the often deployed releases, you’ll need one day to erase the oldest releases if all these releases consume too much space on your deployment server.
At deployment of your application, the ”log” folder (/var/www/my_app/current/) is a symlink to /var/www/my_app/shared/log folder, that isn’t created automatically the first time.
Do create the folder “/var/www/my_app/shared/log” after the first deploy.


3 Comments
Great tutorial, I liked the symlink tip to rollback to the previous release easily
But that’s no always possible if you made changes in the database tables structure (aka ddl)
Thanks a lot, Thanks a lot, Thanks a lot,
Thanks a lot, Thanks a lot, Thanks a lot
I prefer to do a rolling seven days of backups so I use the day of the week instead of the date. This way I always have 7 days of backups, but no more.
date=`date +%a`
mysqldump -uroot -ppassword –opt mydatabase > db_backup_$date.sql