Building Docker images on Travis.ci

Hello!

Inspired by the posts from Viktor Adam's blog, when I have some spare time I've 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 a NGinx hosted at my home, be nice and say hi!

Allan's home devices

Appart of some details like sensible public data management and external CI usage to generate and publish Docker images that in fact are the subject of this post, this is how my stack looks like right now. It will evolve soonish :]

Initial home stack

Sensible public data

As you can see from the description of this repo of mine on Docker hub, some environment variables are expected as parameters to create containers. I do use it myself so sensible data like my Cloudflare API key is stored on my public repository on Github, the .env file.

I could keep it somewhere on my local file system and use it to create containers but if history told me something is, keeping something locally is losing it sooner or later so, better to keep in the cloud where smarter people than me are taking care of backups and things like that.

But how to keep this kind of data safe in public space? If you're using git a good option is to use Git Crypt.

Git Crypt

First, install it, just follow this small guide.

Once you have installed it you need a key to lock and 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've decided to use Symmetric Mode, the setup is easy and do not require further steps after you export your key, just use it.

Setting up git-crypt and exporting a symmetric secret key

As you can see in the documentation a few steps you will have your brand new GPG Key.

Now on your git repository just initiate git-crypt like you do with git and include your user "GPG Public key" to the user's list.

You can use any reference you've provided to create the key, in this case, I'll use the e-mail address

To accomplish this task you only need to simple steps as you can see below, first you initialize git-crypt then you export your symmetric secret key.

git-crypt init
git-crypt export-key /lab/security/git-cript-key

Now you need to create the .gitattributes at the root of your project and list the files you want to encrypt, the syntax is the same used by .gitignore files. Eg: *.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, you just need to run git-crypt unlock referring the secret key that you've just exported, in my case git-crypt unlock /lab/security/git-crypt-key

If you have the intention to unlock this files somewhere else, you need to have access to this key there too, the process is just the same, unlock the files with the same command above.

Setting up a Trevis.ci account

At this point, you probably have something like that on your GitHub. The next step is to build your images and publish them automatically when you update your repository.

Using your 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, you need a .travis file on your repository, you can 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

Since I'm using Raspberry Pi and Rock64 I need to build images for arm architecture and since I want to be nice to people I'm generating amd ones even that they are useless for me.

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, as you may notice my Docker hub credentials to push images: 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.

Ok. Now you just need to push something new to your repository or Trigger the build from More options on Travis interface, by the end you'll see something like that on Travis and your images will be available on Docker hub.

Travis badges

After all this effort you deserve some badges, you can get one straight from your Travis account, just ask for the .svg file related to your repository. It is updated after each build so take care to not break it :)

https://api.travis-ci.org/allandequeiroz/cloudflare-ddns.svg

Microbadger badges

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.

https://images.microbadger.com/badges/version/allandequeiroz/cloudflare-ddns.svg
https://images.microbadger.com/badges/image/allandequeiroz/cloudflare-ddns.svg

Showing off your badges

In the end, you can use something like the lines below to display your badges on your README.md files anywhere.

[![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")

Travis

comments powered by Disqus