This article describeshow to build Docker image and deploy containerized application on Atomic host (any Remote host) using Ansible Playbook.
Building Docker image for an application and run container/cluster of containers is nothing new. But the idea is to automate the whole process and this is where Ansible playbooks come in to play.
Let’s see How to automate the containerization and deployment process for a simple Flask application:We are going to deploy container on Fedora Atomic host .
First, Let’s Create a simple Flask Hello-World Application.
This is the Directory structure of the entire Application: flask-helloworld/ ├── ansible │ ├── ansible.cfg │ ├── inventory │ └── main.yml ├── Dockerfile ├── flask-helloworld │ ├── hello_world.py │ ├── static │ │ └── style.css │ └── templates │ ├── index.html │ └── master.html └── requirements.txt requirements.txt Flask==0.11.1 Jinja2==2.8 hello_world.py from flask import Flask, render_template APP = Flask(__name__) @APP.route('/') def index(): return render_template('index.html') if __name__ == '__main__': APP.run(debug=True, host='0.0.0.0') static/style.css body { background: #F8A434; font-family: 'Lato', sans-serif; color: #FDFCFB; text-align: center; position: relative; bottom: 35px; top: 65px; } .description { position: relative; top: 55px; font-size: 50px; letter-spacing: 1.5px; line-height: 1.3em; margin: -2px 0 45px; } templates/master.html <!doctype html> <html> <head> {% block head %} <title>{% block title %}{% endblock %}</title> {% endblock %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous"> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <link href='http://fonts.googleapis.com/css?family=Lato:400,700' rel='stylesheet' type='text/css'> </head> <body> <div id="container"> {% block content %} {% endblock %}</div> </body> </html> templates/index.html {% extends "master.html" %} {% block title %}Welcome to Flask App{% endblock %} {% block content %} <div class="description"> Hello World</div> {% endblock %} Let’s write the Dockerfile. FROM fedora MAINTAINER Trishna Guha<tguha@redhat.com> RUN dnf -y update && dnf -y install python-virtualenv && dnf clean all RUN virtualenv venv RUN source venv/bin/activate RUN mkdir -p /app COPY requirements.txt /app WORKDIR /app RUN pip install -r requirements.txt COPY files/ /app/ WORKDIR /app ENTRYPOINT ["python"] CMD ["hello_world.py"] Now we will work on Ansible playbook for our application that deals with the automation part:Create :
inventory
[atomic] IP_ADDRESS_OF_HOST ansible_ssh_private_key_file=<'PRIVATE_KEY_FILE'>Replace IP_ADDRESS_OF_HOST with the IP address of the atomic/remote host and ‘PRIVATE_KEY_FILE’ with your private key file.
Create file:
ansible.cfg
[defaults] inventory=inventory remote_user=USER [privilege_escalation] become_method=sudo become_user=rootReplace USER with the user of your remote host.
Create file:
main.yml
--- - name: Deploy Flask App hosts: atomic become: yes vars: src_dir: [Source Directory] dest_dir: [Destination Directory] tasks: - name: Create Destination Directory file: path: "{{ dest_dir }}/files" state: directory recurse: yes - name: Copy Dockerfile to host copy: src: "{{ src_dir }}/Dockerfile" dest: "{{ dest_dir }}" - name: Copy requirements.txt to host copy: src: "{{ src_dir }}/requirements.txt" dest: "{{ dest_dir }}" - name: Copy Application to host copy: src: "{{ src_dir }}/flask-helloworld/" dest: "{{ dest_dir }}/files/" - name: Make sure that the current directory is {{ dest_dir }} command: cd {{ dest_dir }} - name: Build Docker Image command: docker build --rm -t fedora/flask-app:test -f "{{ dest_dir }}/Dockerfile" "{{ dest_dir }}" - name: Run Docker Container command: docker run -d --name helloworld -p 5000:5000 fedora/flask-app:test ...Now simply run <$ansible-playbook main.yml> :). To verify if the application is running issue this command <$ curl http://localhost:5000> ; on your atomic/remote host.
You can also manage your containers running on remote host using Cockpit . Check this article to know how to use Cockpit to manage your containers: https://fedoramagazine.org/deploy-containers-atomic-host-ansible-cockpit


Here is the repository of the above example: https://github.com/trishnaguha/fedora-cloud-ansible/tree/master/examples/flask-helloworld
My future post will be related to ansible-container where I will describe how we can build Docker image and orchestrate container without writing any Dockerfile.