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

“Capify” your application

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

  1. 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) :(

  2. Thanks a lot, Thanks a lot, Thanks a lot,
    Thanks a lot, Thanks a lot, Thanks a lot

  3. 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


Post a Comment

*
*