GitLab allows you to use any Docker image to run your CI jobs. Sometimes you'll want to create your own Docker image, store it in the GitLab container registry and use the.

In this article we'll review a GitLab CI job that creates the image and pushes it out to the container registry.

We are going to go over the GitLab CI config YAML file that was taken from the Perl builder project of Ioan Rogers and that you can find at the bottom of this page. Although this specific project creates a Docker image to test Perl code, the idea can be used for any programming language.

First of all you might wonder why do we need to create an image, why not just use a base image and install everything during the CI process. The primary reason is speed. Many time you need lots of prerequisites to run some applications. Doing that on every run of the CI system would be a lot of waste of time and resources. By creating an image that already has many of the packages installed we can save time, money, and get feedback much faster.

The repository has two files in it. The build.sh shell file that builds a docker image using Buildah and the .gitlab-ci.yml file we are discussing now.

It has two jobs: buildah-build-master will run on the mater branch and buildah-build on all the other branches. These are controlled by the only and except keywords. As the documentation suggest in improved way would be to use the rules syntax.

The difference

As I can see the only difference between the two is that the job on the master branch also adds the latest tag to the created image.

The common part

They both use the buildah Docker image from quay.io, the Docker repository of Red Hat.

The name of the stage, does not really matter.

In the before_script part, that surprisingly happens before the script part both jobs authenticate with the Docker repository. The environment variables $CI_REGISTRY_USER, $CI_REGISTRY_PASSWORD, and $CI_REGISTRY are all predefined variables provided by GitLab.

So are the variables $CI_REGISTRY_IMAGE and $CI_COMMIT_REF_SLUG used in the other commands.

After going over it, this isn't a complex pipeline after all.

examples/perl-builder/.gitlab-ci.yml

buildah-build-master:
  image: quay.io/buildah/stable:latest
  stage: build
  before_script:
    - buildah login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - ./build.sh
    - buildah tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" "$CI_REGISTRY_IMAGE:latest"
    - buildah push "$CI_REGISTRY_IMAGE:latest"
  only:
    - master

buildah-build:
  image: quay.io/buildah/stable:latest
  stage: build
  before_script:
    - buildah login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  script:
    - ./build.sh
    - buildah push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
  except:
    - master