How to build Docker images in GitLab CI
Tags: gitlab, ci, docker
Published: 2021-07-27 07:17:23

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:

```yml
stages:
  - build
```
Defining stages. In our simple example, we are fine with only 1 stage.


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


```yml
  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](https://gitlab.com/marcin-wosinek/building-image-example/-/jobs/1454459626)

```yml
  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.

```yml
    - /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`:
```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:

![running-build.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hm1a1wyrem3e8qubuza6.png)

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

![registry.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/098v6nqpow3jlkp4wwim.png)

# References
Here you can find the example [repository](https://gitlab.com/marcin-wosinek/building-image-example/-/tree/main) & [container registry](https://gitlab.com/marcin-wosinek/building-image-example/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.