April 20, 2021

How to Run Puppet in Docker

Ecosystems & Integrations
How to & Use Cases

If you’ve ever wanted to get started with Puppet or Docker — or both — you’ve probably faced a bit of a conundrum. Should I use Puppet to deploy Docker on my nodes, and then use Puppet to define container images? Or should I use Docker containers to deploy Puppet so I can test dashboards and other modules without having to build out my infrastructure?

In reality, you can do both. Puppet in Docker is a new, experimental way of packaging and releasing Puppet software (including Puppet Server and PuppetDB) using Docker.

In this blog post, I’ll show you how to use some of the Puppet tools to create working containerized environments. You may well try these in development, but I think you’ll quickly see how you can transfer what you learn to production applications.

Table of Contents:

Why Puppet in Docker?

Puppet in Docker is a way to run Puppet and other Puppet software such as Puppet Server and PuppetDB. Learn how to run Puppet software in Docker containers.

By packaging up these components as Docker images we:

  • Allow for running a Puppet infrastructure (e.g., Puppet Server, PuppetDB, PostgreSQL) on any host that can run (or only runs) Linux containers.
  • Allow for running and scaling the same Puppet infrastructure on top of cluster managers like Kubernetes, Rancher, DC/OS or Docker Swarm.
  • Run some features of the Puppet agent on any host that can run a container, by mounting volumes from the underlying host. This includes new platforms for which a native Puppet agent does not yet exist.
  • Create a great local Puppet development environment with Docker Machine, or the recent Docker for Mac and Windows beta. This can make it much easier to test a new version of Puppet or build something against the PuppetDB API.

Puppet Docker Images: What's Available Today?

Today we’re releasing a number of images to Puppet's Docker Hub. These include:

All of the Dockerfiles, and the accompanying build tools and tests, can be found in the Puppet-in-Docker repository. Please do open issues or pull requests with your improvements, issues or suggestions. One reason for releasing images ourselves is to encourage collaboration.

Releasing new software without providing examples of how to use it is never a good idea, so we have a separate repository of Puppet-in-Docker examples. So far, we have examples showing how Puppet in Docker enables running Puppet on VMware Photon OS, Red Hat CentOS Atomic and on CoreOS. Also, how to stand up a Puppet infrastructure using Docker Compose. We’ll be adding more examples as time permits; again, please open issues or send pull requests if you have suggestions or ideas.

Examples of Puppet-in-Docker

The above Puppet-in-Docker repository contains a number of examples, but since this is a new way of running Puppet, it’s useful to include a few simple examples here. The following assumes you already have Docker installed and running on your machine.

First let’s create a simple Docker network. We’re using the latest network and service discovery features in Docker 1.11 here, but you could use explicit links in older versions if needed. 

docker network create puppet

 

With the network created, let’s launch an instance of Puppet Server:

docker run --net puppet --name puppet --hostname puppet puppet/puppetserver

 

And finally let’s run a simple agent.  

docker run --net puppet puppet/puppet-agent-alpine

You should see quite verbose output from both of the containers, showing the agent-server connection and a summary of the agent run. This isn’t a very useful example, in that the container will launch, connect to the Puppet Server, apply any required changes and then terminate. But it does demonstrate the basic agent-server connectivity in a Hello World fashion. 

How to Run Puppet and Docker Containers: A Tutorial

Getting Started: Install Docker With Puppet

Whether you’re just getting started with containers or you’ve been using them for a while, one of the easiest ways to deploy Docker is with the Puppet module

To deploy Docker on any node managed by your Puppet server, you can simply add the basic class:

include ‘docker’

There are other options for the class, but that will get you started, particularly if you’re looking to do your work on a development virtual machine.

 

When Should You Switch from Open Source Puppet to Puppet Enterprise?

🤔 DOWNLOAD THE GUIDE

A graphic of a guide by Puppet. Title: A Business Guide to Open Source Puppet vs. Puppet Enterprise

 

Once deployed to a node, Docker will run and behave just as it would if you installed it manually. Using Puppet to automate this basic step, though, is a great way to deploy as many instances you want, the same way every time.

With Docker installed, you can start running some simple tests, like pulling down the latest version of the CentOS image:

$ docker run -it centos:latest /bin/bash

Let’s take it a step further by having Docker create a new container with Puppet inside, which can perform any instruction you would pass in a manifest. For example:

$ docker run --name apply-test puppet/puppet-agent apply -e 'file { "/tmp/adhoc": content => "Written by Puppet" }'

This will pull the puppet/puppet-agent image from Docker Hub and use Puppet to apply a change, namely creating a file in /tmp/adhoc containing the words, “Written by Puppet.”

If you now run a diff on that container, you’ll see what’s changed from the original image. In this case, upon running, the container created new folders and added content to them, including the /tmp/adhoc file:

