Capistrano series - configuring Capistrano #2

So now Capistrano has created the base structure for the application deployment, we need to look at actually deploying it.

Let's look at some of the settings we need for this and then deploy the application for the first time.


deploy.rb

So far, the deploy.rb file looks like this:

set :application, "domain.com"
set :user, "demo"
set :repository,  "svn+project1ssh://123.45.67.890/home/demo/repository/project1"

# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}"

set :port, 30000

set :deploy_to, "/home/demo/public_html/#{application}"

# If you aren't using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion

role :app, application
role :web, application
role :db, application , :primary => true

Let's start by looking at how the deployment will be conducted and what we need to define for that deployment.

Subversion

We've already got subversion installed and configured on our local machine but what about the Slice?

On a default deployment, Capistrano will execute commands on the Slice and checks out the latest application version from the repository. However, we haven't setup the Slice to access the repository.

We also don't need to.

One of the problems with setting up the Slice to access the repository is that a private key will need to be placed on the Slice (if you want to have passwordless access).

This can be a security issue and the way I prefer to do it is to only allow the workstation to access the subversion repository.

This means that during a Capistrano deployment, the latest version will be checked out from the remote repository (to the workstation), compressed, sent via SSH to the Slice and then uncompressed.

This does mean it takes a few seconds longer to deploy an update but the increased security more than makes up for the slight delay.

Setting up Capistrano to use this deployment strategy is as simple as adding this to the deploy.rb file:

set :deploy_via, :copy

Mongrel user

An odd thing with the Capistrano script is that you will need to explicitly set the user that will start the mongrel instances.

If you don't set it, then the script will fail.

In this example, we'll use the same user as previously defined. You can, however, use another username if that fits better with your needs:

set :runner, user

deploy.rb

As we've added a couple of settings, let's have a reminder of what the deploy.rb file should look like:

set :application, "domain.com"
set :user, "demo"
set :repository,  "svn+project1ssh://123.45.67.890/home/demo/repository/project1"

# If you aren't deploying to /u/apps/#{application} on the target
# servers (which is the default), you can specify the actual location
# via the :deploy_to variable:
# set :deploy_to, "/var/www/#{application}"

set :port, 30000

set :deploy_to, "/home/demo/public_html/#{application}"

# If you aren't using Subversion to manage your source code, specify
# your SCM below:
# set :scm, :subversion

role :app, application
role :web, application
role :db, application , :primary => true

set :deploy_via, :copy

set :runner, user

Initial deployment

So far, we have nearly everything setup to deploy our application.

However, one final thing we need to sort out is to let it know how to start the mongrels on the initial deployment.

This is done via a 'spin' file in the script directory.

We can create that now (remember we are still on the workstation, not the Slice):

touch script/spin

This file will contain the commands that Capistrano will use to control the mongrels.

As the file needs to be executable, we can ensure it has the correct permissions by setting the property in subversion

svn propset svn:executable on script/spin

So what do we put in the file?

At the moment, we only need one line that relates to our mongrel usage:

/home/demo/public_html/domain.com/current/script/process/spawner -p 8000 -i 2 -e production

As you can see, this sets the path to the 'spawner' script (which has been created for us), the port to start the mongrels on (8000 in this case), the number of mongrels (2 in this example) and the Rails environment to use.

Commit

We've made a few changes that need to be added to the repository.

Make sure you 'add' the files to subversion first - you can check what files need adding like this:

svn status

If any need adding (such as the script/spin file) then add them like so:

svn add script/spin

Lastly commit the changes to the subversion respository:

svn commit -m "added script/spin"

Nearly there

Again, a lot is happening here but we are very close to deploying and serving our application.

We're going to deploy the application for the first time now but I give a word of warning:

The application will not show for the domain

Eek!

Why not?

Well, the simple fact is that we haven't created a vhost for the domain yet (sure, we created a test vhost when we installed Nginx but we don't have one for the soon-to-be deployed application).

However, there is nothing stopping us from deploying the application for the first time. That only leaves us with creating a vhost for the application which, if you are super keen, can be done by referring to the original Nginx vhost article (the next article will go through the exact settings that we need though).

Initial Deployment

Let's get on with it.

To deploy the application for the first time needs a simple:

cap deploy:cold

You will see quite a lot of information scroll by in your terminal.

Once done (and it should end with a section entitled " Starting mongrel dispatchers") have a look at what Capistrano actually did.

It did everything we expected in that it checked out the latest code from subversion and compressed it to a temporary file, uploaded it, uncompressed it and then went through a quite complicated procedure of copying the code and creating symlinks, etc.

Lastly, as already mentioned, it started the two mongrel instances as defined in the script/spin file.

Nice.

Summary

Although possibly a little frustrating that we have to configure a vhost for the application, remember that Capistrano is not designed (by default) to install and configure the web servers for us.

Capistrano allows us to use an existing setup to deploy and serve our application with a single command.

The next article will create and define a vhost file so we can then view and interact with the web application.

PickledOnion

Article Comments:

patrick commented Tue Jan 22 17:39:28 UTC 2008 ago:

The SFTP upload was hanging for me. Adding the following line to my deploy.rb seemed fix the problem:

set :synchronous_connect, true

more info here: http://swik.net/Releases+Capistrano

Thanks again for these excellent articles.

PickledOnion commented Tue Jan 22 17:44:10 UTC 2008 ago:

Patrick,

Thanks for the heads-up and link.

I didn't get that issue. I wonder if it is related to the OS of your workstation?

Anyway, thanks again. I am sure that will save a few people some frustration!

PickledOnion

