Keep Chef out of your Docker containers
Configuration Management tools can be of good use to provision your Docker containers. But you don’t want these tools to end up in your Docker images. Using Data Volume Containers and Docker Compose, we can do this and still have a slim image. Here is how you can do it with Chef.
TL;DR
Prepare a docker-compose.yml
file with 3 services: chef
, chefdata
and app
.
chef
exposes/opt/chef
as a volumechefdata
contains the Chef setup (client.rb
, json, cookbooks) exposed on/tmp/chef
app
uses the volumes from the former and runs Chef to provision itself- commit
app
container as an image. - Use your application image! :-)
Get an image with Chef installed
I went over to the Docker Hub to search for an image with Chef preinstalled, but exposed as
a volume. The last part of my request was usually not fulfilled so I created an image
myself: releasequeue/chef-client
Since using floating versions like latest
is not proper release management, I also tag my
images with the Chef version installed.
Prepare your application Chef setup
Create a folder containing your Berksfile
for your application or service:
Retrieve the cookbook and its dependencies:
Cooking your cookbooks container
To run Chef succesfully, we need three parts:
- a config file
- a JSON data file
- the set of cookbooks
We retrieved the cookbook in the previous step. In the chef folder, add a Chef configuration file and a JSON data file to complete the setup:
With all these parts in place, we can create another data volume container containing all of the above. Put a Dockerfile in the chef folder with these contents:
Provisioning the application container
Now we are ready to create our application container. Add your application Dockerfile
to the top-level project folder:
To get the 3 containers running together, we use docker compose
with this input file:
and run docker-compose up
. You should see all three containers be created and Chef
running from the last one. Once it has done, the containers all stop gracefully.
Baking the application image
We have to find the container id of our application container after running docker compose
:
Let’s commit our application container to an image and tag it:
Run your application
We have our provisioned image, so let’s start our application:
Since the volumes of Chef or the cookbooks are no longer there, this image is free of any provisioning tools and much smaller as a result.
Happy container cooking!