How to build Docker images in GitLab CI

In this article, I'll show you how to build Docker images in GitLab & push them to the container registry provided by the platform.

The Docker file

Simple file, where I set non-root user for the node image. Dockerfile:

FROM node:16.5.0

USER node

In Docker Hub images, it's a convention to leave them on the root user. Some npm features are turned off for root, so it's better to run our builds on a different user.

GitLab CI file

Inside .gitlab-ci.yml goes as follow:

stages:
  - build

Defining stages. In our simple example, we are fine with only 1 stage.

docker-image:
  stage: build

Creating the docker-image job & setting it to build stage

image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]

A Google tool for creating images. It's supposed to support standard Dockerfiles, and so far, with 5~8 images, I found no issues that would be specific to kaniko only. There is a Docker image for building images, but it's a bit of a hassle to set up inside Docker. You need to configure docker-in-docker, and I found it simpler to use kaniko.

entrypoint: [""] overrides the entry point of the image. I found it while setting up this thing myself, and indeed if I remove this line the build fails

script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
  • mkdir -p /kaniko/.docker - creates a folder from where kaniko reads access file
  • echo ... - puts the GitLab registry access info to file that will be read by kaniko. Note! Those values are provided by GitLab, you don't have to set up credentials yourself.
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE

We build the files & push the image to the registry. If you want to build multiple images in the repository, you can replace --destination $CI_REGISTRY_IMAGE with --destination $CI_REGISTRY_IMAGE/image-name - in this way you can fit multiple images next to each other.

Complete config

.gitlab-ci.yml:

stages:
  - build

docker-image:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE

Working build

If we configured everything correctly, the build will be running:

And when it's finished an image will be added to the container registry:

References

Here you can find the example repository & container registry.

Summary

In this article, we have seen a simple example of how to build images in GitLab. If you want to build more images, you can always add more /kaniko/executor calls with other files.

28