Launching Docker Container Using Ansible
By: Shubham Rasal
Tags: Automation, Containers, Docker, Ansible, DevOps

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 ansible_key.pub 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 192.168.225.182.

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.