Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Git Deployment with Capistrano

joequery edited this page · 11 revisions

This guide assumes you have configured your server in accordance with the Nginx Server Configuration guide.

Step 1. Delete old testapp project

If you followed through with the Nginx server config guide, you'll have a testapp directory located at /var/www. We need to delete it.

$ rm -rf /var/www/testapp

Step 2. Adjusting nginx.conf

Capistrano slightly modifies the file structure of our deployed rails app, so we must tweak our nginx configuration to match. Recall the nginx.conf file is located at /etc/nginx/nginx.conf

Open the nginx.conf file and Locate the root path specification; it should be underneath the large comment block. Change all occurrences of

root /var/www/testapp/public;

to

root /var/www/testapp/current/public;

We do this because Capistrano creates "releases", and we want our server to serve the "current" release. Since we've altered the configuration file for nginx, we need to restart the server. Let's use our nifty bash function.

$ restart_nginx
Restarting nginx: [warn]: duplicate MIME type "text/html" in /etc/nginx/nginx.conf:23
the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful
[warn]: duplicate MIME type "text/html" in /etc/nginx/nginx.conf:23
nginx.

Step 3. Creating the git user

We will create a git user whose sole purpose is to read and write to git repositories and deploy to /var/www. We create the user and assign it to the web group so it will have write access to /var/www

$ sudo useradd --shell /bin/bash -m -G web git

We need to set up the git user to store public keys. We need to login as the git user to do so.

$ sudo su git

Now set up ssh!

$ ssh-keygen -v -t rsa

Navigate to the newly created ~/.ssh folder

$ cd ~/.ssh

Create an authorized_keys file. This is where we will place users public keys.

$ touch ~/.ssh/authorized_keys

In order to test this account creation and user access, you need to paste your public key into the authorized_keys file. Your public key is most likely located at ~/.ssh/id_rsa.pub. Now, from your local machine, attempt to ssh into your server as the git user.

(local)$ ssh git@yourserver.com

This should successfully log you in as the git user. However, there currently exist a couple of security vulnerabilities, namely the git user can snoop around the home directories of other users. In other words, anyone that has access to the git user via ssh can browse around other users home directories. To solve this problem, we will revoke all group and world permissions on the home directories.

$ sudo chmod go-rwx /home/*/

Now if you want to add/remove a public key, you must login as the git user via sudo su

$ sudo su git 
$ vim /home/git/.ssh/authorized_keys
...
...

Make sure you log out of your server as the git user. Log back in as your normal administrative user for this part of the tutorial.

Now we must set up the git user to have read/write access to git repositories.

We first make the directory where we plan on storing all git repos. I chose /git.

$ sudo mkdir /git

As you can read in the useradd man pages, every time you create a user, a group with the same name is created unless you explicitely instruct useradd not to do so. So give our git user write access to this directory, we will change the group of /git to git.

$ sudo chgrp -R git /git
$ sudo chmod -R 775 /git

Add your administrative account to the git group so you create repos.

$ sudo usermod -a -G git USERNAME

At this time it's recommended you log out and ssh back in. This is because group changes to the currently logged in account sometimes do not take effect until the account has logged out.

Verify your account is now a part of the git` group by executing

$ groups

This command brings up a list of groups the logged in user account is in.

Now we ensure that anything created within the /git directory will belong to the git group.

$ sudo chmod g+s /git

We now create our testapp repo.

$ cd /git
$ git init --bare --shared testapp.git

On your local computer, grab the rails template. We'll skip the bundle install for now just to test the ssh connection.

(local)$ git clone git://github.com/Hack56/Rails-Template.git
(local)$ mv Rails-Template YourAppName
(local)$ cd YourAppName

Now we create a remote reference to the testapp.git repo we created on the server.

(local)$ git remote add test ssh://git@yourserver.com/git/testapp.git
(local)$ git remote test master

This should push your project to the remote server! If the push is unsuccessful, please carefully re-read the tutorial. Once you can successfully push your project, you're ready to move on to configuring Capistrano.

Step 4. Setting up for Deployment

Capistrano does some behind the scenes work on the tmp and log directories of rails apps so that all deployments share the same log files and pids. Although this idea of Capistrano's is sound, it does require an extra few commands on our part. Thankfully, we can abstract these commands out into a handy bash script. Append the following to your ~/.bashrc

# Create a new app properly structured for capistrano/unicorn
# arg1: app directory name
function new_app(){
    appDir=$1 
    mkdir -p $appDir/releases
    mkdir $appDir/shared
    mkdir $appDir/shared/log
    mkdir $appDir/shared/pids
    chmod -R 775 $appDir
}

Now reload the ~/.bashrc file

$ source ~/.bashrc

Now we create the app directory using our new function.

$ new_app testapp

Now on your local, open the config/deploy.rb file from the root directory of your app. Here are the items you should change:

  • domain: change to your domain
  • user: change to "git"
  • application: change to "testapp"
  • repository: change to "ssh://git@yourserver.com/git/testapp.git"
  • If you're using RVM, uncomment the RVM configuration section

Now open the config/unicorn.rb file. The only change we need to make is to append "/current" to the end of the APP_PATH

################################################################################
# Adjust your APP_PATH here!!!
################################################################################
APP_PATH = "/var/www/testapp/current" # NO trailing slash

Now on your local, run bundle install and the deploy command

(local)$ bundle install
(local)$ bundle exec cap deploy

Verify the success of the deployment by viewing the contents of your testapp directory on the server.

$ ls /var/www/testapp
current  releases  shared

The current directory is the directory we've told nginx to watch at the top of this wiki. Now we need to test unicorn to make sure we can view our deployed site.

$ cd /var/www/testapp/current
$ test_unicorn
Starting unicorn...

If no errors appear, you should be able to view http://www.yourserver.com/pages/show

You've successfully deployed with Capistrano!

Something went wrong with that request. Please try again.