Ansible -2

Launching Docker Container Using Ansible

Launch Apache webserver docker container using ansible

We are going to launch the apache webserver docker container on top of a managed node with the help of Ansible.

Before moving to the action let's take a look at what is docker, ansible, and apache server so we will get a little idea about these technologies and the need for this integration. so without waiting let's get into the introduction.

Introduction 🤓

Redhat Ansible

Ansible is an open-source automation tool by which we can automate all cloud provisioning, configuration management, application deployment,intra-service orchestration, and many more IT needs.

Ansible is an open-source community project sponsored by Red Hat, it’s the simplest way to automate IT. Ansible is the only automation language that can be used across entire IT teams from systems and network administrators to developers and managers.
You can read more about ansible in below article and how it helps in DevOps

Docker 🐳

Docker is an open-source project launched in 2013. It is a software platform for building applications based on containers — small and lightweight execution environment share make shared use of the operating system kernel but otherwise run in isolation from one another.

Docker enables you to separate your applications from your infrastructure so you can deliver software quickly.

Apache Webserver

Apache is an open-source and free web server software that powers around 40% of websites around the world. The official name is Apache HTTP Server, and it’s maintained and developed by the Apache Software Foundation. It allows website owners to serve content on the web — hence the name “webserver.” It’s one of the oldest and most reliable web servers, with the first version released more than 20 years ago, in 1995.

Problem Statement 🤯

Write an Ansible PlayBook that does the following operations in the managed nodes:

  1. Configure Docker.
  2. Start and enable Docker services.
  3. Pull the httpd (Apache) server image from the Docker Hub.
  4. Run the docker container and expose it to the public.
  5. Copy the html code in the document root directory and start the webserver.

Now we have a clear idea of what we want to do…
So let’s see step by step how we are going to do this

Action mode 🔥

We will use ssh public key authentication to configure managed/target nodes. The motivation to use public-key authentication over simple passwords is security. Public key authentication provides cryptographic strength that even extremely long passwords can not offer. With SSH we also don’t need to remember long passwords.

So let’s create one ssh key using the below command for that…
Go to the .ssh folder

$ cd .ssh$ ssh-keygen -t rsa -b 4096

Now it will generate two files private and public keys in the .ssh file.

Now we have to copy the public key to the managed node for ssh authentication. for that we will use the ssh-copy-id command or else you can use the SCP command to authorized files also.

$ssh-copy-id -i username@managed_node_ip

It will ask first the time user password and enter the password then you are ready to go. above command append your id to ssh authorized file of a managed node.

In my case, my managed node IP address is
You can check IP address using $ ifconfig command

Now let’s test that we can connect manually to the managed node before moving to an ansible setup.

$ ssh username@hostname

using the above command you can test that we have successfully transferred the ssh public key or not. You can see that the managed node authorized_keys file has your generated public key.

Now we have set up ssh connection now we are ready to connect and configure the managed node using ansible.

Now add managed node IP to your inventory file.
I have created one group called ‘docker’ and inside that group, I have added managed node IP. You can see the in the below image.

$ ansible docker --list-hosts

The above command shows the IP address list in the group name that we have added to the inventory file.

Now let's run the first command to ensure that ansible has a proper connection with the managed node.

$ ansible docker -m ping

If you see a green response and ping: pong then yes.. we are fully ready to start…

Install Docker

  • Configure yum repository

First, we have to add a yum repo for docker so we can download docker software from the yum repository.
Let’s check that the managed node has a yum repo for docker or not.

The below image is of the managed node command output. I will show both the screenshots of the managed node and controller node for better understanding.

You can see that it does not have any docker repo added.

Ansible has a yum_repository module by which we can add a yum repository in the managed node. But we want to configure yum only if the managed node is from the RedHat family.

Create an Ansible playbook with the below code with extension .yml

You can see in the above image that I have added ‘docker’ in hosts that group name that we have added in the inventory file. we have added the above code it's time to run the above code.

$ ansible-playbook docker-cofigure.yml

You can see the orange output means something has changed on the managed node. so we have configured the docker repo successfully. you can check in the below image.

Install docker

Now we have configured the yum repo then we can easily download docker software using the package module in ansible.

