# Arch Linux OCI images: rolling packages in a container, and the price of the key

> The Arch Linux container images are built daily by a GitLab CI pipeline that assembles a root filesystem archive and packages it into an OCI layer, with four variants and cosign verification for all but the DockerHub library image. They are the right base for an Arch-specific build pipeline, and a poor choice for a reproducible production runtime because the packages keep moving.

**archlinux/archlinux-docker** — Docker Base Image for Arch Linux (read-only mirror)

- Repository: https://github.com/archlinux/archlinux-docker
- Website: https://gitlab.archlinux.org/archlinux/archlinux-docker
- Stars: 546 · Forks: 92
- Language: Shell
- License: GPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/archlinux-archlinux-docker

## Why an Arch image at all, and who pulls it

Arch Linux is a rolling release distribution with a minimal base and a current-set package repository, which makes it attractive as a build environment and an awkward choice as a production runtime. The container images exist to bridge that gap, and the project description names them plainly: a Docker base image for Arch Linux.

The images are published in four places, and the difference between them is a cadence question as much as a location question. The official DockerHub library image is updated weekly, and the project's own DockerHub repository, its quay.io repository and its ghcr.io repository are updated daily. The README gives the pull commands for each, and both `podman pull` and `docker pull` are given for every registry, which tells you the images are built with podman and are registry agnostic.

The target user is a platform team or CI system that needs an Arch environment for a build. The README is explicit that the images are regularly kept up to date but strongly recommends running `pacman -Syu` right after starting a container, because of the rolling release nature of Arch Linux. That single sentence is the most important operational fact on the page, and it is why the images are a poor base for anything that needs to be identical next month.

There are no GitHub releases for this repository. The versioning lives in the image tags instead.

## Four variants and the sizes they cost

The README describes four versions of the image, each built around a corresponding meta package, and gives approximate sizes.

`base` is the smallest at roughly 150 MiB and carries the `base` meta package. `base-devel` is roughly 260 MiB and adds the compiler toolchain, which is what you need if the container is going to build something. `multilib-devel` is around 300 MiB and contains the multilib meta package for 32-bit library support on a 64-bit system.

The fourth is `repro`, described as a bit for bit reproducible version of the `base` image. Reproducibility here is a deliberate design decision with a cost attached: to guarantee it, the pacman keys are stripped from the image, so you are expected to run `pacman-key --init && pacman-key --populate archlinux` before you can update the system or install packages with `pacman`. Reproducible and immediately usable are in direct conflict, and the project chose reproducibility for this variant.

All four are available as tags, with `latest` pointing to `base`. That detail catches people out, because pulling `latest` gives you the minimal image rather than a development environment. For anything requiring a compiler, the tag has to be `base-devel`.

The images are also tagged with their date and build job number, in a form like `base-devel-20201118.0.9436`. That naming is what makes it possible to pin a specific build rather than a moving tag, which is the mitigation for the rolling package problem.

Note the `repro` variant is the exception to the general rule that `pacman` works out of the box, which the project lists among its principles and describes as being worked on under technical constraints.

## Stripping the pacman lsign key, and why that is the right call

The principles section of the README says that `pacman` needs to work out of the box, with the exception of the `repro` image, and that all installed packages have to be kept unmodified.

Then there is a separate note about security, marked with warning characters, explaining that for security reasons the images strip the pacman lsign key. The reasoning given is specific: the same key would otherwise be spread to all containers of the same image, which would allow malicious actors to inject packages, for example through a man-in-the-middle. The instruction is to run `pacman-key --init` on first execution and to be careful not to redistribute that key.

This is a good example of a container base image making a security decision on your behalf, and it has a direct consequence for how you use these images. Every container that inherits the shared layer shares the same signing key, so a signature that verifies in one container verifies for everyone running that image. Initialising a per-container keyring breaks that link, at the cost of one setup command per container and a slightly different keyring state from a native Arch install.

The project keeps the package contents unmodified, which is the other half of the design. You get upstream Arch packages as upstream shipped them, packaged in an image, rather than a curated variant.

For the `repro` image, the key stripping is not a security measure but a reproducibility requirement, and the two cases should not be conflated when you read the notes.

## Verifying images with cosign before you pull them into CI

