Deployment of Apache Httpd webserver on Docker using Ansible

Hello Fellow Programmers!!!

Hope you’ll doing great, well today I would like would like to talk about deploying Httpd Webserver over Docker using Ansible.

Content of this Blog

  • About Ansible
  • About Docker
  • About Apache HTTPD Webserver
  • Project Understanding

About Ansible

What is Ansible ?

Ansible is a radically simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs.

Why use Ansible ?

  1. Simple
  • Human readable automation
  • No special coding skills needed
  • Tasks executed in order
  • Get productive quickly

2. Powerful

  • App deployment
  • Configuration management
  • Workflow orchestration
  • Orchestrate the app lifecycle

3. Agentless

  • Agentless architecture
  • Uses OpenSSH and WinRM
  • No agents to exploit or update
  • Predictable, reliable and secure

Ansible Documentation :

About Docker

  • Docker is a open source platform for building, deploying and managing containerized applications. It enables developer to package applications into containers.
  • Containers are the executable components that combines the application source code with the Operating System(OS) libraries and dependencies required to run the code in any environment.
  • Docker makes it easier, simpler and safer to build, deploy and manage containers

Why use Docker ?

  • Doesn’t require machine-specific configurations
  • Could be easily configured for granular update
  • Provides automated container creation
  • Makes container versioning possible
  • Enables container reuse
  • User-contributed containers could be used from open-source registry

To know more about Docker, visit the site below:

Docker Documentation:

About Apache HTTPD Webserver

  • The Apache HTTP Server, colloquially called Apache, is a free and open-source cross-platform web server software, released under the terms of Apache License 2.0.
  • Apache is developed and maintained by an open community of developers under the auspices of the Apache Software Foundation.
  • The vast majority of Apache HTTP Server instances run on a Linux distribution, but current versions also run on Microsoft Windows, OpenVMS and a wide variety of Unix-like systems.

Apache HTTPD Documentation:

Project Understanding

Let’s understand this implementation part by part

Part 1 : Ansible Playbook (main.yml)

Let’s understand it task by task:

  • Mount Directory Creation” : Creation of Mount Directory
- name: Mount Directory Creation
file:
state: directory
path: "{{ mount_directory }}"
  • Mount Directory to CDROM” : Mount the directory created in previous task to the CDROM
- name: Mount Directory to CDROM
mount:
src: "/dev/cdrom"
path: "{{ mount_directory }}"
state: mounted
fstype: "iso9660"
  • YUM Repository-AppStream” : Addition of AppStream YUM repository
- name: YUM Repository - AppStream
yum_repository:
baseurl: "{{ mount_directory }}/AppStream"
name: "DVD1"
description: "YUM Repository - AppStream"
enabled: true
gpgcheck: no
  • YUM Repository -BaseOS” : Addition of BaseOS YUM repository
- name: YUM Repository - BaseOS
yum_repository:
baseurl: "{{ mount_directory }}/BaseOS"
name: "DVD2"
description: "YUM Repository - BaseOS"
enabled: true
gpgcheck: no
  • Docker Repository Setup” : Creation of repository for Docker tor its installation
- name: Docker Repository Setup
yum_repository:
baseurl: https://download.docker.com/linux/centos/7/x86_64/stable/
name: "docker"
description: "Docker repo"
enabled: true
gpgcheck: no
  • Setting pip installer” : Setting up pip installer to install Docker SDK for Python
- name: Setting pip installer
package:
name: "python36"
state: present
  • Setting SELinux Permissive” : Disabling SELinux for successful creation of Docker container
- name: Setting SELinux Permissive
selinux:
policy: targeted
state: permissive
  • Check whether Docker is installed or not” : Checks for presence of Docker by using the command “rpm -q docker-ce” and is used to make Docker Installation idempotent
- name: Check whether Docker is installed or not
command: "rpm -q docker-ce"
register: docker_check
ignore_errors: yes
  • Docker Installation” : Installs Docker only when the above task satisfies the when condition
- name: Docker Installation
command: "yum install docker-ce --nobest -y"
when: '"is not installed" in docker_check.stdout'
  • Starting Docker Service” : Starts Docker service
