Another way of reducing installation time and bandwidth is to use/create container builder images which come pre-installed with the toolchain. I’m often using the official gcc images as a base and then install additional software on top.
Builder Images for C++
The builder image is rebuilt on-demand (or with a CI/CD schedule on a regular basis).
On GitLab.com SaaS, including the Docker template builds the image and tags the latest version in the container registry from where it can be used in .gitlab-ci.yml job configuration.
include:
- template: Docker.gitlab-ci.yml
An example exercise is in
A builder image based on your request
In your example, the before_script
apt-get commands need to be moved into the Dockerfile like this:
# https://hub.docker.com/_/gcc
FROM gcc:11.2
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y cmake build-essential mesa-common-dev cppcheck g++ ninja-build gcc-arm-none-eabi gcc && rm -rf /var/lib/apt/lists/*
CMD ["cmake"]
Note that the FROM
section pins the GCC version to 11.2. That way you can ensure that you build with a specific compiler version, and only bump the version when you are confident to move. Allows for more reproducible builds, in comparison to :latest
potentially breaking your builds and you search endless hours until finding that it is the compiler version and not the code which worked last week.
When the image is spawned as container, the script
section fires the first command and overwrites CMD
. You can use the container for local dev environments too. More tips on Docker image optimization in Pipeline efficiency | GitLab
In your .gitlab-ci.yml file, you’ll add the following job. On self-managed GitLab, you’ll need DinD to build the container images. Use Docker to build Docker images | GitLab
include:
- template: 'Docker.gitlab-ci.yml'
# Change Docker build to manual non-blocking
docker-build:
rules:
- if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
when: manual
allow_failure: true
Manually trigger the pipeline job to build and push the builder image.
Navigate into Package & Registries > Container Registry
to extract the container image path.
In your build jobs, you’ll add the image: registry.gitlab.com/namespace/project
line, or change it globally in .gitlab-ci.yml Note: On self-managed GitLab, the container registry must be enabled, and the registry path needs to be changed accordingly. GitLab Container Registry | GitLab
Conclusion
Builder images are a great way to reduce the traffic and CI/CD time. There are things to keep in mind though:
- Consider creating a dedicated project and group namespace for all builder image, with documentation on the purpose, security, update frequency, etc.
- Consider adding container scanning to the images being used in the CI/CD pipelines. Container Scanning | GitLab
- Document and schedule maintenance for updating the builder images. Security flaws and regression may come from static-never-updated builder images.