Deploy Apache Web-Server in Docker Container using Ansible-Playbook

Prakash Singh Rajpurohit
7 min readAug 5, 2020
Workflow of Task.

In today’s fast and automation world DevOps play’s an important role. The main reason behind DevOps popularity is that it allows enterprises to create and improve products at a faster pace than traditional software development methods.

In this article we gonna use one of the most popular DevOps tool i.e. Ansible. We gonna integrate Ansible with Docker to launch a Web-Server. Before we go to the practical part let’s first we should know what is Docker ? What is Ansible ? How to install ? How Ansible work ? So lets start.

What is docker ?

Docker is a containerization tool. Using Docker we can launch the entire environment for our application server just in 1 second. Docker run in a isolation world so it is very secure to use for application server.

What is Ansible ?

Ansible is an open source IT configuration management (CM) and automation platform, provided by Red Hat. It uses human-readable YAML templates so that users can program repetitive tasks to occur automatically, without learning an advanced language.

We have 2 ways to do Configuration :

  1. Manual : This is typically a old traditional configuration way in which user have to do all work manually and where manual part comes there would a high possibility of errors and mistakes.
  2. Automation : We can do Automatic configuration in 2 way :

a. We have a traditional scripting approach were we use imperative language like python we have, In this we have to mention/tell How to do ? and What to do ?

b. We have a newer scripting approach were we use declarative language like Ansible we have, In this we have to mention/tell What to do ? and amazing thing is that Ansible know how to do ? which makes Ansible very intelligent.

How to install Ansible?

Complete Ansible is build on top of Python. Ansible is one of the library of Python. So to install Ansible first we need to install python in our Operating System. I am using RHEL-8 OS for the practical, so in RHEL-8 dvd python is already given by Redhat community. So you have just run below command to install python in RHEL-8 OS. We can configure any OS with Ansible. Actual intelligence Ansible comes from module.

yum install python3 -y
python3 -V
Installing Python.

We can use python3 -V command to check whether python is installed or not.

So Python is installed successfully, Now we can install Ansible by running below command.

pip3 install ansible
ansible --version

We can use ansible — version command to check whether Ansible is installed or not.

Ansible Installation.

How Ansible Work ?

System were we write/run a code of Ansible is called Controller Node. System which Ansible configure is called Managed Node. For this practical I am using 2 VM of REHL-8 OS, one for Controller Node and other one is for Managed Node. By sitting at 1 single place anywhere in the world you are controlling the Node (Managed Node).

Controller Node and Managed Node.

The system which Ansible manage is inventory. So we have to provide inventory to Ansible to contact managed node. Inventory is a database of IP, username and password.

Inventory

Now we created the inventory in Desktop for Ansible but Ansible don’t know the location of this inventory. So we have to create a Ansible configuration file in which we have to give location of this inventory. Whenever Ansible run any command it always first go to this config file and then run any command. We have to create a Ansible name directory in /etc directory, in Ansible directory we will create Ansible.cfg file. As shown below.

mkdir /etc/ansible
vim /etc/ansible/ansible.cfg
Ansible Configuration File.
Inventory list.

Ansible Configuration file successfully created and now ansible know the location of inventory. Now to connect to managed node Ansible by-default use SSH protocol. To enable SSH protocol in controller node we need 2 packages i.e. epel-release and sshpass. First we need to install epel-release package which configure yum and give us extra packages with sshpass. Run below command to install this 2 packages.

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -yyum install sshpass -y

Now we will ping the managed node from controller node. If it is pinging we can configure anything in managed node. So lets check the connectivity.

Pinging Managed Node.

Managed Node is pingable from Controller Node.

You can go through this practical video of Ansible Installation and Configuration on linux OS.

Ansible Installation and Configuration.

Now let’s Configure docker in Managed Node and deploy Apache Web-Server in docker container. We will use Ansible playbooks for this practical.

Ansible Playbooks are one of the core features of Ansible and tell Ansible what to execute. Playbooks are the files where Ansible code is written. Playbooks are written in YAML format. YAML stands for Yet Another Markup Language.They are like a to-do list for Ansible that contains a list of tasks. Playbooks contain the steps which the user wants to execute on a particular machine(Managed Node). Playbooks are run sequentially.

