Building Munki with Chef in Docker

I’ve previously written about building Munki in Docker, and then going a step further and using Puppet’s SSL client certificates for Munki in Docker. That method allowed us to set up a Munki server in a Docker container that used Puppet’s SSL certificates to offer a secure Munki connection with Puppet clients.

Continuing on the theme of testing out Chef for DevOps, I’d like to try a similar workflow. See my previous blog post about setting up SSL client certificates with Chef.

Once we have a Chef server configured similarly to the aforementioned blogpost, let’s build a Munki Docker container that utilizes Chef.

Chef already has existing containers to build on, but we’re not going to use those. Rather than rebuild an nginx server on top of a container already containing Chef, I’m instead going to add Chef to my existing Munki container.

Start with the basic Munki container:


FROM nginx
RUN mkdir -p /munki_repo
Run mkdir -p /etc/nginx/sites-enabled/
ADD nginx.conf /etc/nginx/nginx.conf
ADD munki-repo.conf /etc/nginx/sites-enabled/
VOLUME /munki_repo
EXPOSE 80

All that really needs to happen here is to make another Dockerfile that just adds Chef to this. We’re going to steal the method for this from Chef’s existing containers. The new Dockerfile:


FROM nmcspadden/munki
RUN apt-get -yqq update
RUN apt-get -yqq install curl lsb-release
RUN curl -L https://getchef.com/chef/install.sh | bash -s — -v 11.16.2 -P container
ADD client.rb /etc/chef/client.rb
ADD validation.pem /etc/chef/validation.pem

The upside to doing it this way: this is how Opscode builds their own Chef containers, so we’re doing exactly what they want and expect. The downside is that we have to install curl just to use it once, during build – and never again. This violates the principles of a small single-purpose Docker container, as I outlined in a previous blog post here. That being said, it’s easier just to do it the way Chef expects and just go with it.

Note the two files that have be to added – client.rb and validation.pem.

Client.rb is straightforward, it’s just the client configuration file for this container, telling it how to access Chef:


log_location STDOUT
chef_server_url "https://chef.sacredsf.org:443/organizations/ssh"
validation_client_name "ssh-validator"
ssl_verify_mode :verify_peer

The validation.pem is called the Chef validator. It’s the private key that gets created when you create an organization (note that the docs refer to it as file.key instead of file.pem, but it’s the same file). This file needs to be added to all clients before they can register with the Chef server, and this Munki container is no exception. You’ll need to copy your organization’s private key file from the Chef server or workstation to the Docker host to build this image.

As you can see in the client.rb file, I’m specifying the Chef server URL, the name of the validator (based on the organization I created, mentioned above), and enforcing SSL verification – which requires a trusted SSL certificate for your Chef server (meaning you can’t use the self-signed default certificate provided by the Chef server on first run).

With all the pieces in place, it’s time to build the container:
docker build -t "nmcspadden/munki-chef" .

Next post is where we run it!

Leave a comment