Ansible-container is surely one of the most customizable way to assemble docker images for any purpose.
If you are an Ansible fan like me you know well an ssh connection is the only prerequisite to run ansible tasks across your servers.
But since docker containers run process and not whole machines the sshd daemon is almost always absent into images and manage them with ansible direcly can be a real pain.
Ansible-contrainer aims to avoid such pain, providing an orchestration container which will run your roles within the docker engine, using the shared docker engine connection in replacement to ssh to communicate with your final image instance.
The process is full ansible-driven so it totally replaces the Dockerfile logic and provide a wrapper for Docker-Compose configuration.
You can find all information at the documentation page.
The other side of the coin of a missing Dockerfile is that may online applications expect it to work properly, so publication to Docker Hub could be not straightforward.
In this article I will describe a very quick way to use a Travis-CI build linked to your GitHub account to automatically publish your build images.
As you can imagine you will need an account on all the three tools and proper access grant to Travis to retrieve github source code.
Simply commit your ansible-container project on github and add a .travis.yml file in the root folder to automatically trigger travis build upon each push.
Then we have to declare our build language (It’s an ansible container build so we’ll user python as base container)
--- language: python python: "2.7"
Next step is to install all the tools we’ll need to perform our build, which means ansible-container.
Since I’m quite accustomed to my favorite-working Ansible version I also want to be sure it will come in the proper release so I’ll force it:
before_install: - sudo apt-get update -qq install: - pip install ansible==184.108.40.206 ansible-container==0.2.0
Since the above will download always the same package and I do not want to waste time, I’ll add also a little cache for pip process:
cache: directories: - $HOME/.cache/pip
Now we have to enable docker service within our build process:
services: - docker
Et-voilà, we are ready to perform our ansible-container build!
script: - ansible-container --var-file ansible/roles/myrole/vars/main.yml build --from-scratch
One of the best part of this approach is that being Travis a AWS-based cloud tool, time for downloading docker base image and ansible-container image will take just few seconds (much much better than my home ADSL 🙂 )
You can see below a sample run from our build from the post Package Apache 2.4.x RPMs via Docker and Ansible-container
Almost done now, we just have to upload our docker image to DockerHub using our credentials.
Since we do not want to publish any branch of our project, we’ll add a small check to be sure what only the master branch will be promoted to the Hub.
Basically we will login to the service, tag our ansible-cointainer-named image with DockerHub naming and then push it.
after_success: - if [ "$TRAVIS_BRANCH" == "master" ]; then docker login -u="$DOCKERHUB_NAME" -p="$DOCKERHUB_PASS"; docker tag PROJECTNAME-SERVICENAME:latest DHACCOUNT/IMAGENAME:IMAGETAG; docker push DHACCOUNT/IMAGENAME:IMAGETAG; fi
$DOCKERHUB_NAME and $DOCKERHUB_PASS are two environment variable set in travis to store Docker Hub credential outside our travis.yml file (which is on a public github repository, do you remember? ). Remember to check that their value is NOT shown into the build log.
You can also use encrypted values if you prefer.
PROJECTNAME-SERVICENAME:latest is the name of the output image of your ansible-container build, replace it in your file with the proper values from your setting.
DHACCOUNT/IMAGENAME:IMAGETAG is the typical naming convention of a DockerHub Image to be pushed, your account first, then the image name and finally the tag. Also this one has to be declared into the file with the real values.
Now everything is in place: every time a new commit will be pushed to your github repo, TravisCi will take care to run a new ansible-container build to re-create the ouput image.
Only if the push occurs on the master branch travis will also push the resulting image to your DockerHub account.