Today a common need is to build and push docker/OCI images in your CI/CD system. One of the primary issues users are facing when doing this is how to build images inside a container (Agola by default uses containers to execute run tasks). This usually requires using docker-in-docker and so privileged containers or bind mount the host docker socket. These choices can face some security issues or break the container isolation.
With Agola you can build and push docker/OCI images without breaking container isolation thanks to tools like kaniko
There’s an example repository here that contains a simple go program that will be built and put in a docker/OCI image.
Building the image
Let’s walk through the first run definition in this example (the agola configuration format used in this example is the
yaml format. But for more advanced definitions you could use the jsonnet format):
This run definition will build the go program and then create an image without pushing it.
This is a run made of two tasks, the first one will checkout the code and build the go binary. Then it’ll copy the binary and the
Dockerfile in the run workspace. The
build docker image task will execute kaniko and build the image.
build docker image task uses the official
gcr.io/kaniko-project/executor:debug image. The image with debug tag is used as it provides also a busybox shell (useful for debugging purposes). We have to override the default shell since in this image the busybox binaries are in the
/busybox/ directory. Kaniko by default expects the “docker context” inside
/workspace, so we’ll use the
working_dir task option to set it.
Building and Pushing the image
Usually building the image without pushing it to a registry isn’t very useful, so let’s see the changes needed to also push the image.
We just have to add few lines to the
build docker image task.
Kaniko documents some ways to authenticate to gcr and aws registries and its images already include a credential helper for amazon ecr. For more information refer to the kaniko doc.
For dockerhub or your own registry you should create a docker
config.json config file (inside
/kaniko/.docker/config.json) with the required auth data.
The environment variable
DOCKERAUTH is populated from a variable defined inside the Agola projectgroup/project, while, for this example, the
DOCKERREGISTRY_URL value is defined in the run definition.
As a note, thanks to the powerful Agola secrets/variables system, you are able to map different variables based on different conditions (branch, tag, pull request) so you can reuse the same run definition and use different registries and auths for your development branches, pull request, master branch or tags