All the images except the official DockerHub library image are signed using cosign's keyless signing, and the README gives a verification command for each of the three signed registries.

For example, to check the daily image on quay.io:

```sh
$ cosign verify quay.io/archlinux/archlinux:latest --certificate-identity-regexp="https://gitlab\.archlinux\.org/archlinux/archlinux-docker//\.gitlab-ci\.yml@refs/tags/v[0-9]+\.0\.[0-9]+" --certificate-oidc-issuer=https://gitlab.archlinux.org
```

The same shape works for the DockerHub and ghcr.io images, and the README lists all three so you can pick the one matching the registry you use.

What the command actually asserts is worth reading. The certificate identity is matched against a regular expression pinning the GitLab CI pipeline file at a tag of the form `v[0-9]+.0.[0-9]+`, and the OIDC issuer is pinned to `https://gitlab.archlinux.org`. So the check is not just that some signature exists, it is that the signature was produced by a specific pipeline in the Arch Linux GitLab instance. That is the meaningful part, because keyless signing means there is no static key to compare against.

The gap to plan for is the official DockerHub library image, which is not signed. If your supply chain policy requires signature verification for every base image, the weekly library image does not meet it and you need one of the daily repositories instead. That is a real reason to prefer `docker.io/archlinux/archlinux:latest` over `docker.io/library/archlinux:latest`.

## How the daily pipeline actually builds an image

The pipeline section describes a GitLab CI setup on the project's own runner infrastructure, and the build is a two stage process that is worth understanding before you build your own.

First, root filesystem archives are constructed and provided in the project's package registry. Then the released multi-stage Dockerfile downloads those archives and verifies their integrity before unpacking them into an OCI image layer. Images are built using podman, which also publishes them to the external repositories.

That split has a practical advantage. The expensive and awkward part, constructing a root filesystem with the right packages and the right pacman configuration, happens once and is stored as an archive. The Dockerfile stage is then a download, a checksum check and an unpack, which is fast and easy to reproduce. It also means the integrity verification of the archive is a build step you can read in the Dockerfile rather than a property you have to trust.

The weekly release to the official DockerHub library uses the same pipeline, with updates delivered as automatic pull requests to the official-images library, whose own GitHub pipeline builds the images from the provided rootfs archives and Dockerfiles.

Development builds work the same way. Changes in Git feature branches are built and tested using the same pipeline, and the development images are uploaded to the GitLab Container Registry.

The repository files back this up. The top level contains `.gitlab-ci.yml`, a `Dockerfile.template`, a `docker-library.template`, a `rootfs/` directory, a `scripts/` directory, `pacman-conf.d-noextract.conf`, `renovate.json`, a `sigstore-param-file.yaml` for the signing configuration, `REPRO.md` and a `Makefile`.

## Building the images yourself with make targets

The repository contains everything needed to create an OCI image for Arch Linux, and the documented entry point is make.

The dependencies are Arch packages: `make`, `devtools` for the pacman.conf files, `git` to fetch the commit or revision number, `podman`, `fakechroot` and `fakeroot`. The README also says to make sure your user can directly interact with podman, which it phrases as making sure `podman info` works.

Usage is a set of `make image-XXX` targets, each creating the corresponding `archlinux:XXX` image based on the corresponding meta package, and the targets currently include `base`, `base-devel`, `multilib-devel` and `repro`. The `Makefile` confirms the set with a default goal that chains all four:

```sh
all: image-base image-base-devel image-multilib-devel image-repro
```

and the generic rule that each one follows:

```sh
image-%: $(OUTPUTDIR)/Dockerfile.%
	${OCITOOL} build -f $(OUTPUTDIR)/Dockerfile.$(*) -t archlinux/archlinux:$(*) $(OUTPUTDIR)
```

The `OCITOOL` variable is set to podman with a comment noting it can be docker, so a docker-based workflow works by changing that one value. The `Makefile` also pins the timezone to UTC and defines `ARCHIVE_SNAPSHOT` as the previous day in UTC and a `SOURCE_DATE_EPOCH` at midnight, both of which feed the rootfs and Dockerfile generation scripts.

Reproducing a `repro` image locally has its own instructions in `REPRO.md`, referenced from the README.

