Copyright © 2011-2012
Matthew C. Smith

Deploying With Vlad The Deployer On Ubuntu


Sample Blog Post

When looking for Rails deployment solution there is probably one gem that immediately pops into your head. Capistano.

But there is another option. Vlad the Deployer.

Vlad will have some familiarity to Capistrano users, but the implementation is starkly different, in a simpler way. Vlad uses another gem under the hood called rake-remote_task. Quoting the documentation, rake-remote_task is the "sexy brainchild" behind Vlad. Rake-remote_task uses Rake, if the name didn't give it away. Simply use remote_task instead of task, and you get access to the usual suspects: run, sudo, put, get, etc. This makes it easy for anyone, even slightly familiar with Rake and/or Capistrano, to use Vlad.

Rake-remote_task relies upon standard operating system tools in its implementation: ssh, sudo, rsync, etc. You have access to set any flag you wish for each tool. If you know the basics of unix, this leaves no surprises. This means in theory, no new concepts. Nice.

Vlad comes squeaky clean. Sure, there are a few packaged defaults, i.e. apache, subversion, passenger, and rails, but they are easy to exchange for your own personal stack. In my case: nginx, git, rails, and unicorn. To exchange, just bundle in the appropriate gems and load them (or create your own), or simply require your own recipes.

Ok, enough of a review, on to the substance of the post: using Vlad and deploying to an Ubuntu server.

As I said, in theory there is nothing new to learn. Well evidently, I needed to brush up on my unix skills. Everything worked fine for me deploying form OSX to Ubuntu, until I needed to use sudo to start/stop nginx.

ruby-1.9.2-p136 ~/work/test[master]% rake vlad:web:quit
(in /Users/matt/work/test)
Pseudo-terminal will not be allocated because stdin is not a terminal.
sudo: no tty present and no askpass program specified
rake aborted!
execution failed with status 1: ssh deploy@xxx.xxx.xxx.xxx sudo -p Password: nginx -s quit

(See full trace by running task with --trace)

I had known that Ubuntu allocates a pty instead of a tty, so that made some since, but the password prompt wasn't being sent back down. Hmmm, what do do. A google search yielded a few hits by excluding applications from requiring a password in the sudoers file. This did not seem like the right idea to me. Since I am in Seattle and often frequent the meeting place of seattle.rb, I asked Ryan Davis. In his infinite wisdom (and with the input of a couple others) we came up with a solution.

In the end, the answer was simple (as almost all perplexing problems are) and staring me right in the face. (Again, as it usually is.)

SUDO(8)                                     MAINTENANCE COMMANDS                                     SUDO(8)

NAME
   sudo - execute a command as another user

OPTIONS
   -S          The -S (stdin) option causes sudo to read the password from the standard input instead of
               the terminal device.

So I added this to my deploy.rb:

set :sudo_flags, sudo_flags << '-S'

Then on the Ubuntu server, add a simple askpass program. I put mine in ~/bin/askpass.

#!/usr/bin/env ruby
puts gets.chomp!

Then because you cannot pass option -S and -A, you must define an environment variable. Check 'man sudo' for more details. At the top of my .bashrc file I added this:

if [ -z "$PS1" ]; then
  export SUDO_ASKPASS=$HOME/bin/askpass
fi

I did it at the top of the file, because Ubuntu puts the following as the first directive in the file:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Then magically everything works.

ruby-1.9.2-p136 ~/work/test[master]% rake vlad:web:quit
(in /Users/matt/work/test)
Password: sudo password: 

I hope this saves you some time or allows you to run programs requiring sudo privileges, without compromising security! All in all, even though I ran into this snafu, I still say Vlad is much simpler to use than Capistrano. And in reality, this was a unix issue, or rather a linux distribution issue, not a Vlad issue. It was so much simpler than getting started with Capistrano.

Again, thanks to Ryan Davis and all involved with Vlad.

Enjoy.

→ Written by Matt Smith on February 19, 2011 in Deployment, Ruby

blog comments powered by Disqus