CREATING DOCKER CONTAINER USING ANSIBLE

CREATING DOCKER CONTAINER USING ANSIBLE

Ansible and Docker have acquired a larger share among DevOps products & tools. So how about creating a generic ansible playbook to deploy a docker container.

If you are new to Ansible, I would recommend you to go through Ansible: Getting Started.

We start our playbook by giving it a name Create Docker Container. This playbook will be executed on host localhost with connection type as local using user root. Make changes as per your need.

---
- name: Create Docker Container
  hosts: localhost
  connection: local  
  remote_user: root

Start with our tasks. First one is to include our variables. This will make this playbook more generic.

tasks:
    - name: include variables
      include_vars: vars.yml

Lets have a look at the vars.yml file

image: swapnillinux/apache-php
name: myweb
src_port: 8080
dest_port: 80
src_vol: /mnt/www
dest_vol: /var/www/html
privileged: true

In this example I am creating a docker container with the following properties. And to make it generic have defined it as a variable in vars.yml file. Suit yourself, make changes as per your need.

  • swapnillinux/apache-php docker images will be used, which is based on CentOS+Apache2+PHP5+mod_ssl
  • name of the container will be myweb
  • port 8080 from host running the container will be forwarded to port 80 of container.
  • port 443 from host running the container will be forwarded to port 443 of container.
  • folder /mnt/www from the host will be mapped as /var/www/html in the container. This will make you web-root persistent.

Next task will install python-docker to support docker modules available with Ansible 2.2

  - name: Install python-docker on Red Hat based distribution
    yum:
     name: python-docker
     enablerepo: extras
     state: latest
    when: ansible_os_family == 'RedHat'
  - name: Install python-docker  on Debian based distribution
    apt: 
      name: python-docker
      update_cache: yes
    when: ansible_os_family == 'Debian' 

I am using docker_container module to create container. And using the variable defined in the vars.yml file

    - name: Create Container
      docker_container:
        name: "{{ name }}"
        image: "{{ image }}"
        ports:
          - "{{ src_port }}:{{ dest_port }}"
        volumes:
          - "{{ src_vol }}:{{ dest_vol }}"
        privileged: "{{ privileged }}"

Theres a lot that can be done with docker_container module. Have a look at some great example by running the below command

ansible-doc docker_container

Thats not it, how about creating a systemd service and starting our container with system boot. For this I have used Jinja2 templates.

This is a jinja2 systemd unit file template.

# cat systemd.j2

[Unit]
Description={{ name }} Docker Container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a {{ name }}
ExecStop=/usr/bin/docker stop -t 2 {{ name }}

[Install]
WantedBy=default.target

We use template module in ansible to create this unit file using the name variable defined in vars.yml

  - name: Create Systemd Unit File as docker-{{ name }}.service
      template: src=systemd.j2 dest=/etc/systemd/system/docker-{{ name }}.service
  - name: reload systemd daemon
    command: systemctl daemon-reload

Next task will enable this service and start it, which should also start our container.

   - name: Start & Enable docker-{{ name }} service
     service:
       name: docker-{{ name }}
       state: started
       enabled: yes

And finally print the docker ps output

    - name: check container status
      command: docker ps
      register: result
    - debug: var=result.stdout
Ansible playbooks are created in yaml which are very sensitive to spaces and indentation. Copy paste in this blog might have destroyed that. So I have made all files available on GitHub at https://github.com/swapnil-linux/ansible/tree/master/create-docker-container

now lets execute this

Thats it for now. Enjoy ansibling :)


Like it? Click here to Tweet your feedback