Running Munki in Docker

The base of this article was taken from my README.

In the previous post, I built a container that serves static files at http://munki/repo using Nginx.

Now that we have build the Docker image, let’s put it to use.

Data Containers

We’re going to hook up the Munki image to a data-only container. Data-only containers are a way of keeping data portable and not tying it to specific locations or configurations on the host OS. This data-only container serves one purpose: to store the contents of the Munki repo and share it with other containers. The benefit to doing this is that we can raise and destroy as many Munki server containers as we want without losing any data (such as the contents of the Munki repo).

Creating a Data Container:

Create a data-only container to host the Munki repo:
docker run -d --name munki-data --entrypoint /bin/echo nmcspadden/munki Data-only container for munki

Let’s deconstruct this command into individual pieces:
docker run
That’s the base command for running a docker image.

This runs the container in “detached” or “daemon” mode, where it runs in the background until we stop it (or it halts execution for some reason).

--name munki-data
Normally, when you run a Docker container, it picks a random human-readable name. Otherwise, you can refer to a container by its numerical ID number. By using --name, we can provide a meaningful name that we can refer to later. This container’s name is “munki-data”.

--entrypoint /bin/echo
The entrypoint for a Docker container is a command that executes upon running of the container. This is the technique Docker containers use to run in the background – by auto-executing a command. More information about entrypoints can be found here and here. This particular entrypoint is /bin/echo – meaning it will simply echo something out and then halt the Docker image.

The name of the image I’m running.

Data-only container for munki
Although it’s a bit hard to see from syntax, this phrase is actually the argument to /bin/echo. The ultimate goal of this container is to execute this command on startup:
/bin/echo Data-only container for munki

For more info on data containers read Tom Offermann‘s blog post and the official documentation.

Note that after you run this image, the Docker container is stopped – check docker ps vs. docker ps -a. That’s okay – the data-only container doesn’t need to be running to contain data. It doesn’t use any system resources (except for file system space), and can be accessed for data by other containers while not running.

Run the Munki container:

We now have a data-container to store our data in, let’s run the Munki container and start the Nginx webserver.

docker run -d --name munki --volumes-from munki-data -p 80:80 -h munki nmcspadden/munki

Let’s deconstruct the new pieces of this command:

--volumes-from munki-data
The --volumes-from argument tells the Docker image to use any exposed volumes from another container – specifically, use the shared volume /munki_repo from the data container named “munki-data”. This means that /munki_repo is actually the same volume in both containers. What happens in one container to /munki_repo will be reflected in the other. This means that the Munki container can make changes and/or serve content from /munki_repo, but it also means that we can get rid of the Munki container without losing any data – it’s all still stored in the data-container named “munki-data.”

-p 80:80
This maps port 80 from the container to port 80 on the host. In other words, it means we can access this container by going to http://localhost:80/ on the Docker host.

-h munki
The -h argument tells the Munki container that its hostname is “munki”. If your Dockerhost has a search domain configured in its DNS settings, it’ll append the search domain onto the hostname. This argument is technically optional as none of the services we’re using in this example make use of it.

The name of the image we’re running.

Check with docker ps to make sure the image is running. If you access http://localhost:80/, you should see the default Nginx welcome page.

Populate the Munki server:

Now we have an empty Munki repo running from Nginx. We should populate this repo with content.

Docker makes this nice and easy, because we can instantly spin up a new container with the functionality we want and just link our existing containers. Since both Munki and munki-data have an exposed volume – /munki_repo/ – we can use a Samba/SMB container to share out this directory to an OS X client, where we can use the Munki tools to follow the Demonstration Setup.

For this task, we’ll use my SMB-Munki container:

  1. docker pull nmcspadden/smb-munki
  2. docker run -d -p 445:445 --volumes-from munki-data --name smb nmcspadden/smb-munki
  3. You will need to change permissions on the mounted share, as it’s currently owned by root. We want a simple SMB configuration where the guest is allowed read/write permissions. You can do this easily using docker exec:
    docker exec smb chown -R nobody:nogroup /munki_repo
    docker exec smb chmod -R ugo+rwx /munki_repo
    Check permissions now with docker exec smb ls -alF /munki_repo to make sure.
  4. From an OS X client, Go -> Connect to Server -> smb://docker_host_IP/ and authenticate as Guest to the Public share, which will mount as /Volumes/public/.
  5. Populate the Munki repo using the usual tools – munkiimport, manifestutil, makecatalogs, etc. Try making a site_default manifest.

Anyone with SMB familiarity will note that the SMB configuration is rather weak on security and allows anyone to simply log in and make changes. We’re not hosting an SMB server – it’s better to think of the Docker container like running an application. We quit when we’re done. To prevent unwanted access, we can simply stop the SMB container:
docker stop smb
That gracefully exits the SMB service and kicks off all clients. If we wanted to run it again, we simply start it:
docker start smb

Once you’ve got the Demonstration setup (or any setup) completed, you should be able to access a manifest via web browser easily:

In the next post, I’ll talk about using Puppet to secure the repo with SSL.


3 thoughts on “Running Munki in Docker

  1. Great example.
    I’m getting this error that I’m trying to figure out. I get this output when I run “docker run -d -p 445:445 –volumes-from munki-data –name smb nmcspadden/smb-munki”:

    “docker: Error response from daemon: driver failed programming external connectivity on endpoint smb (4aa2f505ff90b7102003e1e668e06aec266d0c59a15db34055bfb9e05c447cd9): Error starting userland proxy: Bind for unexpected error (Failure EADDRINUSE).”

    I suppose something I’m doing is already using that port?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s