Configure Apache Web-Server in Docker Container using Ansible-Playbook
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 :
- 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.
- 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 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).
This is my Controller Node !
This is my Managed Node !
make sure they both PING
Now lets move on to Configuration
Lets Setup ENV — Controller Node
install python3
yum install python3 -y
Check it
python3 -V
Install Ansible
pip3 install ansible
Check it
ansible --version
Creating Inventory
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.
Go to Desktop and Create a inventory file , you can give your file name
nano filename.txt
Inside the inventory give the SSH details
ManagedNodeipaddress ansible_ssh_user=root ansible_ssh_pass=yourpassword
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
nano /etc/ansible/ansible.cfg
here we need to write the conf code for ansible
[defaults]
inventory = your path to inventory file.txt
ansible_host_key_checking=FALSE
Check it working or not , using the following command
ansible all --list-hosts
here we see our Managed Node. 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 -y
yum 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.
ansible all -m ping
now we have successfully setup of ENV Controller Node ,
Now lets do a little test so we can verify our ansible is working properly for that go to Managed Node and delete the fire fox and reinstall through ansible Controller Node
to delete the fire fox in the Managed Node
rpm -q firefox
yum remove firefox -y
Now go to Controller Node and give the following command to install fire fox
ansible all -m package -a "name=firefox state=present"
now go back to Managed Node and check its done
rpm -q firefox
Our task is complete and ansible is working properly
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.
Create the play book , use following command
nano filename.yml
here in this file we need to give the process what we wanna do in the Managed Node
→ 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
→ 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
→ 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:"yum install python3 -y"
- 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
→ 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"
→ 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
Hope you got an idea about the code
This is my complete Ansible playbook for for Configure Docker and Deploy Web Server in Docker Container:
- hosts: "all"
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: "yum install python3"
- 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
finally you have add your html code in your specified path in code — if you don't have code you can use my code in the github repo bellow
Lets run this Ansible-playbook with given below command:
ansible-playbook yourfilename.yml
It will give the output like this:
Web-Server is Successfully deployed in docker container. Lets go to the Managed node and check.
use the following command in the Managed Node
systemctl status docker
Now lets check the output by give the ip of Managed Node in our host system web browser
ipaddress:portnumber
Here we can see our site running successfully