Building Docker images on Travis.ci
Inspired by the posts from Viktor Adam's blog, when I have some spare time I have been playing with Docker and some open source tools to build this blog.
So far I have my two little devices a Raspberry Pi and a Rock64 hosting this blog, yes, that's right, you're reading this straight from a Ghost blog behind an NGinx hosted at my home, be nice and say hi!
Appart of some details like sensible public data management and external CI usage to generate and publish Docker images
that is the subject of this post, this is how my stack looks like right now. It will evolve soonish :]
Sensible public data
As we can see from the description of this repo of mine on Docker hub, some environment variables are expected as parameters to create containers. Some sensible data like Cloudflare API key goes to a public repository on Github, the
.env file in binary form instead of row text.
I could keep it somewhere on my local file system and use it to create containers but if I've learned something from past events is, maintaining files on my machine is the same of losing them sooner or later so, better to have them on the cloud where smarter people than me are taking care of backups.
However, how to keep this kind of data safe in a public space? For git repositories, a good option is to use Git Crypt.
First, install it, following this guide.
Once you have installed it you need a key to
unlock the files you want, there are two options, the
Symmetric Mode where you export a key and refer it to unlock your files and
GPG Mode where you create a key and import the public key wherever you need to unlock files. I have decided to use
Symmetric Mode, this time "after few disappointments with the GPG Mode". The setup is easy and does not require further steps after exporting the key.
Setting up git-crypt and exporting a symmetric secret key
Now on the git repository initiate,
git-crypt like with a regular
git init and export your symmetric key.
git-crypt init git-crypt export-key /lab/security/git-cript-key
Now we need to create the
.gitattributes at the root of the project and list the files to be encrypted, the syntax is the same used with
*.env filter=git-crypt diff=git-crypt
From this point
.env will be automatically encrypted before being pushed to the repository. To unlock it in different machines, we need to run
git-crypt unlock referring the secret key that we have just exported, in my case
git-crypt unlock /lab/security/git-crypt-key
If the intention is to unlock this files somewhere else, is necessary to have access to this key from this other place too, the process is the same, unlock the files with the same command above.
Setting up a Trevis.ci account
At this point, we probably have something like that on your GitHub. The next step is to build images and publish them automatically when updating the repository.
Using a GitHub account, Sign Up to Trevis.ci and enable the integration for this repo.
Setting up the .travis.yml file
To tell Travis what to do, we need a
.travis file at the repository root, to learn about it here to create one that works for you. Mine looks like that:
sudo: required services: - docker script: # setup QEMU - docker run --rm --privileged multiarch/qemu-user-static:register --reset # build images - docker build -t ddns:$DOCKER_TAG -f Dockerfile.$DOCKER_ARCH . # push images - docker login -u="$DOCKER_HUB_LOGIN" -p="$DOCKER_HUB_PASSWORD" - docker tag ddns:$DOCKER_TAG allandequeiroz/cloudflare-ddns:$DOCKER_TAG - docker push allandequeiroz/cloudflare-ddns:$DOCKER_TAG - > if [ "$LATEST" == "true" ]; then docker tag ddns:$DOCKER_TAG allandequeiroz/cloudflare-ddns:latest docker push allandequeiroz/cloudflare-ddns:latest fi env: matrix: - DOCKER_TAG=arm DOCKER_ARCH=arm LATEST=true - DOCKER_TAG=amd64 DOCKER_ARCH=amd64
The environment uses a Raspberry Pi and Rock64, so is necessary to build images for
arm architecture, and in case someone needs it in for an
amd architecture, let's generate an
amd one too, for a good karma sake.
You can ask
Travis to do that defining the
matrix section, this way the
script part will be executed once for each line of the
matrix, in this case, every time I push something new to GitHub, two new images will be generated and pushed to Docker hub.
Another interesting detail here is the ability to define environment variables, so we can push images to docker hub for example, without exposing credentials
docker login -u="$DOCKER_HUB_LOGIN" -p="$DOCKER_HUB_PASSWORD"
Travis provides a
settings interface where you can define environment variables and use them instead of keeping it public on your repository.
Right. Now we need to push something new to the repository or Trigger the build from
More options on Travis interface, by the end we have our images ready to be pulled from Docker hub.
After all this effort we deserve some badges, we can get them straight from the
Travis account, just point to the
.svg file related to that build. Travis update it after each build so take care not to break the build :)
To have some badges from your Docker hub account you can use Microbadger, once again Sign Up using your GitHub account and link it to your Docker Hub account, after few seconds you'll have some badges waiting for you, in this case,
version the architecture and
layers amount of layers of your image.
Showing off the badges
In the end, we can use something like the lines below to display badges on the
[![Travis](https://api.travis-ci.org/allandequeiroz/cloudflare-ddns.svg)](https://travis-ci.org/allandequeiroz/cloudflare-ddns) [!(https://images.microbadger.com/badges/version/allandequeiroz/cloudflare-ddns.svg)](https://microbadger.com/images/allandequeiroz/cloudflare-ddns "Get your own version badge on microbadger.com") [!(https://images.microbadger.com/badges/image/allandequeiroz/cloudflare-ddns.svg)](https://microbadger.com/images/allandequeiroz/cloudflare-ddns "Get your own image badge on microbadger.com") [!(https://images.microbadger.com/badges/version/allandequeiroz/cloudflare-ddns:amd64.svg)](https://microbadger.com/images/allandequeiroz/cloudflare-ddns:amd64 "Get your own version badge on microbadger.com") [!(https://images.microbadger.com/badges/image/allandequeiroz/cloudflare-ddns:amd64.svg)](https://microbadger.com/images/allandequeiroz/cloudflare-ddns:amd64 "Get your own image badge on microbadger.com")