\[ \definecolor{data}{RGB}{18,110,213} \definecolor{unknown}{RGB}{217,86,16} \definecolor{learned}{RGB}{175,114,176} \]


Look mom, no Dockerfile!

Vadim Rutkovsky
Red Hat Czech, http://github.com/vrutkovs

Typical case

Grafana - an app to build dashboards and grafs from various sources

Default choice: monitoringartist/grafana-xxl

Why I didn't like default Grafana-XXL image from dockerhub:

  • Bloated: all the grafana plugins installed
  • Bloated: uses gosu to run
  • Has auto-upgrade on by default
  • Doesn't have read-only anonymous access

Dockerfile + shell = hell

ENV GRAFANA_VERSION=3.1.1-1470047149 \
    GF_PLUGIN_DIR=/grafana-plugins \

COPY ./run.sh /run.sh

RUN apt-get update && \
  apt-get -y --force-yes --no-install-recommends install libfontconfig \
      curl ca-certificates git jq && \
  curl https://grafanarel.s3.amazonaws.com/builds/grafana_${GRAFANA_VERSION}_amd64.deb >
      /tmp/grafana.deb && \
  dpkg -i /tmp/grafana.deb && \
  rm /tmp/grafana.deb && \
  curl -L https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64 > \
      /usr/sbin/gosu && \
  chmod +x /usr/sbin/gosu && \
for plugin in $(curl -s https://grafana.net/api/plugins?orderBy=name | 
      jq '.items[] | select(.internal=='false') | .slug' | tr -d '"'); do 
      grafana-cli --pluginsDir "${GF_PLUGIN_DIR}" plugins install $plugin; done

Ansible Container

Ansible Container


sudo pip install ansible-container

A tool to build Docker images and orchestrate containers using only Ansible playbooks instead of Dockerfile + shell + docker-compose combination.

Ansible Container allows using several ansible features:

  • Vars
  • Templates
  • Roles

Directory structure

ansible-container init creates initial files:

└── ansible
    ├── container.yml
    ├── main.yml
    └── requirements.txt
  • main.yml - playbook to build the image
  • container.yml - orchestration
  • requirements.txt - requirements for ansible module

container.yml - orchestration

version: "1"
    image: centos:7
      - "3000:3000"
    user: "grafana"
    command: ["/usr/sbin/grafana-server",

    url: atomic-registry.usersys.redhat.com:5000
    namespace: vrutkovs

main.yml - playbook

- hosts: grafana
    rpm: https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.1-1470047149.x86_64.rpm
    - name: Upgrade all packages
      yum: name=* state=latest

    - name: Install grafana
      yum: name="{{ rpm }}" state=present
    - name: Install plugins
      command: grafana-cli --pluginsDir /grafana-plugins plugins install {{ item }}
        - grafana-piechart-panel
        - alexanderzobnin-zabbix-app
        - mtanda-histogram-panel
    - name: Copy config file
      copy: src="grafana.ini" dest=/etc/grafana owner=grafana

    - name: Make sure grafana user is the owner of its dirs
      file: name={{ item }} state=directory owner=grafana recurse=true
        - /grafana-plugins
        - /var/lib/grafana
        - /var/log/grafana
    - name: Clean yum files
      command: yum clean all

Build process

  • ansible-container build creates a build container: "ansible_ansible-container" and containers for services: "ansible_<service name>"
  • Build container adds service container to the inventory
  • Build container runs the playbook
  • The result is committed and the images are exported
  • The image can be 'flattened' into a single layer

Build log

Starting Docker Compose engine to build your images...
Attaching to ansible_ansible-container_1
Attaching to ansible_ansible-container_1, ansible_grafana_1
ansible-container_1  | 
ansible-container_1  | PLAY [grafana] ********************************************
ansible-container_1  | 
ansible-container_1  | TASK [setup] **********************************************
ansible-container_1  | ok: [grafana]
ansible-container_1  | 
ansible-container_1  | TASK [Upgrade all packages] *******************************
ansible-container_1  | ok: [grafana]
ansible-container_1  |


ansible-container_1  | PLAY RECAP ************************************************
ansible-container_1  | grafana: ok=7    changed=2    unreachable=0    failed=0   
ansible-container_1  | 
ansible_ansible-container_1 exited with code 0
Aborting on container exit...
Stopping ansible_grafana_1 ... 
Stopping ansible_grafana_1 ... done
Exporting built containers as images...
Committing image...
Exported grafana-xxl-grafana with image ID 
Cleaning up grafana build container...
Cleaning up Ansible Container builder...

Running and shipping it

run starts services according to their description in container.yml

push pushes the resulting image to a specified registry

shipit kubernetes creates a playbook which deploys the image to a k8s cluster

shipit openshift same for Openshift


A very young project, has lots of plans:

  • Build caching
  • Detached run, stop and restart
  • Custom volumes and build variables
  • rkt and OCI support

Github: https://github.com/ansible/ansible-container

Docs: https://docs.ansible.com/ansible-container

#ansible-container on Freenode

Thanks! Questions?