Blogs

Forum

Guide

Useful Links

Meta

Subscribe

F. How To Deploy your first rails app to Dreamhost using Capistrano in Windows

Credit: This tutorial owes its existence to the wonderful Dreamhost/Capistrano wiki article.

The primary thrust of this tutorial will be to help you deploy your first rails app using Capistrano from a Windows environment. Although I’m specifically addressing deploying to Dreamhost, you may be able to modify things to work with your own host. Rails apps on Dreamhost usually run on Fast-CGI, so this tutorial covers that as well. You may need to find more information in order to get your app up and running on Lighttpd or Mongrel.

UPDATE: Thanks to Chris_M from the comments for letting me in on another preperatory step. Before using Capistrano, please download the subversion command line stuff from here.

You’re also going to want to be doing this using the latest edge version of Rails. If you’re reading this after Rails 1.2 is available, you may not need edge.

First, let’s install capistrano:

gem install capistrano

The next thing you’ll need to do is to set up a simple rails app. Create a rails app:

rails CapTest

Now, in order to play with Capistrano to see if your deployment works, our app will just display an index.rhtml page. First let’s create a controller:

script/generate controller whatever

Now create an index.rthml file under app/views/whatever. Let’s just make it look like this:

<html>

<head><title>CAPTest</title></head>

<body>

<p>It is now <%= Time.now %>. <br /></p>

</body>

</html>

In this way, we can make sure that rails is running. Once we get the app up to Dreamhost and running, we’ll add another couple of lines to this simple file as we deploy a few times to see the Capistrano magic.

We’re almost done with setup. Now, let’s change our route so that when we visit our site we’ll go straight to our test page. Open config/routes.rb and make sure it has a line like this:

map.connect '', :controller => "whatever"

In order to get the whatever controller’s index page to work like this, though, you need to delete the index.rhtml found in your app’s public folder.

Now, let’s test the app with a WEBrick/Mongrel (depending on your version of Rails) server.

ruby script/server

Just go to http://localhost:3000/ in your browser and you should see our test page showing the current time. Now, over to Dreamhost.

Our next step will be to set up a Subversion repository on Dreamhost and get our CapTest application into it. This is a very important step; we won’t be able to utilize Capistrano without it. So, go look at my handy-dandy Windows+Subversion+Tortoise+Dreamhost tutorial and come back when you get stuff set up.

Ok, now you should have a CapTest rails app that’s synched up with a subversion repository up at Dreamhost. Take a look at your app in explorer:

All of your folders should have green check marks like mine. If any don’t, right click on the topmost folder and choose SVN Commit… That will allow you to resynch whatever’s out of synch.

Now let’s create a subdomain to stick all this stuff up at Dreamhost. Just go into Manage Domains and create a new subdomain (something like captest.yourdomainname.com) and make sure that the FastCGI open is checked and be sure to append /current/public, instead of the default directory suggested. IMPORTANT: After DNS allows access to your newapp.yourdomain.com/current/public folder, you must manually delete the ”/current/public” that DH creates. This is so that later in this tutuorial, ‘cap deploy’ can create a symlink to /current, allowing capistrano and subversion to live happily together. Thanks to topfunky.com for the troubleshooting tip!

The next step is to modify your app according to the instructions under the config/environment section of the Capistrano/Dreamhost tutorial. When you deploy your app it needs to be in Production mode already. One strategy for managing your development work vs the production files is to synch up the important production files first and then modify them for development work – just remember to not synch the development versions! There’s probably a better way to handle this that I haven’t thought of. If you know a better strategy, please leave a comment below.

Now can we start playing with Capistrano. First, let’s Capistranoize our application. Open a command window at the toplevel of your app and type:

cap --apply-to .

This will create two files in your app. A config/deploy.rb and a lib/tasks/capistrano.rake. Use tortoise to synch them up with your repository.

The next step is to modify your deploy.rb file. This file contains the bits of information that are specific to your app and your host. Getting all of this to work properly has been difficult for me, I think primarily because I’m deploying from Windows. Let’s look at my deploy.rb file. You’ll need to change a few things to make it particular to your domain and sub-domain. The comments up to where the Tasks start should be self-explanatory. This is all standard capistrano deployment for Dreamhost accounts. We’ll discuss the tasks below.

# the name of your subversion application

set :application, "captest"

# use exactly what you see on the Dreamhost subversion control panel

set :repository, "http://www.icuo.us/captest"

# These three should be set to your subdomain name you set up

# on Dreamhost. The explanation of all of these is beyond

# the scope of this tutorial.

role :web, "cap.icuo.us"

role :app, "cap.icuo.us"

role :db, "cap.icuo.us", :primary => true

# This is the directory you created when you setup

# your subdomain on Dreamhost. Don't include the

# public/current part...

set :deploy_to, "/home/tdonaghe/cap.icuo.us"

# Dreamhost doesn't allow you to use sudo.

set :use_sudo, false

# Do this so subversion doesn't create a .svn in your

# world-accessible directory.

set :checkout, "export"

# Make sure to set this to your DreamHost user name that

# you use when you connect to ssh

set :user, "your_user_name"

# # TASKS # desc "Tasks to execute after code update"

task :after_update_code, :roles => [:app, :db, :web] do

# fix permissions

run "chmod +x #{release_path}/script/process/reaper"

run "chmod +x #{release_path}/script/process/spawner"

