Multi-arch build, what about Travis?

Jeremie Drouet

Jul 08 2020

Following the previous article where we saw how to build multi arch images using GitHub Actions, we will now show how to do the same thing using another CI. In this article, we’ll consider Travis, which is one of the most tricky ones to use for this use case.

To start building your image with Travis, you will first need to create .travis.yml file at the root of your repository.

languagebash
distbionic
services:
  - docker
script:
  - docker version

You may notice that we specified using “bionic” to have the latest version of Ubuntu available – Ubuntu 18.04 (Bionic Beaver). As of today (May 2020), if you run this script, you’ll be able to see that the Docker Engine version it provides is 18.06.0-ce which is too old to be able to use buildx. So we’ll have to install Docker manually.

language: bash
distbionic
before_install:
  - sudo rm -rf /var/lib/apt/lists/*
  - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  - sudo add-apt-repository "deb [arch=amd64] 
https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge"
  - sudo apt-get update
  - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
script:
  - docker version

As you can see in the previous script, the installation process requires adding new keys in order to be able to synchronize the package database and download new packages from the Docker APT repository. We can then install the latest version of Docker available for Ubuntu 18.04. Once you have run this, you can see that we now have the version 19.03 of the Docker Engine.

At this point we are able to interact with the Docker CLI but we don’t yet have the buildx plugin installed. To install it, we will download it from GitHub.

language: bash
dist: bionic
before_install:
  - sudo rm -rf /var/lib/apt/lists/*
  - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) edge"
  - sudo apt-get update
  - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
  - mkdir -vp ~/.docker/cli-plugins/
  - curl --silent -L "https://github.com/docker/buildx/releases/download/v0.3.0/buildx-v0.3.0.linux-amd64" > ~/.docker/cli-plugins/docker-buildx
  - chmod a+x ~/.docker/cli-plugins/docker-buildx
script:
  - docker buildx version

We are now able to use buildx. It’s verbose and because of how Travis works and the versions it’s based on, we won’t be able to shorten that by using a Docker image like on CircleCI. We’ll have to keep this big boilerplate at the top of our script and allow it to take about 1.5min of build, each time you run the build.

Now it’s time to build our image for multiple architectures. We’ll use the same Dockerfile that we used for the previous article and the same build command:

FROM debian:buster-slim
RUN apt-get update \
  && apt-get install -y curl \
  && rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl" ]

Modify the Travis configuration file to have the following in the `script` section:

script:
  - docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag your-username/multiarch-example:buildx-latest .

If you launch it like this, you will see the following error:

multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")

This is due to the fact that there is no buildkit driver already started. So, if we add that line to our configuration file and run it again, this will allow buildx to have an instance of a buildkit running to build the multiarch images.

Navigating to the Travis dashboard, you should see the following result:

The last step is now to store the image on the Docker Hub. To do so we’ll need an access token from Docker Hub to get write access.

Once you created an access token, you’ll have to add it to your project settings in the “Settings” section.

We can then create DOCKER_USERNAME and DOCKER_PASSWORD variables to login afterward.

Once this is done, you can add the login step and the --push option to the buildx command as follows.

script:
  - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"
  - docker buildx create --use
  - docker buildx build --push --platform
linux/arm/v7,linux/arm64/v8,linux/amd64 --tag
your-username/multiarch-example:buildx-latest .

And voila, you can now create a multi arch image each time you make a change in your codebase.