devcontainer: Add the Kitware APT repository

Configure `apt.kitware.com` in the development container so that `cmake`
is the latest CMake release rather than the older one Ubuntu carries, and
so that developers reach each further release through `apt-get` alone.

Fetch the repository's signing key, verified against the hash the
`Dockerfile` pins, and trust it just long enough to install
`kitware-archive-keyring`, which then provides the key, so that `apt`
follows the rotations Kitware makes to it.  Interpolating the hash into
the step that fetches the key also busts the build cache when the hash
changes, so a rotation is picked up rather than served from an old layer.
Reaching either the key or the repository needs `curl` and a certificate
store, neither of which the base image carries, so install them first.
This commit is contained in:
Taylor Braun-Jones
2026-09-08 16:24:41 +00:00
parent 69c15636b6
commit 7ae5c3cfb2
3 changed files with 88 additions and 3 deletions
+18 -2
View File
@@ -5,8 +5,9 @@
# The images our CI infrastructure uses, described under `.gitlab/ci/docker/`,
# are built on the distributions we test CMake against and are minimized for
# CI use. Prepare the environment from scratch on Ubuntu instead: it offers
# the broadest ecosystem of packages and tooling for development, including a
# recent `cmake` and the `clang-format` version our style rules require.
# the broadest ecosystem of packages and tooling for development, including
# the `clang-format` version our style rules require and the Kitware APT
# repository through which CMake itself is published.
ARG BASE_IMAGE=ubuntu:26.04
FROM ${BASE_IMAGE}
@@ -15,6 +16,21 @@ ARG USERNAME=cmake-dev
ARG USER_UID=1000
ARG USER_GID=${USER_UID}
# The SHA-256 of the signing key `apt.kitware.com` publishes. Kitware rotates
# that key every few years; updating this hash both approves the new key and
# forces the step below to fetch it again rather than reuse a cached layer.
# Read the current value with:
# curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc | sha256sum
ARG KITWARE_PUBLIC_KEY_SHA256=801bc629e356c3c96f184351272914222ce427777400fa7d1baed3ab180b3e3b
# Add the Kitware APT repository, which carries CMake releases newer than the
# ones the distribution provides, before installing anything from it below.
RUN --mount=type=bind,source=install_kitware_archive.sh,target=/root/install_kitware_archive.sh \
--mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
--mount=type=cache,target=/var/cache/apt,sharing=locked \
sh /root/install_kitware_archive.sh ${KITWARE_PUBLIC_KEY_SHA256}
# Install the packages needed to build CMake, run its test suite, build its
# documentation, and satisfy its style rules, along with a few more that make
# the container a comfortable place to work.
+56
View File
@@ -0,0 +1,56 @@
#!/bin/sh
# Add the Kitware APT repository, which carries CMake releases newer than the
# ones the distribution provides. See `Help/dev/devcontainer.rst`.
set -e
readonly key_sha256="$1"
if test -z "$key_sha256"; then
echo "usage: $0 <sha256-of-kitware-archive-key>" >&2
exit 1
fi
# Install without asking questions.
export DEBIAN_FRONTEND=noninteractive
# `VERSION_CODENAME` names the suite the repository provides for the
# distribution the container is based on.
. /etc/os-release
readonly sources=/etc/apt/sources.list.d/kitware.sources
readonly keyring=/usr/share/keyrings/kitware-archive-keyring
readonly key_url=https://apt.kitware.com/keys/kitware-archive-latest.asc
# Describe the repository, verified with the keyring named as the argument.
write_sources() {
cat > "$sources" <<EOF
Types: deb
URIs: https://apt.kitware.com/ubuntu/
Suites: ${VERSION_CODENAME}
Components: main
Signed-By: $1
EOF
}
apt-get update
# The base image carries neither `curl` nor a certificate store, and neither
# the key nor the repository can be reached without one: both redirect HTTP
# to HTTPS.
apt-get install -y ca-certificates curl
# Trust the repository with the key it publishes, checked against the hash our
# caller pins, just long enough to install `kitware-archive-keyring`. Once
# that package provides the key, `apt` follows the rotations Kitware makes to
# it each year, which a pinned hash would not. `apt` reads an armored key
# only from a `.asc` file, and the package provides a `.gpg` one, so name the
# file each step uses accordingly.
curl -fsSL -o "$keyring.asc" "$key_url"
echo "$key_sha256 $keyring.asc" | sha256sum --check
write_sources "$keyring.asc"
apt-get update
apt-get install -y kitware-archive-keyring
write_sources "$keyring.gpg"
rm "$keyring.asc"
+14 -1
View File
@@ -97,7 +97,19 @@ Provided Tools
In addition to the compiler and the external dependencies CMake can build
against, the container provides:
* ``cmake`` and ``ninja``, to build CMake with.
* ``cmake`` and ``ninja``, to build CMake with. ``cmake`` comes from the
`Kitware APT repository`_, which the container configures, so it is the
latest CMake release rather than the older one Ubuntu carries, and
``apt-get`` offers each new release as it is published:
.. code-block:: console
$ sudo apt-get update
$ sudo apt-get install --only-upgrade cmake
The repository also carries release candidates, in a suite named after the
Ubuntu release with ``-rc`` appended. Add it to the ``Suites`` field of
``/etc/apt/sources.list.d/kitware.sources`` to install those as well.
* ``ccache``, to speed up repeated builds, e.g.:
@@ -139,6 +151,7 @@ against, the container provides:
See `GitLab Authentication`_ below for the one-time setup they need.
.. _`Kitware APT repository`: https://apt.kitware.com
.. _`C++ Code Style`: source.rst#c-code-style
.. _`.pre-commit-config.yaml`: ../../.pre-commit-config.yaml
.. _`CMake Documentation Guide`: documentation.rst