Skip to main content
As leading DevOps technologies, Docker and Puppet complement each other very well. Docker is used as a way to encapsulate applications in predictable environments within a lightweight container, while Puppet can be used to configure the host server to support and orchestrate Docker deployments. In this guide, we will walk through steps to configure and manage Docker containers with Puppet. This guide is composed of the following parts:
Part 1 – Creating and Uploading Containers to Docker Hub
Part 2 – Writing Puppet code to Manage Containers
Part 3 – Download and Deploy Custom Containers from Docker Hub
Technology Note
The guide is drafted based on the current course material at Linux Academy, which will allow you to get up to speed fairly quickly. However, as Docker tends to evolve very rapidly due to heavy development, there is a chance that whatever Docker implementation you are using could differ from the course. If that’s the case, we encourage you to post comments in our community forum if you have questions about the guide.
The following skills would be useful in following this guide, but aren’t strictly necessary:
  • Managing Linux or Unix-like systems (we will be mostly working within the terminal).
  • Having a working knowledge of Docker.
  • A basic understanding of Puppet.
Feel free to take advantage of the following resources available from Linux Academy to get up to speed:
  • Linux Essentials Certification –
  • Docker Quick Start –
  • Docker Deep Dive –
  • Learning Puppet DevOps Deployment (Puppet Professional Cert) –
Other related resources are listed at the end of this guide.
In addition, you should have the following:
  • A workstation environment with Docker installed.
  • An Linux server that supports Docker (in this guide, we are using Ubuntu 14.04) Has an installed copy of the Puppet agent (we recommend version 4.6.2).
  • A Docker Hub account. Instructions can be found at
Assuming that you have all of that, you may proceed.
Docker Development
As a first step, at the base of your home directory, create the directory src/docker/demo and then change over to that path.
stardust:~ rilindo$ mkdir -p src/docker/demo
stardust:~ rilindo$ cd src/docker/demo
Next, we will download the latest version of CentOS from Docker by running docker pull centos:latest:
stardust:demo rilindo$ docker pull centos:latest
The output should look similar to:
stardust:demo rilindo$ docker pull centos:latest
latest: Pulling from library/centos
8d30e94188e7: Pull complete
Digest: sha256:2ae0d2c881c7123870114fb9cc7afabd1e31f9888dac8286884f6cf59373ed9b
Status: Downloaded newer image for centos:latest
Now we will test the image by instantiating it with the command docker run -d –name apacheweb1 centos/apache:v1:

stardust:demo rilindo$ docker run -d --name apacheweb1 centos/apache:v1
It will return a long uuid string:
stardust:demo rilindo$ docker run -d --name apacheweb1 centos/apache:v1
We should be able to verify that it is running using the docker ps -a command:
stardust:demo rilindo$ docker ps -a
Output should be similar to the following:
stardust:demo rilindo$ docker ps -a
f4cd168eeef1 centos/apache:v1 "/bin/sh -c 'apachect" 9 seconds ago Up 8 seconds
With basic functionality verified, we can go ahead and create a custom Docker image.
Customizing a Docker Image
In the directory src/docker/demo, create the following Dockerfile:
FROM centos:latest
RUN yum update -y
RUN yum install -y httpd net tools
RUN echo "This is a custom index file built during the image creation" > /var/www/html/index.html
When we build the image, the following actions will take place:
  • Update CentOS to the latest version
  • Install the httpd (apache) application and supporting tools
  • Create a custom index page
  • Setup the container to start Apache in the foreground
Save the file and build the image with this command:
docker build -t centos/apache:v1
The output should be similar to the following:
stardust:demo rilindo$ docker build -t centos/apache:v1 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:latest
---> 980e0e4c79ec
---> Using cache
---> 418ea7dd7050
Step 3 : RUN yum update -y
---> Using cache
---> e2455d5eefd2
Step 4 : RUN yum install -y httpd net tools
---> Using cache
---> c81b8cd54ce8
Step 5 : RUN echo "This is a custom index file build during the image creation" > /var/www/html/index.html
---> Using cache
---> 362d569c3803
Step 6 : ENTRYPOINT apachectl "-DFOREGROUND"
---> Using cache
---> abcf05ec382a
Successfully built abcf05ec382a
Once the image is finished building, we are going to test it by spinning up a container based off of the image with:
docker run -d --name apacheweb1 -p 8080:80  centos/apache:v1
When you run the above command, you should be able to see it in the Docker process list by running docker ps -a. The output should look similar to this:
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                  NAMES
b049ba2e829f rilindo/myapacheweb:v1 "/bin/sh -c 'apachect" 4 days ago Up 4 seconds>80/tcp apacheweb1
stardust:~ rilindo$
You should be able to view the custom index page by browsing to it or downloading it with a web utility. In our case, we are able to view the index page by simply using curl:
stardust:~ rilindo$ curl localhost:8080
This is a custom index file build during the image creation
With your setup, you may need to pull the page against the Docker IP, which you can retrieve by parsing for the IPAddress against the output of docker inspect:
stardust:~ rilindo$ docker inspect apacheweb1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
Uploading The Custom Container
Now that you created a custom image, it is time to upload it to a private repository. If you haven’t done so, sign up for a Docker Hub account. When you are done, click on the button called “Create Registry”:
Then specify the name of the registry, a brief description of the repository, and mark the repository as “private” (we will get to the reasons why later on):
Once you are done, go back to your terminal and run docker login to authenticate against your account:
stardust:~ rilindo$ docker login
Enter your Docker Hub username and password and it should return with Login Succeeded message:
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to to create one.
Username: rilindo
Login Succeeded
stardust:~ rilindo$
Now list the images you have locally with the command Docker images (it should return most of the images you have locally)
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none> <none> 28ade7a75856 23 hours ago 485.4 MB
centos/apache v1 abcf05ec382a 23 hours ago 485.4 MB
nginx latest ba6bed934df2 3 days ago 181.4 MB
centos latest 980e0e4c79ec 2 weeks ago 196.8 MB
We will then tag the image we created using its Image ID that was just returned to us from the previous command. The tag should match the name of the repository, like so:
stardust:~ rilindo$ docker tag abcf05ec382a rilindo/myapacheweb:v1
When that is done, upload it with:
docker push  rilindo/myapacheweb:v1
It will take some time to upload, depending on your bandwidth. When it finishes, it should return with a hash at the end (note the bolded line):
stardust:~ rilindo$ docker push  rilindo/myapacheweb:v1
The push refers to a repository []
abfaedfcb05d: Mounted from rilindo/apache
c8bbf58a3299: Mounted from rilindo/apache
49715a5feaeb: Mounted from rilindo/apache
0aeb287b1ba9: Mounted from rilindo/apache
v1: digest: sha256:22136f81d1938870f19ec3a4773595de0660c39c1645e1a376855ec8d9897a6f size: 1160
Congratulations! You have successfully uploaded a Docker image to your account.
The next step at this point is to write puppet code to manage Docker containers, which we will do next time on Managing Docker with Puppet – Writing Puppet code to Manage Containers.
Comments are disabled for this guide.