Step1:

→ Configure Docker

Here we are Configuring Docker Repository and then we pass a command to install docker with community edition (ce).

- hosts: "Managed_Node1"
tasks:
- name: Configuring Docker Repository
yum_repository:
name: Docker
description: "Docker Repo"
baseurl: "https://download.docker.com/linux/centos/docker-ce.repo"
gpgcheck: no
register: x
- name: Checking Configuration Status
debug:
var: x.failed
- name: Installing Docker
package:
name: "docker-ce-18.06.3.ce-3.el7.x86_64"
state: present
register: y
- name: Checking Install Status
debug:
var: y.failed

Step2:

→ Start and Enable Docker Services

Here we pass a command to start Docker Services in managed node.

- name: Starting Docker Daemon
service:
name: docker
state: started
enabled: yes
when: y.failed == false

Step3:

→ Pull the httpd server image from the Docker Hub

Here we pass a command to pull the httpd image from docker hub. Before we pull the image we need a docker-py package otherwise it won’t pull the image because for pulling it require some python libraries (pre-requisite).

- name: Install
command: "pip install docker-py"
- name: Pull a Docker Image
docker_image:
name: httpd
tag: latest
source: pull
register: z
- name: Checking Pull Status
debug:
var: z

Step4:

→ Create Persistent Volume to mount with docker container.

Here first we are creating a persistent volume in managed node, after that we are copying the developer code in it.

- name: Creating a Persistent Volume Dir
file:
path: "/root/pv"
state: directory
- name: Copying the HTML code in the Directory
copy:
src: "/root/Desktop/index.html"
dest: "/root/pv"

Step5:

→ Run the httpd container and expose it to the public.

Here we are launching the HTTPD container and we expose the webserver so that client can access the webserver. We also mount the volume which we created in Step-4 with container, so that if any container get terminated / fail we won’t lose data.

- name: Launching an HTTPD Container
when: z.failed == false
docker_container:
name: apache-server
image: httpd
state: started
exposed_ports:
- "80"
ports:
- "8888:80"
volumes:
- /root/pv:/usr/local/apache2/htdocs

I write simple html code for accessing on Web-Server, which you can check below.

Code

This is my complete Ansible playbook for for Configure Docker and Deploy WebServer in Docker Container:

- hosts: "Managed_Node1"
tasks:
- name: Configuring Docker Repository
yum_repository:
name: Docker
description: "Docker Repo"
baseurl: "https://download.docker.com/linux/centos/docker-ce.repo"
gpgcheck: no
register: x
- name: Checking Configuration Status
debug:
var: x.failed
- name: Installing Docker
package:
name: "docker-ce-18.06.3.ce-3.el7.x86_64"
state: present
register: y
- name: Checking Install Status
debug:
var: y.failed
- name: Starting Docker Daemon
service:
name: docker
state: started
enabled: yes
when: y.failed == false
- name: Install
command: "pip install docker-py"
- name: Pull a Docker Image
docker_image:
name: httpd
tag: latest
source: pull
register: z
- name: Checking Pull Status
debug:
var: z
- name: Creating a Persistent Volume Dir
file:
path: "/root/pv"
state: directory
- name: Copying the HTML code in the Directory
copy:
src: "/root/Desktop/index.html"
dest: "/root/pv"
- name: Launching an HTTPD Container
when: z.failed == false
docker_container:
name: apache-server
image: httpd
state: started
exposed_ports:
- "80"
ports:
- "8888:80"
volumes:
- /root/pv:/usr/local/apache2/htdocs

Lets run this Ansible-playbook with given below command

ansible-playbook docker_conf.yml

It will give the output like this:

Web-Server is Successfully deployed in docker container. Lets go to the Managed node and check.

Managed Node.

Docker service is running and also Apache Web-Server is running in a container.

Now let access the Web-Server.

Web-Server.

Below you can go through the video of this task:

You can connect with me on linkedin : Prakash Singh

You can get code of this task in my github account : Click here to get code

Thank-you for reading.

If you find this article helpful, it would be appreciable if you could give 1 clap for it.

--

--

Prakash Singh Rajpurohit

Cloud Stack Developer. Working on Machine Learning, DevOps, Cloud and Big Data.