One maintenance chore is documented that is easy to miss. Every year in June, the protected `GITLAB_PROJECT_TOKEN` variable needs to be replaced, with a new access token carrying `api` and `write_repository` scope and the `Maintainer` role, creating a bot user that then needs access to the protected `releases` branch. An expired token is the kind of thing that stops daily builds without any obvious symptom.

## Licence, and what the image is not

The project is licensed GPL-3.0, with a `LICENSE` file at the top level of the tree. The licence covers the build scripts and templates in this repository. The licence status of the Arch Linux packages that end up inside the image is a separate question governed by those packages themselves, since the project states that all installed packages are kept unmodified. This is a description of the terms as stated, not legal advice.

The other thing worth being clear about is what these images are not. They are not a pinned, immutable runtime. They are not a minimal security-hardened base, since they carry a full package manager and a keyring mechanism. And they are not a substitute for a real Arch installation in a build pipeline that expects a stable base.

The alternative approach is worth naming, because the difference is about where reproducibility comes from. A distribution that does not move, with dated image tags and a fixed package set, gives you the same result on the same commit for reasons that have nothing to do with your build system. Arch gives you current packages and a rolling security model, which is a different property. Where the build is the thing you care about, a dated `base-devel-20201118.0.9436` tag is the mechanism to use, and it is easy to miss because the `latest` tag exists and points at `base`.

If your requirement is that the container is bit for bit identical when rebuilt later, the `repro` variant is the one the project built for that, and it carries the keyring setup cost described earlier.

## Conclusion

Use these images when the build has to happen on Arch specifically, when a `base-devel` environment with the toolchain you need is the point, or when you want the pacman keyring to be per container rather than baked into a shared layer. Do not use them for a long-lived production runtime that is expected to be reproducible, because the packages are rolling and the `repro` variant is the only one that is bit for bit reproducible, and it needs its own pacman key initialised. Before you build on them, read the `Makefile` and `scripts/` directory to understand what `make image-XXX` does on your machine, check that your user can run `podman info`, and confirm the cosign verification command works against the registry you actually pull from, since the official DockerHub library image is not signed.

## FAQ

### How do I pull the Arch Linux container image?

The official DockerHub library image is updated weekly and is pulled with `docker pull archlinux:latest`, while the project's own DockerHub, quay.io and ghcr.io repositories are updated daily and are pulled with `docker pull archlinux/archlinux:latest` or the equivalent podman command. The `latest` tag points to the `base` image in all cases.

### What is the difference between the base, base-devel, multilib-devel and repro images?

The first three are built around the corresponding meta package and are approximately 150 MiB, 260 MiB and 300 MiB respectively, with `base-devel` adding the compiler toolchain and `multilib-devel` adding 32-bit library support. The `repro` image is a bit for bit reproducible version of `base`, and its pacman keys are stripped so you must initialise them before using pacman.

### Why do the Arch Linux images strip the pacman lsign key?

The project explains that the same key would otherwise be spread across all containers of the same image, which would let malicious actors inject packages for example through a man-in-the-middle. The instruction is to run `pacman-key --init` on the first execution and not to redistribute the resulting key.

### How do I verify an Arch Linux image signature?

All images except the official DockerHub library image are signed with cosign's keyless signing, and the README gives a `cosign verify` command per registry that pins the certificate identity to the GitLab CI pipeline file at a version tag and pins the OIDC issuer to `https://gitlab.archlinux.org`.

### How do I build the Arch Linux images myself?

You need the Arch packages `make`, `devtools`, `git`, `podman`, `fakechroot` and `fakeroot`, and your user must be able to run `podman info`. Then you use the `make image-XXX` targets, where the current set is `base`, `base-devel`, `multilib-devel` and `repro`, each producing an `archlinux:XXX` image from the matching meta package.

## Sources

- [archlinux/archlinux-docker on GitHub](https://github.com/archlinux/archlinux-docker)
- [Issues](https://github.com/archlinux/archlinux-docker/issues)
- [License: GPL-3.0](https://github.com/archlinux/archlinux-docker/blob/master/LICENSE)
- [Project website](https://gitlab.archlinux.org/archlinux/archlinux-docker)
- [README](https://github.com/archlinux/archlinux-docker/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/archlinux-archlinux-docker