Mike commented Fri Jan 25 17:14:24 UTC 2008 ago:

Deploying from a Windows box, I had one snag. Make sure the spin script is saved in UNIX file format and not DOS. The latter will cause a parsing error when the mongrels try to start.

Great article.

PickledOnion commented Fri Jan 25 17:16:42 UTC 2008 ago:

Mike,

Thanks for the note, I hope that helps other's using Windows as the workstation.

PickledOnion

Mike commented Fri Jan 25 17:22:56 UTC 2008 ago:

One other comment for someone using Windows. The set :deploy_via, :copy relies on having tar installed. The cygwin version of tar works. The gnuwin32 version does not work because it doesn't implement the fork functionality.

Stagiros commented Sun Jan 27 12:50:47 UTC 2008 ago:

I had the same problem with Patrick. I am running the exact same OS configuration on my machine and the slice (aka Ubuntu 7.10 Gutsy). Once I added the line "set :synchronous_connect, true" as Patrick suggested, everything worked correctly. If more people are getting the same behaviour from the system, I think that somebody should look seriously into that problem.

Otherwise a superb series of tutorials. Thank you!

Virginian commented Sat Feb 02 00:09:14 UTC 2008 ago:

I had to manually run rake RAILS_ENV=production globalize:setup to get it to work.

How can i put this in my deploy.rb file?

Todd commented Thu Mar 13 13:39:49 UTC 2008 ago:

what i have mutiple enviroments?

1 server is a svn server, 1 server is a 'staging' server (for beta deployments) and there's 1 more final server for production deployments...

PJ commented Tue Mar 18 11:17:59 UTC 2008 ago:

For Windows users, how do you save the script/spin file in Unix format?

Kyle commented Thu Mar 20 22:02:15 UTC 2008 ago:

Amen to the 'set :synchronous_connect, true' fix. Same thing here - Ubuntu 7.10 on workstation and slice. Maybe this should go into the main article text as a precaution.

Brian commented Tue Mar 25 18:40:56 UTC 2008 ago:

Hey I just wanted to add that the "set :deploy_via, :copy" was taking too long for me. I have a relatively big project and the upload time is annoying.

I tried taking out the "set :deploy_via, :copy" and I got the following error:

** [err] svn: Undefined tunnel scheme 'project1ssh'

I found a way to get around it but not sure if this is right:

It was looking for "svn+project1ssh" tunnel on the slice as well.

Not only does the local machine need to be able to tunnel into the slice, the slice needs to be able to tunnel into itself (this seems really bizarre to me, but its the only way I got it to work).

We already added it to the local machine, but you need to add it to the slice as well. Add:

project1ssh = /usr/bin/ssh -p 30000 -l admin

In the tunnels section of: sudo nano ~/.subversion/config

Then you also need to make a private/public key pair so the command works on the server.

ssh-keygen -t rsa ... Go through the prompts and write down the pass phrase that you specify. cat ~/.ssh/idrsa.pub >> ~/.ssh/authorizedkeys

then try ssh'ing from the slice into the slice once to see if it works without passwords.

If anyone knows a better way please post it this seems very hackish.

michael commented Wed May 07 16:30:25 UTC 2008 ago:

How do you set the permissions on spin if you are using git and not svn?

Daniel commented Sun Aug 24 04:20:03 UTC 2008 ago:

Is anybody else having trouble with permissions when trying to cap deploy:cold?

I can run the cap deploy:setup ok, but when I run cap deploy:cold, cap can't create any of the directories, and I get a whole long list of failed attempts, for example:

* [err :: (my ip address)] tar: 20080824034850: Cannot mkdir: Permission denied

Maybe I messed something up earlier on in this process?

Thanks for any pointers. Excellent, excellent series of articles.

Braxo commented Fri Aug 29 18:46:24 UTC 2008 ago:

@Daniel

I am also having the same issues. Capistrano is now at version 2.5.0 where this tutorial was written when it was 2.1.0. I wonder if that is causing us the grief?

Tom commented Mon Sep 01 07:18:31 UTC 2008 ago:

I just configured this with 2.5.0.

In order it to work completely, you need to add trunk at the end of set :repository, "svn+project1ssh://123.45.67.890/home/demo/repository/project1"

so it'll be set :repository, "svn+project1ssh://123.45.67.890/home/demo/repository/project1/trunk"

Also.. Braxo and Daniel, you need to set the permissions for demo or whatever account. Refer to Pickel's guide on Permissions for Vhosts, I believe it is under apache.

You need to be able to write to the folder. For instance, the reason you are getting is this is because if you were to log in with demo, and try mkdir test, in the folder capi is suppose to deploy to, it won't work. You need proper permissions.

Pickel should update the article to reflect that.

Firefly commented Wed Sep 03 07:41:56 UTC 2008 ago:

Daniel, Braxo, I also had problem with permission.

This is what I did.

  1. Login to slice
  2. sudo chown myuser /home/www/project_path -R

This will give the user ownership to directory.

Hope it helps.

VJ commented Wed Sep 03 14:40:57 UTC 2008 ago:

@brian,

I had the same issue like yours. I didn't want to use deploy_via copy.

Like you, I had to add private/public key pair, but i didn't have to modify subversion config with "sudo nano ~/.subversion/config". Which is one step less.

At first i also encountered error, but I tried to do check out manually at slice. The system prompted to authorized the computer, afterwards, I can already do the cap deploy:cold.

svn checkout -q -r12 svn+ssh://server.example.com/home/repo/project1 /home/www/example.com/releases/20080903142954

@all, I had problem with the syntax svn+project1ssh, so I only use svn+ssh. Works well for me.

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)