Building a Chef server from scratch

As I explained to my non-techie brother-in-law when he asked how I’d spent my weekend: “We have a task that requires a car. The car we have now is serviceable, but it creaks a bit, and if any bits of it fell off or the whole thing caught fire, fixing it would be extremely difficult. What we have now, with this thing I’ve built, is a factory for churning out identical Ferraris by the dozen.”


Apparently this is the first time I’ve ever explained anything about my job in a way that made sense to him. 


Chef is something we’re using more and more for Ops at AMEE. We have our own Chef server, which works OK, but was put together in a rather ad-hoc way – it’s basically a big pile of Technical Debt. This was starting to bother me, so I sat down on Friday night to see if I could come up with a better solution.

OpsCode have this excellent guide to installing your own Chef server, which serves as a fine starting point, but I took a diversion into RVM and Ruby 1.9.2, and also installed a newer version of RabbitMQ.

Chef has all sorts of dependencies on all sorts of technologies. Of particular interest are:

  • Java – Oracle, ever the friend of Free Software, recently made it more difficult to install Java on Ubuntu. On Friday night, however, I stumbled upon this witchcraft which apparently downloads the sources and prepares deb packages locally, which we can then install. I didn’t look too deeply into this (and Heaven knows what Oracle will make of it), but it works and it’s mind-blowing. Oh, and Java is required because Solr.
  • Ruby – Chef runs fine on Ruby 1.8, but I’d much rather use 1.9.2 these days. This is currently not in the Ubuntu apt repos (at least on Lucid, our current release of choice), so we turn to RVM.

So I followed the instructions in the OpsCode howto, and by about 02:00 on Saturday morning I had a huge number of VirtualBox snapshots, a page of notes, and a working Chef server!

I transcribed the notes into a clunky first-draft script, then I set about making all of this stuff start at boot-time. The Chef gems come with upstart scripts to kick things off, but these want to run everything as root, and we’d rather use the ‘chef’ user. So we attack these scripts with a horrendous sed monster until they look like this:

# chef-server - Chef Server
# Chef Server provides the Chef API server

description "Chef Server API"

start on filesystem
stop on runlevel [!2345]

respawn limit 5 30

pre-start script
  su - chef -c "which chef-server" || { stop; exit 0; }
end script

  su - chef -c "chef-server -e production -p 4000 -L /var/log/chef/server.log"
end script

and that’s all there is to it.

So I now had a working script, but what I really wanted was to make it idempotent. VirtualBox snapshots are great for this:

A whole lot of VirtualBox snapshots

So after a  long afternoon of testing, breaking stuff, and reverting to previous snapshots, I had produced this. To install it from scratch on a pristine Ubuntu Lucid node, you can do this:

sudo apt-get install -y curl ; bash <(curl -s 

It will probably work on other Debian-ish distros, and it might even play nice on a box that already has some of this installed, but be very careful if you already any Solr data you care about: chef-solr-installer will nuke it all.

Hope somebody finds this useful.

Back to AMEE Blog