OCI Images
The build and test templates use layered OCI/Docker images to provide the base environment. Currently, the project includes images based on Debian, which are suitable for building and testing across multiple architectures due to Debian’s extensive multi-architecture support.
Tip
You can use this template repository solely for building OCI images, independent of the provided build and test system templates.
Note
We aim to use a consistent Debian version across all architectures to ensure compatibility and reduce complexity. However, for some architectures, different Debian versions may be required due to varying support (e.g., older versions for EOL architectures or newer/unstable versions for newer and unofficial architectures).
Containerfile Structure
Image Layering
Templates are designed to allow layering of multiple Containerfiles. This modular approach enables customization, where each layer adds specific tools or configurations for different toolchains, with optional platform-specific adjustments.
To support image layering, the following image build arguments are used:
FROM_IMAGE_NAME: Name of the base image for the build.FROM_IMAGE_TAG: Tag of the base image for the build.
These are automatically set by the oci template during layered image
builds.
Platform Naming
Supported platforms follow this naming convention:
OS-TYPE-ARCH.
OS: Eitherlinuxorwindows.TYPE: Type of toolchain used for the build:native: Uses the toolchain from the base image.cross: Uses a cross-toolchain for the target platform.
ARCH: Target architecture, e.g.,amd64,arm64,riscv64.
This convention follows OCI platform naming, with addition of native and
cross used to indicate the type of the build environment, and uses a dash
instead of a slash to separate platform type from architecture.
Platform-specific Adjustments
Containerfiles use multi-stage builds for platform-specific adjustments. The
base OCI target provides a common foundation, which each platform can
extend with its own tools and configurations.
For example, Containerfile.base installs essential tools for all platforms and adds Wine only for Windows targets. Here is a snippet showing customization for different platforms:
ARG FROM_IMAGE_NAME
ARG FROM_IMAGE_TAG
FROM ${FROM_IMAGE_NAME}:${FROM_IMAGE_TAG} AS base
# Common for all targets.
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} package-used-by-all-platforms \
&& ${APT_CLEANUP}
# Targets without adjustments.
FROM base AS linux-native-386
FROM base AS linux-native-amd64
...
# Target with adjustment.
FROM base AS windows-cross-amd64
RUN ${APT_UPDATE} \
&& ${APT_INSTALL} windows-specific-dependency \
&& ${APT_CLEANUP}
Available Layers
Base
The base image, defined in Containerfile.base, serves as the foundation for
all other images. It includes essential tools for CI:
build-essential: Meta-package with tools for building software (GCC, Make, etc.).pkg-config: Manages compile and link flags for libraries, often needed but not included inbuild-essential.wineandmingwtoolchain for Windows targets: Enables running and testing Windows applications on Linux.
Additionally, the base image defines environment variables for use in subsequent layers:
APT_UPDATE: Updates package lists.APT_INSTALL: Installs packages with sane defaults.APT_CLEANUP: Cleans up APT cache to reduce image size.
LLVM
Containerfile.llvm extends the base image with the LLVM toolchain. It
includes Clang, LLVM tools (e.g., llvm-ar, llvm-strip), lld, and
libomp if supported. LLVM version is set to the latest available in Debian
repositories.
For Windows targets, it also installs a recent version of the LLVM-MinGW toolchain.
Meson
Containerfile.meson builds upon the base image (either Base or
Base with LLVM layer) and adds support for the Meson
build system. It installs Meson, Ninja, and Gcovr.
Meson and Gcovr are Python packages with outdated versions in Debian repositories, so they are installed via pipx for consistency for all layers.
Pre-built Images
This repository builds and pushes pre-built OCI images to the GitLab Container Registry.
Available images:
buildah: Base image with Buildah and QEMU, used by theocitemplate for multi-arch builds.debian/debootstrap: Used for building Debian images via debootstrap if the upstream image is unavailable for a given platform.debian/debian: Upstream Debian image (slim variant).debian/base: Based ondebian/debianwith the Base layer.debian/llvm: Based ondebian/basewith the LLVM layer.debian/llvm-meson: Based ondebian/llvmwith the Meson layer.debian/example: Composed of Base, LLVM, and Meson layers in a single build job for selected architectures, demonstratingocitemplate usage.
Each image tag consists of a branch indicator and platform. For the default
branch, the indicator is latest. For other branches, it is a sanitized
branch name. For example, debian/llvm-meson:latest-linux-native-amd64 is
the default branch image for the linux-native-amd64 platform.
Debian Images
Current platform support for Debian images:
Platform |
Debian |
GNU |
LLVM |
Meson |
Gcovr |
|---|---|---|---|---|---|
linux-cross-mips |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-386 |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-amd64 |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-arm-v5 |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-arm-v7 |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-arm64-v8 |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-mips64le |
Bookworm (12) |
12 |
19 |
1.8 |
7.2 |
linux-native-mipsel |
Bookworm (12) |
14 |
19 |
1.8 |
7.2 |
linux-native-ppc |
Sid (14) |
latest (15) |
19 |
1.8 |
7.2 |
linux-native-ppc64 |
Sid (14) |
latest (15) |
19 |
1.8 |
7.2 |
linux-native-ppc64le |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
linux-native-riscv64 |
Trixie (13) |
14 |
19 |
1.8 |
7.2 |
windows-cross-686 |
Trixie (13) |
14 |
20250709 |
1.8 |
7.2 |
windows-cross-amd64 |
Trixie (13) |
14 |
20250709 |
1.8 |
7.2 |
windows-cross-arm64-v8 |
Trixie (13) |
N/A |
20250709 |
1.8 |
7.2 |
Note
linux-native-mipsel, linux-native-ppc, and linux-native-ppc64
are built from Debian Ports as they have
no official OCI image builds.
Note
Windows Cross targets use MinGW GNU toolchain from official Debian repositories, and for LLVM pre-built binaries from LLVM MinGW.
OCI Image Build Template
The oci.yml template provides a workflow for building layered OCI container images. It uses Buildah for multi-arch images, leveraging QEMU for cross-architecture builds.
Inputs
The template accepts the following inputs:
Layering
from_image_name: Base OCI image name (e.g., one of the Pre-built Images images).from_image_tag_base: Base OCI image tag, without the target platform suffix. Default:latest.oci_context: The context for the OCI build. The default “.” means the top-level repository directory.containerfiles: Path to a Containerfile or multiple Containerfiles for stacking, separated by space (e.g.,Containerfile.base Containerfile.llvm) in theoci_contextdirectory. Default:Containerfile.
Image Configuration
image_registry: Registry for the built image. Default:$OCI_REGISTRY_IMAGE.image_name: Image name which will be pushed to theimage_registry. Default:$CI_PROJECT_NAME.image_tag_base: Default image tag, without the target suffix. Default:$OCI_TAG.
Target Configuration
image_target_tag_matrix: List of targets to build, as an array for the job matrix.Default:
- TARGET: - linux-cross-mips - linux-native-386 - linux-native-amd64 - windows-cross-686 - windows-cross-amd64 - linux-native-mips64le - linux-native-mipsel - linux-native-ppc - linux-native-ppc64 - linux-native-ppc64le - linux-native-riscv64 - linux-native-arm-v5 - linux-native-arm-v7 - linux-native-arm64-v8 - windows-cross-arm64-v8 RUNNER_TAG: ""
You can adjust this to include specific targets and set the CI runner tag for each group. For example, Freedesktop.org projects might use:
# Use fleeting runners if possible. - TARGET: - linux-cross-mips - linux-native-386 - linux-native-amd64 - windows-cross-686 - windows-cross-amd64 RUNNER_TAG: "" # Use QEMU-capable runners if no native runners are available. - TARGET: - linux-native-mips64le - linux-native-mipsel - linux-native-ppc - linux-native-ppc64 - linux-native-ppc64le - linux-native-riscv64 RUNNER_TAG: "kvm" # Use native aarch64 runners for ARM targets. - TARGET: - linux-native-arm-v5 - linux-native-arm-v7 - linux-native-arm64-v8 - windows-cross-arm64-v8 RUNNER_TAG: "aarch64"
image_target_env_dir: Base path for target environments. Each target should have a file named${TARGET}.env. Default:.gitlab-ci.d/oci/target-env.This allows you to define target-specific environment variables, passed as build arguments. Not all targets require a file.
image_target_platform_map: Maps target platforms to their OCI platform string for multi-arch builds. Default:linux-cross-mips linux/amd64 linux-native-386 linux/386 linux-native-amd64 linux/amd64 linux-native-arm-v5 linux/arm/v5 linux-native-arm-v7 linux/arm/v7 linux-native-arm64-v8 linux/arm64/v8 linux-native-mips64le linux/mips64le linux-native-mipsel linux/mipsel linux-native-ppc linux/ppc linux-native-ppc64 linux/ppc64 linux-native-ppc64le linux/ppc64le linux-native-riscv64 linux/riscv64 windows-cross-686 linux/amd64 windows-cross-amd64 linux/amd64 windows-cross-arm64-v8 linux/arm64/v8
Usually, you do not need to change this. To add a new target, add it here in the format
<target> <platform>, where<target>matchesimage_target_tag_matrixand<platform>is the OCI platform string.
CI Job and Builder
buildah_image_name: Buildah image name, used by the GitLab runner to build the image. If the default value is left, it uses instance-specific image from ci-multiplatform mirror. Default:""".buildah_image_tag: Buildah image tag. Default:latest.cache_image_name: Name of the image used for caching layers in theimage_registry. Default:cache.extends: Array of jobs to extend this job template. Can include target activation rules, e.g.:.ci-multiplatform-base: rules: - if: "$TARGET =~ $ACTIVE_TARGET_PATTERN"
Default:
[.ci-multiplatform-base]. See Top-level Requirements for details.job_name_prefix: Prefix for the job name. Useful for disabling or customizing jobs. Default:"".job_name_suffix: Suffix for the job name. Useful for distinguishing multipleocitemplate instances. Default:"".needs: Array of jobs that must run before this job. Useful for chained builds. Default:[].retry: Job retry count, helpful for intermittent issues on GitLab.com runners. Default:2.stage: CI stage name for the job. Default:oci.
Image labels
When the image is built with the OCI template, the following OCI image labels are applied:
Image Label |
Value |
|
|
|
|
|
|
|
|
|
|
<prefix> is fdo for jobs run on Freedesktop.org, and gitlab-ci
otherwise. This is to use similar labeling convention as ci-templates on FDO.
For the values starting with CI_, see the GitLab
environment variables documentation
Example Usage
For basic usage without a full build/test/summarize flow, see OCI Build Example. For more advanced usage, using the Meson flow, see Meson Project Example.
This template is used in this repository to build the example image
(debian/example), which includes the base, LLVM, and Meson layers. It is
included in .gitlab-ci.d/oci/debian/debian.yml as the final include.
You can also create a wrapper template that encapsulates the oci component,
allowing you to apply project-specific customizations and simplify reuse. For
instance, the .gitlab-ci.d/oci/debian/debian-layer.yml template demonstrates
how to instantiate the oci template to build the various debian image
layers.
Another example is in the Pixman project, where it builds a customized image based on the Meson pre-built image.