Before this let’s check that on the managed node we have already installed docker or not. As you see we our managed node does not have docker software.

To install software we can use the package module in ansible. so let's take the help of the package module to install docker. Add below code under yum repository task.

after this time to run the playbook again and test.

Ansible has idempotent so you can check that it does not configure yum again. and it has changed something in docker task and returned with orange output that means it has successfully installed docker software for us. let’s go and check on the managed node.

yes.. we have successfully installed docker on the managed node.

Now to perform an operation on docker we have to start the docker service. because it is by default inactive.

to start docker service we have a ‘service’ module in ansible. we will use the ‘service’ module to start the docker service.

add below code to our playbook file to start the docker service.

now let’s run the playbook again to see the effect.

now we have started docker using ansible let’s confirm it using systemctl command on the managed node.

Now we have installed docker and started docker successfully.. its time to launch the container… no we have to download docker SDK because it is a pre-requisite for our next module

so let’s write the code to download docker SDK before launching the docker container. First, install python pip3 using the package and then download docker SDK using pip

After running these tasks using ansible-playbook docker-configure.yml

You can see in above image it has successfully downloaded docker SDK using pip. You can check it on the managed node using the pip list command.

Now finally finished with docker installation totally. now we can launch as many containers as we want…

but before that, we have to copy our source code of the website to the managed node.
we have to copy somewhere in the managed node but let's make it a little organized and create one directory for our project and then copy source code to that directory.

so let’s declare one variable in the playbook, or you can create another file for the variable and then imports the variable from that file. but for simplicity, I am keeping it into the single playbook. The benefit of declaring a variable for another project I don’t need to go and manually update code, Just update the value for the variable.

Here “dev-creatorsbyheart” is my development version of the creatorsbyheart project. I want to also name this as a container name so I can differentiate between different environments of the project.
Let’s create a directory where we want to copy the source code.

Let's confirm that the directory is not already created. As you can see at the current location there is no directory of the project name.

Add below code at the end of the playbook.

Here we are reading the value of user_dir from ansible_facts. In our case, it is /root as we have login using root. Then at that location, we will create a new directory of the project name using the ‘file’ module in ansible.
Let’s run it and check it has created is successfully or not.

Now that we have created the directory time to copy source code to the directory created on a managed node in the above step.

for copying files/directory we have the ‘copy’ module in ansible. we will use that module to achieve our goal.
before that declare a variable for project files because the path varies for different projects.

Add below task for copy files.

Here we are copying files from the directory mentioned in the source_code_dir variable to the destination folder we created in the previous step.

Let’s run and check the ansible successfully copied to the proper destination or not.

Now the time is arrived to launch the container and deploy our website using the container. My need is to use apache webserver so I will use apache docker image. Before that let's check any container is running or not on the managed node.

No there is no container running now… so let’s run our webserver without wasting time…
Now there will be the time we have multiple docker containers and the port number will also vary. so create a new variable for the port number.

and add the below task also for launching the docker container. I have used only the variable for port numbers you can customize as per your need.

We are using an ansible ‘docker_container’ module for launching an httpd container. It will pull the image if it is not already downloaded in a managed node and launch the container. we are exposing its HTTP port and attaching the source code directory with the document root of the apache webserver. That way container can directly access files from the directory.

Let’s check the container is running or not on managed not.

Yes, it running and now we can connect to a webserver using managed node IP and the port we have mentioned in variables.

If you facing trouble with connecting to this URL, you might need to restart the firewall of a managed node or add port forwarding rules for the container.
In ansible we have ‘firewalld’ module for that.. you can use that as you need.

You can multiple things with ansible to know what we can achieve using Ansible I recommend you to read this blog.

You can find the above playbook on this GitHub repository. Bookmark or star it for future use.

If you have any doubts or something improvement needed in this blog, please feel free to reach out to me on my LinkedIn account.

I hope you learned something new and find ansible more interesting.
Let me know your thoughts about ansible and how do plan to use ansible?

Thank you.

About the writer:
Shubham loves technology, challenges, is open to learning and reinventing himself. He loves to share his knowledge. He is passionate about constant improvements.
He writes blogs about
Cloud Computing, Automation, DevOps, AWS, Infrastructure as code.
Visit his Medium home page to read more insights from him.