root@node02:~# docker diff apply-test
C /etc
C /etc/puppetlabs
C /etc/puppetlabs/puppet
A /etc/puppetlabs/puppet/ssl
A /etc/puppetlabs/puppet/ssl/certificate_requests
A /etc/puppetlabs/puppet/ssl/certs
A /etc/puppetlabs/puppet/ssl/private
A /etc/puppetlabs/puppet/ssl/private_keys
A /etc/puppetlabs/puppet/ssl/public_keys
...
C /tmp
A /tmp/adhoc

This is a good way to experiment with and learn Puppet with very little infrastructure or overhead. Instead of building out a full virtual machine and setting it up as a Puppet node, you can use a straightforward Docker command to see how Puppet would make a change or apply some action. It’s fast and you can quickly see your workflows in action. If something breaks, you can just remove the containers and start over.

Run Puppet Server on Top of Docker

You can actually move well beyond launching a handful of containers, and run your Puppet infrastructure on top of a containers-as-a-service platform. This can be accomplished with the puppet/puppetserver image, which will deploy a fully functioning Puppet server:

$ docker run --net puppet --name puppet --hostname puppet puppet/puppetserver

In this example, the Puppet server is created in a container called puppet on a Docker network named "puppet." The only piece you really need is docker run puppet/puppetserver, but the other bits allow you to attach your server to a specific network, name the container for easy reuse, and set the hostname so container-based agent nodes can find it.

All the open-source components of a stand-alone Puppet infrastructure are available in this same fashion, including Puppet Server, PuppetDB and various dashboards. You can put them all back together as a stack with Docker Compose.

Compose is a YAML file format that enables you to describe a series of containers in key-value pairs, and define how they should be related and linked. You can manually install docker-compose or install it using the docker::compose class in the docker module mentioned above.

To test the power of Docker Compose, create a docker-compose.yml file or download the sample from the examples.

The file describes several container images, including puppetserver, puppetdb-postgres, puppetboard and puppetexplorer. These last two are browser-based dashboard components that will become accessible when Docker Compose completes.

Everything will be pulled, built and booted from a single command executed from the directory where you’ve saved your docker-compose.yml file:

$ docker-compose up
A screenshot of Puppet code in which several Puppet nodes are deployed as containers using docker-compose
Figure 1. Several Puppet nodes are deployed as containers using docker-compose

 

Results

You should now begin to see how the combination of Puppet and Docker gives you new and powerful ways to expand your development environment. Instead of deploying one Puppet node at a time, you can use simple Docker commands to do the work for you. That means you can spend less time building the platform, and more time developing and testing. And because these environments are up and running in minutes, you can deploy as many as you want almost anywhere you want — and easily start over with a clean install every time.

Thanks to the Community For Puppet + Docker

We know this is useful to some already because of a great deal of prior art from within the Puppet community. A simple search on Docker Hub today shows more than 400 Docker images matching the search term Puppet. And there have been several excellent blog posts from people over the past year or so, with instructions and examples of how to roll your own images. We took inspiration from many of these efforts, but struck out on our own for the implementation for a few reasons:

  • We want to balance ease of first use with more advanced features. Ultimately, more advanced users can always use the images as a base image to build from, or even take and modify the Dockerfile.
  • The best practice around Dockerfiles is still emerging. As well as adhering to some of those practices, we’re looking to push the state of the art a little with the accompanying build toolchain.
  • By providing an integrated set of images, we can more easily create full-stack examples, and we can be sure to release updates to the images with the latest Puppet software as it becomes available.

We’re hoping the community will find value in a central set of images aimed at the majority use case. We’ll also look to publish more documentation about using the existing images as a base for more advanced cases.

What’s Next For Puppet + Docker?

This is a new and experimental way of installing and running Puppet, intended mainly for testing and for early adopters. We’re releasing this to the Puppet community in order to get feedback and learn. We hope it's useful now, but software improves with feedback and input from users (that’s you!). We’re interested in the interface, in the defaults chosen, in how you’d like to be able to use these images (but can’t yet). The current release also assumes a level of Docker knowledge; we wonder if there are people interested in some of these capabilities who maybe don’t have, or don’t want, a Docker-centered approach.

It’s worth noting here that the aim isn’t to replace the existing battle-tested packages we already provide, but to supplement them so people working with container-centric infrastructures can still take advantage of all Puppet has to offer. This current release of images focuses on the various open source components, but we’d also love to hear from Puppet Enterprise customers who find this approach compelling.

This is just the start. We have a number of ideas for building on this initial release, as well as building with it. We’re looking forward to seeing what you think.

Try Puppet Today

Not using Puppet Enterprise yet? Get started with your free trial today.

✅ START MY TRIAL NOW  

Learn More

 

This blog was originally published in two parts on May 31, 2016 and April 20, 2017. It has since been updated for accuracy and relevance.