Published on 16 April 2015 by

With the impending release of Puppet Enterprise 3.8, we will be adding support for managing Docker and Docker containers.

For those of you who haven't yet had the chance to take a look at Docker, it enables apps to be quickly assembled from multiple components and eliminates some of the friction between development, QA, and production environments. With new Docker Platform tools Swarm, Machine and Compose, it is a growing component of modern infrastructure.

Docker was first released around two years ago, and since then it's increasingly used as the basis for testing infrastructure, development environments and all manner of production applications. Using Puppet to manage Docker allows users to more quickly and efficiently deploy, and start and stop containers. The Puppet Docker module was first released around the initial release of Docker, and has been a great community effort since then, with more than 200 pull requests and close to 100,000 downloads from the Puppet Forge alone.

Managing Docker

At its simplest, the Docker module allows you to install Docker with one line in your manifest:

include 'docker'

The module also supports specifying a version of Docker, binding to a TCP socket, providing DNS settings, selecting a storage driver and much more. Configuration can be done by passing parameters to the Docker class or via Hiera.

As well as installing and managing Docker, the module allows for downloading images from the Docker Hub. You can download images and keep them current, or download specific tags, all using the Puppet domain-specific language (DSL):

docker::image { 'nginx': }

docker::image { 'ubuntu':
  image_tag => 'precise'

The module also supports building images from Dockerfiles automatically.

Running Docker Instances

The module supports running and managing individual Docker containers. This doesn't aim to replace a higher-level scheduler like Kubernetes or Mesos, but has the advantage of not requiring additional software. The module is perfect for managing containers you want running everywhere, or for using Docker on existing infrastructure. The containers can run under the host init system (like systemd or sysvinit) or using Docker's built-in process manager.

docker::run { 'helloworld':
  image   => 'base',
  command => '/bin/sh -c "while true; do echo hello world; sleep 1; done"',

The module also supports mounting volumes, setting environment variables, running privileged containers, exposing ports and more. You can also execute commands within the context of running containers using the docker exec feature.

docker::exec { 'helloworld-uptime':
  detach    => true,
  container => 'helloworld',
  command   => 'uptime',
  tty       => true,

See How It Works

This short video walks through how to manage Docker with Puppet:

Examples of Usage

There are a number of examples of the module in action, including using Puppet to create and manage a Docker Swarm cluster:

  • Launch vNext app in Docker using Puppet. This example contains a fairly simple example using Vagrant to launch a Linux virtual machine, then Puppet to install Docker, build an image and run a container. For added spice, the container runs an ASP.NET vNext application.

  • Multihost containers connected with Consul. This lets you launch multiple hosts running simple application containers, and load-balance between them using Nginx.

  • Configure Docker Swarm using Puppet. This example builds a cluster of hosts running Docker Swarm.

The Future

The combination of Puppet and Docker presents a number of exciting opportunities for managing modern infrastructure, and this module is really just the start. If you're already using the two together, we'd like to hear how, and what the results are. We're also interested in your ideas for features or enhancements. Please share your input in the comments section of this post, or on the puppet-users mailing list. Thanks in advance!

Learn more

  • The Puppet Forge has more than 3,000 modules to choose from for automating many operations tasks with Puppet.
Share via:
Posted in:

Im trying to use the module to run a container from a image of Docker Hub, but I got this error:

Error: Execution of '/bin/yum -d 0 -e 0 -y --enablerepo=rhel7-extras list docker' returned 1: Error getting repository data for rhel7-extras, repository not found
Error: /Stage[main]/Docker::Install/Package[docker]/ensure: change from absent to present failed: Execution of '/bin/yum -d 0 -e 0 -y --enablerepo=rhel7-extras list docker' returned 1: Error getting repository data for rhel7-extras, repository not found

My pp file has:
include 'docker'

docker::image { 'hello-world':
image_tag => 'precise',

docker::run { 'puppettest':
image => 'hello-world',
command => '/bin/sh -c "while true; do echo hello world; sleep 1; done"',

I have Docker installed in a RHEL 7 instance, running without problem.

Can you suggest me some advice?

Thank you in advance.

Gareth Rushgrove

Hi Javier

it looks from the error like you don't have the rhel7-extras repo available, and when the default it passed to yum it fails. You can override that using the repo_opts param at the top level. Something like:

class { 'docker':
    repo_opt => '',

With this, Pauppet is not searching on rhel7-extras repo, but didn't find the Docker installation anyway.
Finally I reinstalled Docker and it finally work.
Thank you very much.

I'm pretty new on Puppet and I try to run a Docker image with this module.
Before applying the manifest, is always this container up?
Is there a way to cancel this action?
Best regards!

Hi there!

Thanks for the walkthru! Its helpful. I am evaluating puppet enterprise at the moment. I would like to know what puppet classes I need to modify and/or to the node I want to bring up with this:

Additionally, what changes do I need to apply to the puppet master so that the node can read the class definitions properly?

Hi Tinoco

You should be able to do something similar to the following to run a container based on that image:

docker::run { 'elk':
  image   => 'blacktop/elk',
  ports => [80,  9200]

For questions like these you'll probably find the Ask Puppet site and the puppet-user community on IRC or the mailing list a good place to ask.

Hi Gareth,
I don't use docker class to manage docker daemon. When I use docker::run to start containers, it is always blocked when execute docker-systemd-reload. How could I manage docker container with Docker's built-in process manager? It always run under the host init system.

PP File is as following:
::docker::image { 'ctdcto23:5000/redis':
ensure => 'present',
image_tag => '3.0.0',

::docker::run { 'redis':
image => 'ctdcto23:5000/redis:3.0.0',
memory_limit => '500m',
hostname => 'redis',
ports => '6379:6379',
volumes => '/shared/datastore/redis:/data',
command => "redis-server --requirepass 'password'",
extra_parameters => ["--restart=always", "--log-driver syslog", "--log-opt syslog-facility=local0", "--log-opt syslog-tag='consul'"],
require => Docker::Image['ctdcto23:5000/redis'],

Hi Lex

This is a little underspecified and under-documented, but if you pass the restart parameter to the docker::run type you can bypass the creation of the host init and use Docker's built-in process manager. The code is unfortunately the best reference at present:

The options for passing to restart are as presented by Docker at:

The content of this field is kept private and will not be shown publicly.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.