run "chmod 755 #{release_path}/public/dispatch.*"

end

desc "Restarting after deployment"

task :after_deploy, :roles => [:app, :db, :web] do

run "touch /home/tdonaghe/cap.icuo.us/current/public/dispatch.fcgi"

end

desc "Restarting after rollback"

task :after_rollback, :roles => [:app, :db, :web] do

run "touch /home/tdonaghe/cap.icuo.us/current/public/dispatch.fcgi"

end

During my initial experimentations with Capistrano, I would have a lot of failures when deploying. These failures all stemmed around the executable permissions of the reaper and spawner scripts. I think this is a problem because when you build your rails app in Windows, you don’t have a good way to set the unix style permissions on these files. The first task takes care of this.

This task is called :after_update_code. Capistrano runs various tasks while it’s deploying your code. For each of these tasks you can create custom tasks to run either before or after they run. Just create a new task with the prefix of either “before” or “after” and the task name you’d like to add behavior to. In the :after_update_code case we’re going to run some unix commands after all of the code has been deployed onto the server.

When Capistrano deploys your app, it creates a directory structure something like this:

To get this started, let’s save this deploy.rb file as is and commit it to your subversion repository. Now, in a command line, run “cap setup” in a command window from the top level of your rails app. This will create the necessary starting structure up on the server for your app to be deployed to.

The important thing to notice in the :after_update_code is that your code goes into a 2006XXXX directory under the subdomain/releases directory. The location of this directory is stored in the release_path variable, and that’s what’s used in the after_update_code task. After the deploy step, Capistrano sets a symlink to point our cap.icuo.us/current/public directory to whatever the most recent release/public directory is. After the code update that’s not set yet, so we have to refer to the most recent release path as you see in the :after_update_code task.

So, we set executable permissions on the two process scripts as well as chmod’ing public/dispatch.* to 755 – something else I don’t know how to do in Windows.

Finally, there’s one more step for the deploy process – yet another stepped I figured out through trial and error. At the end of the deploy process you can see the reaper script attempt to restart the server by calling dispatch.fcgi. As you can see, this step fails:

If we let the deployment stop at this point, our web app won’t start and we’ll get a Rails error. I found that if I ssh’d into Dreamhost and opened dispatch.fcgi in nano, made a trivial edit (I think just stick a space after a comment) and then save that I could refresh the webpage and the app would work. I couldn’t though, figure out how to script in calling nano into a task. I finally remembered reading that you could sometimes “touch dispatch.fcgi” to get it to run sometimes. So, I created the :after_deploy task to do exactly that.

With the :after_update_code and :after_deploy tasks in place, you should be able to save your deploy.rb file, commit it to your subversion repository, and then run “cap deploy” in a command window from the top level directory of your rails app. If everything works ok you’ll soon be prompted to enter your ssh password. Then more scripts will run, and hopefully the process will end with no errors.

If you get errors at this point, please leave me a comment and I’ll try to help you out, and hopefully more knowledgeable folks will help as well. If you’re deploying this really simple rails app from Windows to Dreamhost we ought to be able to figure something out. The first thing I’d check is your dispatch.fcgi file. Open it in a text editor like Notepad++ and look at the end-of-line characters. If you have anything other than just LineFeeds (LF) at the end of each line, you’ll need to convert the file to Unix format, commit the file to your repository and try again.

Now try to navigate to your website. If it fails, see the previous paragraph. Let’s be optimistic and assume that everything works ok. Now let’s witness the power of Capistrano! Go into your app/views/whatever folder and edit your index.rhtml file. Just add a line to the end of it. Now save and commit the file to subversion. Run “cap deploy” again. Refresh your webpage. Voila! You should see your new line!

Now, let’s try a different Capistrano method. In your deploy.rb file you should also have a task that runs after a rollback, :after_rollback. This guy just “touches” your dispatch.fcgi file again. This time we can’t use #{release_path} to get to the public folder because by this time, that’s gone. So, we just use the absolute path of your newly rolled back app. Let’s try it out. Do “cap rollback” from the command window. Refresh your browser. You should see the original page we saw after doing the first deploy. Nifty, huh? Now we can just do a “cap deploy” to see our updated page.

That’s deploying and rollback changes to a rails app in a nutshell. There’s about a bajillion more things you can do with Capistrano like deploying apps to multiple servers, etc. There’s tons of info you can find out in GoogleLand. Hopefully this tutorial has helped you get your first pretty trivial rails app deployed out to Dreamhost. The principles should remain the same for more and more complicated websites. So, get to capping and have fun!

Please take a look at the wiki article mentioned at the top of this tutorial for more information and some helpful hints. It’s also very worthwhile to take a look at the Capistrano book up at RubyOnRails.org.

Advertisements

Like this:

LikeLoading...

2 Responses to “F. How To Deploy your first rails app to Dreamhost using Capistrano in Windows”

– The multi-line blocks are rendering to a single line, off the right edge of the screen (on FireFox 2.0 on Windows).

- The after_deploy and after_rollback methods contain hard-coded paths that are unnecessary--I changed them to "run touch #{deploy_to}/current/public/dispatch.fcgi", which seemed to work well.

- The error you highlight, "couldn't find any processes matching...dispatch.fcgi", isn't necessarily an error if your app isn't running yet. I don't recall where I read that, but it does appear to be innocuous (always?).