Creating immutable servers with chef and docker.io
Building applications in a docker.io Dockerfile is relatively simple, but sometimes you want to just install the application exactly as you would normally via already built chef cookbooks. Turns out this is actually pretty simple.
The first thing you’ll need to do is build a container with chef-client and berkshelf installed. You can grab the one I’ve built by running docker pull paulczar/chef-solo
or build one youself from a Dockerfile
that looks a little something like the following…
Creating a docker.io container with chef and berkshelf
1 2 3 4 5 6 7 8 9 |
|
you’ll notice I’m using the embedded chef ruby to install the berkshelf gem, this is a handy shortcut to avoid messing around with random ruby versions from your distributions packaging.
run $ docker build -t paulczar/chef-solo .
to build a usable docker container from the above Dockerfile
.
Using chef-solo and berkshelf to build an application in a docker.io container
My example application will install Kibana3
to your docker container. I’ll step through how it works below.
Chef-Solo
To run chef-solo
successfully we require two files. solo.rb
to set up file locations, and `solo.json’ to set up the json / run list required for your application.
1 2 3 4 |
|
1 2 3 4 5 6 7 8 |
|
Berkshelf
To run berkshelf
we need to build a Berksfile which contains a list of all the chef cookbooks required for the applocation. Berkshelf will download these cookbooks to a local directory which will be usable by chef-solo.
1 2 3 4 5 6 7 |
|
You can see some of the cookbooks are being pulled from the opscode repository, whereas others are being pulled directly from github.
Dockerfile
All that’s left now is to create a Dockerfile that will bring it all together.
1 2 3 4 5 6 7 8 9 10 11 |
|
Run $ docker build -t demo/kibana3 .
to build your application.
It will add the local files ( solo.rb
, solo.json
, Berksfile
) to /chef in the server and then call berkshelf to download the cookbooks and chef-solo to install your application. Finally it will give nginx
a directive to run in the foreground so that we don’t have to do any sneaky prcess control to get it to work with the way docker.io
runs processes.
To run the resultant docker.io
container you simply need to run $ docker run -d -p 80 demo/kibana3