- name: Starting Docker Service
systemd:
name: "docker"
state: started
  • Stopping Firewall Service”: Disabling Firewall for accessing web page from the browser present outside the VM(Virtual Machine)
- name: Stopping Firewall Service
systemd:
name: "firewalld"
state: stopped
  • Installation of Docker SDK for Python for using Docker modules in Ansible” : Installation of Docker SDK for Python i.e., “docker-py’ for using Docker modules in Ansible
- name: Installation of Docker SDK for Python for using Docker modules in Ansible
pip:
name: "docker-py"
  • Creation of directory” : Creation of directory to be mounted with the HTTPD’s document root within Docker container
- name: Creation of directory
file:
path: /root/web_page/
state: directory
  • Copying the web page to the directory created” : Web page present within web directory(more details below) is copied to the directory created in previous tasks
- name: Copying the web page to the directory created
copy:
src: web/index.html
dest: /root/web_page/
  • Restarting Docker Service” : Docker Service is restarted to resolve the error mentioned below
- name: Restarting Docker Service
systemd:
name: "docker"
state: restarted
External Connectivity Error
  • Creation of Docker container for httpd” : Involves creation of Docker container using httpd image, the directory created in previous tasks is mounted to the Document Root of httpd and PAT(Port Address Translation) is performed to expose the container created
- name: Creation of Docker container for httpd
docker_container:
name: httpd_container
image: httpd
pull: yes
detach: yes
state: started
ports:
- "{{ port_number }}:80"
volumes:
- /root/web_page/:/usr/local/apache2/htdocs/

Complete Playbook

- hosts: test
vars_files:
- vars.yml
tasks:
- name: Mount Directory Creation
file:
state: directory
path: "{{ mount_directory }}"
- name: Mount Directory to CDROM
mount:
src: "/dev/cdrom"
path: "{{ mount_directory }}"
state: mounted
fstype: "iso9660"
- name: YUM Repository - AppStream
yum_repository:
baseurl: "{{ mount_directory }}/AppStream"
name: "DVD1"
description: "YUM Repository - AppStream"
enabled: true
gpgcheck: no
- name: YUM Repository - BaseOS
yum_repository:
baseurl: "{{ mount_directory }}/BaseOS"
name: "DVD2"
description: "YUM Repository - BaseOS"
enabled: true
gpgcheck: no
- name: Docker Repository Setup
yum_repository:
baseurl: https://download.docker.com/linux/centos/7/x86_64/stable/
name: "docker"
description: "Docker repo"
enabled: true
gpgcheck: no
- name: Setting pip installer
package:
name: "python36"
state: present
- name: Setting SELinux Permissive
selinux:
policy: targeted
state: permissive
- name: Check whether Docker is installed or not
command: "rpm -q docker-ce"
register: docker_check
ignore_errors: yes
- name: Docker Installation
command: "yum install docker-ce --nobest -y"
when: '"is not installed" in docker_check.stdout'
- name: Starting Docker Service
systemd:
name: "docker"
state: started
- name: Stopping Firewall Service
systemd:
name: "firewalld"
state: stopped
- name: Installation of Docker SDK for Python for using Docker modules in Ansible
pip:
name: "docker-py"
- name: Creation of directory
file:
path: /root/web_page/
state: directory
- name: Copying the web page to the directory created
copy:
src: web/index.html
dest: /root/web_page/
- name: Restarting Docker Service
systemd:
name: "docker"
state: restarted
- name: Creation of Docker container for httpd
docker_container:
name: httpd_container
image: httpd
pull: yes
detach: yes
state: started
ports:
- "{{ port_number }}:80"
volumes:
- /root/web_page/:/usr/local/apache2/htdocs/

Part 2 : Variable File (vars.yml)

mount_directory: "/dvd1"
port_number: "82"

Used to make Playbook more dynamic and it specifies the value of Port Number(for PAT) and Mount Directory

Part 3 : Web Page (index.html)

Hello, it's working

It specifies the web page to be accessed from outside the container

Part 4 : Output