Docker - Building containers using Ansible
Have you thought about building Docker containers using some Ansible role(s) or playbook(s) you may already be using for your regular automated deployments? Well this is something I have been going back and forth on. Whether to disregard existing Ansible roles I have created to deploy applications and services with or to start from scratch to build Docker containers. So I wanted to share a quick example of how you can do this if interested. The only downside is that the Docker image is a little fat because of the Ansible installation within the container. The plus to this is that Ansible is already installed in the container and you can actually reconfigure your containers with different variables ( based on variables in your Ansible role(s) or playbook(s) ) using docker exec commands. But that is debatable IMHO because I would possibly rather use Ansible to spin up the containers passing the ENV variables which are defined as part of the container. So the real benefit here would be to leverage your existing role(s) and playbook(s) that you use for your non containerized instances to build your Docker containers.
So with the above being said let’s take these methodologies and build a MySQL container.
As I mentioned above, I already have an Ansible role to deploy MySQL so I will be leveraging that.
If we look at the directory structure of the files that will be copied into our Docker container during the build.
vagrant@node-1:/vagrant/containers/mysql-ansible$ tree
.
├── ansible_tasks
│ ├── playbook.yml
│ └── requirements.yml
└── Dockerfile
1 directory, 3 files
And below are the contents of the files which will be copied.
playbook.yml
---
- hosts: localhost
become: true
vars:
- mysql_allow_remote_connections: true
- mysql_docker_install: true
roles:
- role: ansible-mysql
tasks:
requirements.yml
---
- src: https://github.com/mrlesmithjr/ansible-mysql.git
And our Dockerfile to build from (Using Ansible)
FROM ubuntu:14.04
MAINTAINER Larry Smith Jr. <[email protected]>
#Update apt-cache
RUN apt-get update
#Install pre-reqs for Ansible
RUN apt-get -y install git python-dev python-pip
#Install Ansible
RUN pip install ansible
#Copy Ansible tasks
COPY ansible_tasks /opt/ansible_tasks
#Install Ansible role(s)
RUN ansible-galaxy install -r /opt/ansible_tasks/requirements.yml
#Run Ansible playbook
RUN ansible-playbook -c local /opt/ansible_tasks/playbook.yml
#Clean-up packages
RUN apt-get -y clean && \
apt-get -y autoremove
#Clean-up temp files
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#Expose port(s)
EXPOSE 3306
#Process start-up
CMD ["/usr/bin/mysqld_safe"]
Now we can build our container..
docker build -t mysql-ansible .
Now if we do a standard Docker install without using Ansible using the below Dockerfile
FROM ubuntu:14.04
MAINTAINER Larry Smith Jr. <[email protected]>
#Update apt-cache
RUN apt-get update
#Install MySQL
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server
#Clean-up packages
RUN apt-get -y clean && \
apt-get -y autoremove
#Clean-up temp files
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#Expose port(s)
EXPOSE 3306
#Process start-up
CMD ["/usr/bin/mysqld_safe"]
And now build without Ansible.
docker build -t mysql .
And if we do a quick look at our Docker images to compare the differences in the image sizes…
vagrant@node-1:/vagrant/containers/mysql$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 26c155e1472e 4 seconds ago 339.4 MB
mysql-ansible latest 549207bd1f0e 14 minutes ago 636 MB
ubuntu 14.04 07c86167cdc4 3 hours ago 188 MB
As you can see there is quite a bit of bloat using Ansible but it may or may not be worth it. So YMMV.
So there you have it and hopefully you found this to be of some use. And I am very interested in your thoughts and perspecitves.
UPDATE: After posting this I thought I would see if there was a difference in the image size if I were to install Ansible via apt ppa instead. Being that I installed Ansible via pip in the previous comparison. So here are those results. (The image names are different than the above original but you can compare the image sizes to validate)
Using the following Dockerfile…
FROM ubuntu:14.04
MAINTAINER Larry Smith Jr. <[email protected]>
#Update apt-cache
RUN apt-get update
#Install pre-reqs for Ansible
RUN apt-get -y install git software-properties-common
#Adding Ansible ppa
RUN apt-add-repository ppa:ansible/ansible
#Update apt-cache
RUN apt-get update
#Install Ansible
RUN apt-get -y install ansible
#Copy Ansible tasks
COPY ansible_tasks /opt/ansible_tasks
#Install Ansible role(s)
RUN ansible-galaxy install -r /opt/ansible_tasks/requirements.yml
#Run Ansible playbook
RUN ansible-playbook -c local /opt/ansible_tasks/playbook.yml
#RUN pip uninstall ansible -y
#RUN apt-get -y purge git python-dev python-pip
#Clean-up packages
RUN apt-get -y clean && \
apt-get -y autoremove
#Clean-up temp files
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#Expose port(s)
EXPOSE 3306
#Process start-up
CMD ["/usr/bin/mysqld_safe"]
And now building…
docker build -t mysql-ansible-apt .
And below are the results…
vagrant@node-1:/vagrant/containers$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql-ansible-pip latest b7b7f93506c6 9 seconds ago 636 MB
mysql-ansible-apt latest f9e313ffc5fa 2 minutes ago 504.9 MB
mysql latest 9ac234dd93bf 4 minutes ago 339.4 MB
ubuntu 14.04 07c86167cdc4 3 hours ago 188 MB
And as you can see from above we indeed saved 132MB installing Ansible via apt using their ppa repository.
Enjoy!
Leave a comment