The base of this article was taken from my README.
Now that we have build the Docker image, let’s put it to use.
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:
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).
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”.
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
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.
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 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.”
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 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.
docker ps to make sure the image is running. If you access http://localhost:80/, you should see the default Nginx welcome page.
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:
docker pull nmcspadden/smb-munki
docker run -d -p 445:445 --volumes-from munki-data --name smb nmcspadden/smb-munki
- 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 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_repoto make sure.
- 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/.
- 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.