Now you can use Puppet to solve two problems with large Docker workflows:

You have a Puppet code base, and you're moving some of your services into containers. By sharing the same code across your infrastructure, regardless of whether or not it uses containers, you can cut down on duplication of effort, and take advantage of work you've already done.

You're building many images, but scaling Dockerfile involves either a complex hierarchy of images or copying and pasting snippets between many individual Dockerfiles. The image_build Puppet module lets you share common functionality using the familiar Puppet modules mechanism, and Puppet itself provides a rich domain-specific language for declarative composition of images.

I spoke at DockerCon in Seattle this year about the Dockerfile explosion and the need for higher-level tools, and this functionality continues that conversation. It’s not about a general-purpose solution in the vein of Dockerfile — it specifically addresses the needs of existing Puppet users, as well as those new to Puppet working in large, messy enterprise organizations.

Installation

Packaged as a Puppet module, image_build is available on the Forge. You can install it with the usual tools, including the puppet module command:

puppet module install puppetlabs/image_build

You also need to install Docker, for which I'd recommend the excellent Docker for Mac or Docker for Windows. Or you can just install Docker from packages if you're on Linux.

After installing the module, you can use some new Puppet commands, including puppet docker, which in turn has two subcommands: one triggers a build of an image, while the other outputs the intermediary Dockerfile. The examples directory contains a set of examples for experimenting with. Let’s look at one of those now.

Hello world

We'll create a Docker image running Nginx and serving a simple text file. This is a realistic but obviously simplistic example; it could be any application, such as a custom Java or Ruby or other application.

First, let’s use a few Puppet modules from the Forge. We'll use the existing Nginx module and specify its dependencies. We'll also use the dummy_service module to ignore service resources in the Nginx module. We do this by creating a standard Puppetfile.

Next, let’s write a simple manifest. Disabling nginx daemon mode isn't supported by the module just yet (but the folks maintaining the module have just merged this capability), so let’s drop a file in place with an exec. Have a look at manifests/init.pp:

The image could be run via the Puppet Docker module, or atop any of the container schedulers.

Thanks

The development of image_build benefitted greatly from conversations with several of our larger customers, and I wanted to thank everyone who spoke to us and provided feedback. Thanks in particular to Jason Meltzer, director of technology at Fannie Mae, who nicely summarized what we’re aiming to accomplish with this work:

We’re excited about this announcement because it makes it possible to move a service from traditional infrastructure to a containerized environment with the tools we use today to manage everything from databases, to app servers, to services running in containers.

Next steps

This is the first release of image_build, and we have lots more ideas for improvements and more fleshed-out workflows for using this with other tools in the Puppet and container ecosystems. Keep an eye on this blog for more posts, and if you have any ideas or thoughts, please let us know in the comments below.