Deploying Sinatra with Vlad

So you've just written a nice new Sinatra application, and you want to get it running on your web server. How hard can it be? Well with Vlad the Deployer, it's actually rather easy.

Creating a sample application

Let's start by making ourselves a test app:

$ mkdir hello
$ cd hello
$ touch app.rb

Open app.rb in your editor and put this code in it:

require "rubygems"
require "sinatra"

get "/" do
  "Hello!"
end

We can check that the app works locally by running it...

$ ruby app.rb

...and then opening http://localhost:4567 in a web browser.

We need to create a public directory too, as Vlad assumes that we have a public directory for our static assets. I'm also going to make an empty CSS file so that the directory doesn't get ignored by Git:

$ mkdir public
$ touch public/master.css

We'll deploy our application from version control. I'm using Git, but you can use any system that Vlad supports; just check your files into a repository that will be accessible from your web server.

Configuring Vlad

Okay, we're ready for Vlad. It's a Ruby gem, so it's very easy to install:

$ sudo gem install vlad
Successfully installed vlad-1.2.0
1 gem installed
Installing ri documentation for vlad-1.2.0...
Installing RDoc documentation for vlad-1.2.0...

There's no need to install Vlad on your server, just your workstation.

You access Vlad's functionality through Rake tasks. This means that we need a Rakefile which loads the Vlad code. Create Rakefile in the same directory as app.rb, then add the following code to it:

begin
  require "vlad"
  Vlad.load(:app => nil, :scm => "git", :web => nil)
rescue LoadError
  # do nothing
end

Note that we've told Vlad that we intend to use Git (subversion is the default).

These instructions were tested using Vlad 1.2.0. They still work if you're using Vlad 2.x, but be aware that support for git was moved into a separate gem in Vlad 2.x, so you'll also want to run gem install vlad-git. If you don't, vlad will later complain with "Please specify the server domain via the :domain variable".

We've set :app to nil as Vlad assumes that we'll run our application with Mongrel. I'm not going to use Mongrel here, so we don't want Vlad to load its Mongrel recipes.

If you run rake -T now you should see a bunch of vlad tasks that are available to you. You can't run them yet; you need to configure Vlad with a config/deploy.rb file:

$ mkdir config
$ touch config/deploy.rb

Open deploy.rb in your editor and set the following variables:

set :application, "hello"
set :repository, "ssh://your.git.server/path/to/project/hello.git"
set :domain, "your.web.server"
set :deploy_to, "/var/apps/#{application}"

Make sure that :repository correctly references your source control system, and that :domain is set to the hostname of your server.

I won't be able to create any directories under the /var/apps directory (I'm going to run vlad using my own username in this example), so I need to login to my server and make sure that I can create files in the hello directory:

$ ssh your.web.server
$ sudo mkdir -p /var/apps/hello
$ sudo chown yourusername /var/apps/hello

Now you can try running Vlad, to create all the directories necessary to serve your project. Back on your workstation, type:

$ rake vlad:setup

You should find that some directories have been created within /var/apps/hello on your server.

Let's trying deploying some code:

$ rake vlad:update
(in /Users/graham/data/effectif/projects/hello)
Initialized empty Git repository in /var/apps/hello/scm/repo/.git/
Switched to a new branch "deployed-HEAD"

You should now find that if you ssh into your server that you can run the application:

$ ssh your.web.server
$ cd /var/apps/hello/current
$ ruby app.rb

Try making a change to your source, committing it to your repository, then run vlad:update again. Your code will be updated. If you restart Sinatra in the new directory you'll see your changes in the browser.

If you're following along with these commands, be careful that you're running app.rb in the freshly deployed directory. current is a symlink to a specific release directory, so you'll need to leave the directory and return to it to see the new source code (i.e. symlinks don't get updated under your shell's feet). This should do it:

$ cd ~ && cd -
$ ruby app.rb

You may now be wondering how to get Thin running automatically, and how to re-start it when you run vlad:update. That should be the subject of my next blog post (you can subscribe if you need it).

Deploying from a Git branch

If you want to deploy from a specific Git branch (master is the default) you can set the :revision variable in deploy.rb:

set :revision, "origin/mybranch"

Deploying as a different user

It's not a great idea to deploy and run applications as your own login name (it's better practice to run web applications as users that don't have many privileges). I've not really addressed users in this article in order to focus on the basics of Vlad, but if you're interested you can deploy as a different user with these settings in deploy.rb:

set :user, "deploy"
set :domain, "#{user}@domain.com"