From dcc9f86d028174d2d064ae92a5538dffe35f2cdc Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 15:26:48 +0100 Subject: [PATCH 01/19] feat(justfile): pick latest git release via version="latest-git-tag" Signed-off-by: Anthony Turcios (anthoturc) --- justfile | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/justfile b/justfile index da01125..a0b65b5 100644 --- a/justfile +++ b/justfile @@ -1,6 +1,14 @@ version := '' image := 'ghcr.io/linkerd/dev' -_tag := if version != '' { "--tag=" + image + ':' + version } else { "" } + +# Auto-detect latest git version if version is 'latest-git-tag' +_version := if version == 'latest-git-tag' { + shell('which git > /dev/null || (echo >&2 "$1error$2: git not available" && exit 1) && git --git-dir="$3/.git" --work-tree="$3" tag -l --sort=-version:refname "v*" | head -n 1', style('error'), NORMAL, justfile_directory()) +} else { + version +} + +_tag := if _version != '' { "--tag=" + image + ':' + _version } else { "" } k3s-image := 'docker.io/rancher/k3s' @@ -26,7 +34,7 @@ build: && _list-if-load for tgt in {{ targets }} ; do just output='{{ output }}' \ image='{{ image }}' \ - version='{{ version }}' \ + version='{{ _version }}' \ _target "$tgt" done @@ -36,22 +44,22 @@ _list-if-load: if [ '{{ load }}' = 'true' ] ; then just image='{{ image }}' \ targets='{{ targets }}' \ - version='{{ version }}' \ + version='{{ _version }}' \ list fi list: #!/usr/bin/env bash set -euo pipefail - if [ -z '{{ version }}' ]; then + if [ -z '{{ _version }}' ]; then echo "Usage: just version= list" >&2 exit 64 fi for tgt in {{ targets }} ; do if [ "$tgt" == "devcontainer" ]; then - docker image ls {{ image }}:{{ version }} | sed 1d + docker image ls {{ image }}:{{ _version }} | sed 1d else - docker image ls {{ image }}:{{ version }}-$tgt | sed 1d + docker image ls {{ image }}:{{ _version }}-$tgt | sed 1d fi done @@ -100,8 +108,9 @@ _target target='': @just \ output='{{ output }}' \ image='{{ image }}' \ + version='{{ _version }}' \ _build --target='{{ target }}' \ - {{ if version == '' { '' } else { '--tag=' + image + ':' + version + if target == 'devcontainer' { '' } else { '-' + target } } }} + {{ if _version == '' { '' } else { '--tag=' + image + ':' + _version + if target == 'devcontainer' { '' } else { '-' + target } } }} # Build the devcontainer image _build *args='': From 469996bd703b39a27dd7a9e387b6195803cdf0b3 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 18:55:25 +0100 Subject: [PATCH 02/19] feat(justfile): allow passing in additional docker args to build Signed-off-by: Anthony Turcios (anthoturc) --- justfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/justfile b/justfile index a0b65b5..7c0b39e 100644 --- a/justfile +++ b/justfile @@ -28,14 +28,15 @@ export DOCKER_PROGRESS := env_var_or_default('DOCKER_PROGRESS', 'auto') all: sync-k3s-images build -build: && _list-if-load +build *args='': && _list-if-load #!/usr/bin/env bash set -euo pipefail for tgt in {{ targets }} ; do just output='{{ output }}' \ image='{{ image }}' \ version='{{ _version }}' \ - _target "$tgt" + _target "$tgt" \ + {{ args }} done _list-if-load: @@ -104,13 +105,14 @@ _k3s-channels: | {key:.id, value:$tag} ] | from_entries' -_target target='': +_target target='' *args='': @just \ output='{{ output }}' \ image='{{ image }}' \ version='{{ _version }}' \ _build --target='{{ target }}' \ - {{ if _version == '' { '' } else { '--tag=' + image + ':' + _version + if target == 'devcontainer' { '' } else { '-' + target } } }} + {{ if _version == '' { '' } else { '--tag=' + image + ':' + _version + if target == 'devcontainer' { '' } else { '-' + target } } }} \ + {{ args }} # Build the devcontainer image _build *args='': From a2d66916ec227cd1f794261fea6012944aa8e1ca Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 15:44:11 +0100 Subject: [PATCH 03/19] feat(Dockerfile): install arch-specific versions of tools Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0847b4a..47bc920 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,8 +39,9 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update # j5j Turns JSON5 into plain old JSON (i.e. to be processed by jq). FROM apt-base as j5j -ARG J5J_VERSION=v0.2.0 # repo=olix0r/j5j -RUN url="https://github.com/olix0r/j5j/releases/download/${J5J_VERSION}/j5j-${J5J_VERSION}-x86_64-unknown-linux-musl.tar.gz" ; \ +ARG J5J_VERSION=v0.2.1 # repo=unleashed/j5j +RUN arch=$(uname -m); \ + url="https://github.com/unleashed/j5j/releases/download/${J5J_VERSION}/j5j-${J5J_VERSION}-${arch}-unknown-linux-musl.tar.gz" ; \ scurl "$url" | tar zvxf - -C /usr/local/bin j5j # just runs build/test recipes. Like `make` but a bit more ergonomic. @@ -75,7 +76,8 @@ RUN url="https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz" ; \ # helm-docs generates documentation from helm charts. FROM apt-base as helm-docs ARG HELM_DOCS_VERSION=v1.14.2 # repo=norwoodj/helm-docs -RUN url="https://github.com/norwoodj/helm-docs/releases/download/$HELM_DOCS_VERSION/helm-docs_${HELM_DOCS_VERSION#v}_Linux_x86_64.tar.gz" ; \ +RUN arch=$(uname -m | sed -e 's/aarch/arm/'); \ + url="https://github.com/norwoodj/helm-docs/releases/download/$HELM_DOCS_VERSION/helm-docs_${HELM_DOCS_VERSION#v}_Linux_${arch}.tar.gz" ; \ scurl "$url" | tar xzvf - -C /usr/local/bin helm-docs # kubectl controls kubernetes clusters. @@ -153,7 +155,8 @@ RUN url="https://github.com/google/protobuf/releases/download/$PROTOC_VERSION/pr # cargo-action-fmt formats `cargo build` JSON output to Github Actions annotations. FROM apt-base as cargo-action-fmt ARG CARGO_ACTION_FMT_VERSION=v1.0.4 # ignore -RUN url="https://github.com/olix0r/cargo-action-fmt/releases/download/release%2F${CARGO_ACTION_FMT_VERSION}/cargo-action-fmt-${CARGO_ACTION_FMT_VERSION}-x86_64-unknown-linux-musl.tar.gz" ; \ +RUN arch=$(uname -m); \ + url="https://github.com/olix0r/cargo-action-fmt/releases/download/release%2F${CARGO_ACTION_FMT_VERSION}/cargo-action-fmt-${CARGO_ACTION_FMT_VERSION}-${arch}-unknown-linux-musl.tar.gz" ; \ scurl "$url" | tar zvxf - -C /usr/local/bin cargo-action-fmt FROM apt-base as cargo-auditable From d9a75a43dfddc8dbcc644eeb151db9fff5af23a3 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 15:48:01 +0100 Subject: [PATCH 04/19] feat(Dockerfile): install docker-compose explicitly Previously the devcontainer build infrastructure would install docker-compose in the container via scripts, but that script ended up requiring global changes to Python code in order to install docker-compose. Now we just install it here to avoid that problem. Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Dockerfile b/Dockerfile index 47bc920..9a52e70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -385,6 +385,12 @@ RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ ENV CC=clang-19 \ CXX=clang++-19 +# Install docker-compose since it breaks in the docker-debian script on arm64 +RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/apt \ + --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose + # Use microsoft's Docker setup script to install the Docker CLI. # # A distinct cache is used because the script adds an apt repo that we don't From e817d01e53cf6fe95ff827bc8582bb48aa105438 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 15:59:17 +0100 Subject: [PATCH 05/19] feat(justfile): support specifying architecture via docker_arch Signed-off-by: Anthony Turcios (anthoturc) --- justfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/justfile b/justfile index 7c0b39e..34a0c34 100644 --- a/justfile +++ b/justfile @@ -12,6 +12,8 @@ _tag := if _version != '' { "--tag=" + image + ':' + _version } else { "" } k3s-image := 'docker.io/rancher/k3s' +docker_arch := '' + targets := 'go rust rust-musl tools devcontainer' load := 'false' @@ -35,6 +37,7 @@ build *args='': && _list-if-load just output='{{ output }}' \ image='{{ image }}' \ version='{{ _version }}' \ + docker_arch='{{ docker_arch }}' \ _target "$tgt" \ {{ args }} done @@ -110,6 +113,7 @@ _target target='' *args='': output='{{ output }}' \ image='{{ image }}' \ version='{{ _version }}' \ + docker_arch='{{ docker_arch }}' \ _build --target='{{ target }}' \ {{ if _version == '' { '' } else { '--tag=' + image + ':' + _version + if target == 'devcontainer' { '' } else { '-' + target } } }} \ {{ args }} @@ -119,6 +123,7 @@ _build *args='': docker buildx build . {{ _tag }} --pull \ --progress='{{ DOCKER_PROGRESS }}' \ --output='{{ output }}' \ + {{ if docker_arch != '' { '--platform=' + docker_arch } else { '' } }} \ {{ args }} From 02a7759961daab64261a317f9f46e20b40cec856 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 16:16:01 +0100 Subject: [PATCH 06/19] feat(justfile): use dry_run=true to print but avoid executing docker commands Signed-off-by: Anthony Turcios (anthoturc) --- justfile | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/justfile b/justfile index 34a0c34..c374ae2 100644 --- a/justfile +++ b/justfile @@ -12,6 +12,7 @@ _tag := if _version != '' { "--tag=" + image + ':' + _version } else { "" } k3s-image := 'docker.io/rancher/k3s' +dry_run := 'false' docker_arch := '' targets := 'go rust rust-musl tools devcontainer' @@ -38,6 +39,7 @@ build *args='': && _list-if-load image='{{ image }}' \ version='{{ _version }}' \ docker_arch='{{ docker_arch }}' \ + dry_run='{{ dry_run }}' \ _target "$tgt" \ {{ args }} done @@ -61,10 +63,17 @@ list: fi for tgt in {{ targets }} ; do if [ "$tgt" == "devcontainer" ]; then - docker image ls {{ image }}:{{ _version }} | sed 1d + cmd="docker image ls {{ image }}:{{ _version }} | sed 1d" else - docker image ls {{ image }}:{{ _version }}-$tgt | sed 1d + cmd="docker image ls {{ image }}:{{ _version }}-$tgt | sed 1d" fi + + echo "{{ style('error') }}$cmd{{ NORMAL }}" + if [ "{{ dry_run }}" = "true" ]; then + continue + fi + + eval "$cmd" done # Fetch the latest version of k3s images and record their tags and digests. @@ -114,17 +123,28 @@ _target target='' *args='': image='{{ image }}' \ version='{{ _version }}' \ docker_arch='{{ docker_arch }}' \ + dry_run='{{ dry_run }}' \ _build --target='{{ target }}' \ {{ if _version == '' { '' } else { '--tag=' + image + ':' + _version + if target == 'devcontainer' { '' } else { '-' + target } } }} \ {{ args }} # Build the devcontainer image _build *args='': - docker buildx build . {{ _tag }} --pull \ + #!/usr/bin/env bash + set -euo pipefail + + cmd="docker buildx build . {{ _tag }} --pull \ --progress='{{ DOCKER_PROGRESS }}' \ --output='{{ output }}' \ {{ if docker_arch != '' { '--platform=' + docker_arch } else { '' } }} \ - {{ args }} + {{ args }}" + + echo "{{ style('error') }}$cmd{{ NORMAL }}" + if [ "{{ dry_run }}" = "true" ]; then + exit 0 + fi + + eval "$cmd" md-lint *patterns="'**/*.md' '!repos/**'": From aba1270d70cca80b7575599b5ff6a3f9e70bc834 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 16:25:43 +0100 Subject: [PATCH 07/19] feat(justfile): add podman support Signed-off-by: Anthony Turcios (anthoturc) --- justfile | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/justfile b/justfile index c374ae2..05cf4fe 100644 --- a/justfile +++ b/justfile @@ -15,17 +15,32 @@ k3s-image := 'docker.io/rancher/k3s' dry_run := 'false' docker_arch := '' +# Detect docker_bin if not specified: try docker first, then podman +docker_bin := shell('which docker 2> /dev/null || which podman 2> /dev/null || (echo >&2 "$1error$2: neither docker nor podman found" && exit 1)', style('error'), NORMAL) +# Extract basename of docker_bin to identify implementation +_docker_bin_name := file_name(docker_bin) +# Auto-detect if podman is in remote mode (unless explicitly overridden) +podman_remote := if _docker_bin_name == 'podman' { + shell('if $1 info 2>/dev/null | grep -q "remoteSocket"; then echo "true"; else echo "false"; fi', docker_bin) +} else { + 'false' +} + targets := 'go rust rust-musl tools devcontainer' load := 'false' push := 'false' -output := if push == 'true' { - 'type=registry' - } else if load == 'true' { - 'type=docker' - } else { - 'type=image' - } + +# Remote mode cannot use the --output flag +output := if podman_remote == 'true' { + '' +} else if push == 'true' { + '--output=type=registry' +} else if load == 'true' { + '--output=type=docker' +} else { + '--output=type=image' +} export DOCKER_PROGRESS := env_var_or_default('DOCKER_PROGRESS', 'auto') @@ -40,6 +55,8 @@ build *args='': && _list-if-load version='{{ _version }}' \ docker_arch='{{ docker_arch }}' \ dry_run='{{ dry_run }}' \ + docker_bin='{{ docker_bin }}' \ + podman_remote='{{ podman_remote }}' \ _target "$tgt" \ {{ args }} done @@ -63,9 +80,9 @@ list: fi for tgt in {{ targets }} ; do if [ "$tgt" == "devcontainer" ]; then - cmd="docker image ls {{ image }}:{{ _version }} | sed 1d" + cmd="{{ docker_bin }} image ls {{ image }}:{{ _version }} | sed 1d" else - cmd="docker image ls {{ image }}:{{ _version }}-$tgt | sed 1d" + cmd="{{ docker_bin }} image ls {{ image }}:{{ _version }}-$tgt | sed 1d" fi echo "{{ style('error') }}$cmd{{ NORMAL }}" @@ -124,6 +141,8 @@ _target target='' *args='': version='{{ _version }}' \ docker_arch='{{ docker_arch }}' \ dry_run='{{ dry_run }}' \ + docker_bin='{{ docker_bin }}' \ + podman_remote='{{ podman_remote }}' \ _build --target='{{ target }}' \ {{ if _version == '' { '' } else { '--tag=' + image + ':' + _version + if target == 'devcontainer' { '' } else { '-' + target } } }} \ {{ args }} @@ -133,9 +152,9 @@ _build *args='': #!/usr/bin/env bash set -euo pipefail - cmd="docker buildx build . {{ _tag }} --pull \ + cmd="{{ docker_bin }} buildx build . {{ _tag }} --pull \ --progress='{{ DOCKER_PROGRESS }}' \ - --output='{{ output }}' \ + {{ output }} \ {{ if docker_arch != '' { '--platform=' + docker_arch } else { '' } }} \ {{ args }}" From c9b88db97df0b90158e280f1b492d9f354c08083 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 16:35:57 +0100 Subject: [PATCH 08/19] feat(justfile): add pull_policy argument so we avoid hitting limits This is set to never with podman since I'm still experimenting. Signed-off-by: Anthony Turcios (anthoturc) --- justfile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index 05cf4fe..4356eab 100644 --- a/justfile +++ b/justfile @@ -26,6 +26,13 @@ podman_remote := if _docker_bin_name == 'podman' { 'false' } +# pull policy +_pull_policy := if _docker_bin_name == 'podman' { + '=never' +} else { + '' +} + targets := 'go rust rust-musl tools devcontainer' load := 'false' @@ -152,7 +159,7 @@ _build *args='': #!/usr/bin/env bash set -euo pipefail - cmd="{{ docker_bin }} buildx build . {{ _tag }} --pull \ + cmd="{{ docker_bin }} buildx build . {{ _tag }} --pull{{ _pull_policy }} \ --progress='{{ DOCKER_PROGRESS }}' \ {{ output }} \ {{ if docker_arch != '' { '--platform=' + docker_arch } else { '' } }} \ From d0fc217ca5dbbf3101b15a61688746227364620b Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 15:44:57 +0100 Subject: [PATCH 09/19] feat(justfile, Dockerfile): make apt cache sharing configurable This is useful to avoid locking the cache, which is desirable if using buildah, since it has had bugs around this feature. The tradeoff is that you could potentially find locking issues if running multiple parallel apt commands (such as in CI). Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 38 ++++++++++++++++++++------------------ justfile | 8 ++++++++ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9a52e70..a77ad34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -267,11 +267,13 @@ COPY --link --from=tools-script /bin/* /bin/ ## Base images ## +ARG APT_CACHE_SHARING=",sharing=locked" + # A Go build environment. FROM docker.io/library/golang:${GO_TAG} as go RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y file jo jq COPY --link --from=tools-script /bin/* /usr/local/bin/ COPY --link --from=tools-go /bin/* /usr/local/bin/ @@ -284,8 +286,8 @@ ENV PROTOC_NO_VENDOR=1 \ # A Rust build environment. FROM docker.io/library/rust:${RUST_TAG}-slim-bookworm as rust RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ cmake \ curl \ @@ -297,8 +299,8 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ libssl-dev \ pkg-config RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang-19 llvm-19 RUN rustup component add clippy rustfmt COPY --link --from=tools-lint /bin/checksec /usr/local/bin/ @@ -322,8 +324,8 @@ RUN rustup target add \ aarch64-unknown-linux-musl \ x86_64-unknown-linux-musl RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ binutils-aarch64-linux-gnu \ g++-aarch64-linux-gnu \ @@ -336,8 +338,8 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ FROM docker.io/library/debian:bookworm as devcontainer RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ cmake \ curl \ @@ -374,13 +376,13 @@ RUN groupadd --gid=1000 code \ # git v2.34+ has new subcommands and supports code signing via SSH. RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y -t bookworm-backports git RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang-19 llvm-19 ENV CC=clang-19 \ CXX=clang++-19 @@ -398,16 +400,16 @@ RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/a # # TODO(ver): replace this with a devcontainer feature? RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/apt \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ --mount=type=bind,from=tools,source=/bin/scurl,target=/usr/local/bin/scurl \ scurl https://raw.githubusercontent.com/microsoft/vscode-dev-containers/main/script-library/docker-debian.sh | bash -s ENV DOCKER_BUILDKIT=1 ARG MARKDOWNLINT_VERSION=0.22.1 RUN --mount=type=cache,from=apt-node,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-node,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-node,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-node,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-node,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs RUN npm install "markdownlint-cli2@${MARKDOWNLINT_VERSION}" --global diff --git a/justfile b/justfile index 4356eab..5f1d9b6 100644 --- a/justfile +++ b/justfile @@ -33,6 +33,13 @@ _pull_policy := if _docker_bin_name == 'podman' { '' } +# apt cache sharing mode hits a bug in buildah +_apt_cache_sharing := if _docker_bin_name == 'podman' { + '' +} else { + ',sharing=locked' +} + targets := 'go rust rust-musl tools devcontainer' load := 'false' @@ -163,6 +170,7 @@ _build *args='': --progress='{{ DOCKER_PROGRESS }}' \ {{ output }} \ {{ if docker_arch != '' { '--platform=' + docker_arch } else { '' } }} \ + --build-arg APT_CACHE_SHARING={{ _apt_cache_sharing }} \ {{ args }}" echo "{{ style('error') }}$cmd{{ NORMAL }}" From 79efd329a4b5e7d08cd7df0872232b8364360596 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Ruiz Date: Wed, 19 Nov 2025 19:06:07 +0100 Subject: [PATCH 10/19] Revert "feat(justfile, Dockerfile): make apt cache sharing configurable" This reverts commit 27ab1a5333cc5c5af743c6878f42da23aa5050bf. Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 38 ++++++++++++++++++-------------------- justfile | 8 -------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index a77ad34..9a52e70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -267,13 +267,11 @@ COPY --link --from=tools-script /bin/* /bin/ ## Base images ## -ARG APT_CACHE_SHARING=",sharing=locked" - # A Go build environment. FROM docker.io/library/golang:${GO_TAG} as go RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y file jo jq COPY --link --from=tools-script /bin/* /usr/local/bin/ COPY --link --from=tools-go /bin/* /usr/local/bin/ @@ -286,8 +284,8 @@ ENV PROTOC_NO_VENDOR=1 \ # A Rust build environment. FROM docker.io/library/rust:${RUST_TAG}-slim-bookworm as rust RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ cmake \ curl \ @@ -299,8 +297,8 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ libssl-dev \ pkg-config RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang-19 llvm-19 RUN rustup component add clippy rustfmt COPY --link --from=tools-lint /bin/checksec /usr/local/bin/ @@ -324,8 +322,8 @@ RUN rustup target add \ aarch64-unknown-linux-musl \ x86_64-unknown-linux-musl RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ binutils-aarch64-linux-gnu \ g++-aarch64-linux-gnu \ @@ -338,8 +336,8 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ FROM docker.io/library/debian:bookworm as devcontainer RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ cmake \ curl \ @@ -376,13 +374,13 @@ RUN groupadd --gid=1000 code \ # git v2.34+ has new subcommands and supports code signing via SSH. RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y -t bookworm-backports git RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang-19 llvm-19 ENV CC=clang-19 \ CXX=clang++-19 @@ -400,16 +398,16 @@ RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/a # # TODO(ver): replace this with a devcontainer feature? RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/apt \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ --mount=type=bind,from=tools,source=/bin/scurl,target=/usr/local/bin/scurl \ scurl https://raw.githubusercontent.com/microsoft/vscode-dev-containers/main/script-library/docker-debian.sh | bash -s ENV DOCKER_BUILDKIT=1 ARG MARKDOWNLINT_VERSION=0.22.1 RUN --mount=type=cache,from=apt-node,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-node,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,from=apt-node,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ + --mount=type=cache,from=apt-node,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-node,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs RUN npm install "markdownlint-cli2@${MARKDOWNLINT_VERSION}" --global diff --git a/justfile b/justfile index 5f1d9b6..4356eab 100644 --- a/justfile +++ b/justfile @@ -33,13 +33,6 @@ _pull_policy := if _docker_bin_name == 'podman' { '' } -# apt cache sharing mode hits a bug in buildah -_apt_cache_sharing := if _docker_bin_name == 'podman' { - '' -} else { - ',sharing=locked' -} - targets := 'go rust rust-musl tools devcontainer' load := 'false' @@ -170,7 +163,6 @@ _build *args='': --progress='{{ DOCKER_PROGRESS }}' \ {{ output }} \ {{ if docker_arch != '' { '--platform=' + docker_arch } else { '' } }} \ - --build-arg APT_CACHE_SHARING={{ _apt_cache_sharing }} \ {{ args }}" echo "{{ style('error') }}$cmd{{ NORMAL }}" From 5ec21489a8f11ee0c09eb830523c47cbd0874005 Mon Sep 17 00:00:00 2001 From: Raymond Kroeker Date: Thu, 9 Jul 2026 12:11:24 -0700 Subject: [PATCH 11/19] feat(arm64): upgrade the container Use the latest stable version of debian (trixie) resulting in some cascading changes. Add llvm's repo key without using the removed 'add-key' binary. This *also* bumps the version of llvm from bookworm-19 to trixie-22. Drop j5j from a curl install to using 'node-json5' available from the debian repo. It is a drop-in replacement for j5j that strips json5 and outputs base json. Install just and yq from the deb repo vs from a url. Install git from default deb repo vs backports. Install docker using devcontainer/features versus from legacy microsoft repo. 'origin/amr/multiarch-and-podman-support'. Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 49 +++++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9a52e70..d8bf6e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,13 +7,13 @@ ARG GO_TAG=1.26 ARG RUST_TAG=1.90.0 +ARG DEBIAN_RELEASE=trixie # These layers include Debian apt caches, so layers that extend `apt-base` # should not be published. Instead, these layers should be used to provide # cached data to individual `RUN` commands. -FROM docker.io/library/debian:bookworm-slim as apt-base -RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >>/etc/apt/sources.list +FROM docker.io/library/debian:${DEBIAN_RELEASE}-backports AS apt-base RUN DEBIAN_FRONTEND=noninteractive apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y curl unzip xz-utils COPY --link bin/scurl /usr/local/bin/ @@ -28,21 +28,26 @@ RUN apt-get update && apt-get install nodejs -y # See https://apt.llvm.org/. FROM apt-base as apt-llvm RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gnupg2 -RUN curl --tlsv1.2 -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key |apt-key add - -RUN ( echo 'deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-19 main' \ - && echo 'deb-src http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-19 main' ) >> /etc/apt/sources.list +RUN /usr/bin/curl --tlsv1.2 -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key |/usr/bin/tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc + +ARG DEBIAN_RELEASE +# https://docs.docker.com/reference/dockerfile#understand-how-arg-and-from-interact +# ^ declare arg to use the default value in RUN below +RUN ( echo "deb http://apt.llvm.org/${DEBIAN_RELEASE}/ llvm-toolchain-${DEBIAN_RELEASE}-22 main" \ + && echo "deb-src http://apt.llvm.org/${DEBIAN_RELEASE}/ llvm-toolchain-${DEBIAN_RELEASE}-22 main" ) > /etc/apt/sources.list.d/llvm-toolchain.list +RUN cat /etc/apt/sources.list.d/llvm-toolchain.list RUN DEBIAN_FRONTEND=noninteractive apt-get update ## ## Scripting tools ## -# j5j Turns JSON5 into plain old JSON (i.e. to be processed by jq). -FROM apt-base as j5j -ARG J5J_VERSION=v0.2.1 # repo=unleashed/j5j -RUN arch=$(uname -m); \ - url="https://github.com/unleashed/j5j/releases/download/${J5J_VERSION}/j5j-${J5J_VERSION}-${arch}-unknown-linux-musl.tar.gz" ; \ - scurl "$url" | tar zvxf - -C /usr/local/bin j5j +# json5 transforms json +FROM apt-base AS apt-json5 +RUN DEBIAN_FRONTEND=noninteractive apt-get update +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y node-json5 +# consumers use j5j as the interface to stripping comments from json +RUN ln -s /usr/bin/json5 /usr/local/bin/j5j # just runs build/test recipes. Like `make` but a bit more ergonomic. FROM apt-base as just @@ -57,9 +62,6 @@ RUN url="https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linu scurl -o /yq "$url" && chmod +x /yq FROM scratch as tools-script -COPY --link --from=j5j /usr/local/bin/j5j /bin/ -COPY --link --from=just /usr/local/bin/just /bin/ -COPY --link --from=yq /yq /bin/ COPY --link bin/scurl /bin/ ## @@ -282,7 +284,7 @@ ENV PROTOC_NO_VENDOR=1 \ PROTOC_INCLUDE=/usr/local/include # A Rust build environment. -FROM docker.io/library/rust:${RUST_TAG}-slim-bookworm as rust +FROM docker.io/library/rust:${RUST_TAG}-slim-${DEBIAN_RELEASE} as rust RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ @@ -316,7 +318,6 @@ ENV CARGO_INCREMENTAL=0 \ RUSTUP_MAX_RETRIES=10 ENTRYPOINT ["/usr/local/bin/just-cargo"] -COPY --link --from=just /usr/local/bin/just /usr/local/bin/ FROM rust as rust-musl RUN rustup target add \ aarch64-unknown-linux-musl \ @@ -334,7 +335,7 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ ## Devcontainer ## -FROM docker.io/library/debian:bookworm as devcontainer +FROM docker.io/library/debian:${DEBIAN_RELEASE} AS devcontainer RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ @@ -343,6 +344,7 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ curl \ dnsutils \ file \ + git \ iproute2 \ jo \ jq \ @@ -372,12 +374,6 @@ RUN groupadd --gid=1000 code \ && echo "code ALL=(root) NOPASSWD:ALL" >/etc/sudoers.d/code \ && chmod 0440 /etc/sudoers.d/code -# git v2.34+ has new subcommands and supports code signing via SSH. -RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ - DEBIAN_FRONTEND=noninteractive apt-get install -y -t bookworm-backports git - RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ @@ -391,17 +387,14 @@ RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/a --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose -# Use microsoft's Docker setup script to install the Docker CLI. -# +# devcontainers/features: install docker do not use moby (not supported on trixie) # A distinct cache is used because the script adds an apt repo that we don't # want to pull in for other layers. -# -# TODO(ver): replace this with a devcontainer feature? RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/apt \ --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ --mount=type=bind,from=tools,source=/bin/scurl,target=/usr/local/bin/scurl \ - scurl https://raw.githubusercontent.com/microsoft/vscode-dev-containers/main/script-library/docker-debian.sh | bash -s + scurl https://raw.githubusercontent.com/devcontainers/features/refs/heads/main/src/docker-outside-of-docker/install.sh | MOBY=false bash -s ENV DOCKER_BUILDKIT=1 ARG MARKDOWNLINT_VERSION=0.22.1 From 63a07af2181f9050f170a1bb74f567ea2a3a1424 Mon Sep 17 00:00:00 2001 From: Raymond Kroeker Date: Fri, 10 Jul 2026 12:13:53 -0700 Subject: [PATCH 12/19] feat(arm64): refactor unused stages Include node-json5, just and yq packages in devcontainer. Previously the stages were orphaned. True up all of the cache mount options. Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 54 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/Dockerfile b/Dockerfile index d8bf6e6..f0380ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -271,9 +271,9 @@ COPY --link --from=tools-script /bin/* /bin/ # A Go build environment. FROM docker.io/library/golang:${GO_TAG} as go -RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y file jo jq COPY --link --from=tools-script /bin/* /usr/local/bin/ COPY --link --from=tools-go /bin/* /usr/local/bin/ @@ -285,9 +285,9 @@ ENV PROTOC_NO_VENDOR=1 \ # A Rust build environment. FROM docker.io/library/rust:${RUST_TAG}-slim-${DEBIAN_RELEASE} as rust -RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ cmake \ curl \ @@ -298,9 +298,9 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ jq \ libssl-dev \ pkg-config -RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang-19 llvm-19 RUN rustup component add clippy rustfmt COPY --link --from=tools-lint /bin/checksec /usr/local/bin/ @@ -322,9 +322,9 @@ FROM rust as rust-musl RUN rustup target add \ aarch64-unknown-linux-musl \ x86_64-unknown-linux-musl -RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ binutils-aarch64-linux-gnu \ g++-aarch64-linux-gnu \ @@ -336,9 +336,9 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ ## FROM docker.io/library/debian:${DEBIAN_RELEASE} AS devcontainer -RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y \ cmake \ curl \ @@ -348,17 +348,23 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,ro \ iproute2 \ jo \ jq \ + just \ libssl-dev \ locales \ lsb-release \ netcat-openbsd \ + node-json5 \ pkg-config \ skopeo \ sudo \ time \ tshark \ umoci \ - unzip + unzip \ + yq + +# consumers use j5j as the interface to stripping comments from json +RUN ln -s /usr/bin/json5 /usr/local/bin/j5j # Link the gnu versions of ranlib to the musl toolchain. # See: https://github.com/linkerd/linkerd2/issues/13350 @@ -374,34 +380,34 @@ RUN groupadd --gid=1000 code \ && echo "code ALL=(root) NOPASSWD:ALL" >/etc/sudoers.d/code \ && chmod 0440 /etc/sudoers.d/code -RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,ro \ +RUN --mount=type=cache,from=apt-llvm,source=/etc/apt,target=/etc/apt,sharing=locked \ --mount=type=cache,from=apt-llvm,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-llvm,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ + --mount=type=cache,from=apt-llvm,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y clang-19 llvm-19 ENV CC=clang-19 \ CXX=clang++-19 # Install docker-compose since it breaks in the docker-debian script on arm64 -RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/apt \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt${APT_CACHE_SHARING} \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists${APT_CACHE_SHARING} \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose # devcontainers/features: install docker do not use moby (not supported on trixie) # A distinct cache is used because the script adds an apt repo that we don't # want to pull in for other layers. -RUN --mount=type=cache,id=apt-docker,from=apt-base,source=/etc/apt,target=/etc/apt \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,id=apt-docker,from=apt-base,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ --mount=type=bind,from=tools,source=/bin/scurl,target=/usr/local/bin/scurl \ scurl https://raw.githubusercontent.com/devcontainers/features/refs/heads/main/src/docker-outside-of-docker/install.sh | MOBY=false bash -s ENV DOCKER_BUILDKIT=1 ARG MARKDOWNLINT_VERSION=0.22.1 -RUN --mount=type=cache,from=apt-node,source=/etc/apt,target=/etc/apt,ro \ - --mount=type=cache,from=apt-node,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ - --mount=type=cache,from=apt-node,source=/var/lib/apt/lists,target=/var/lib/apt/lists,sharing=locked \ - DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs +RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/cache/apt,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,from=apt-base,source=/var/lib/apt,target=/var/lib/apt,sharing=locked \ + DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y nodejs npm RUN npm install "markdownlint-cli2@${MARKDOWNLINT_VERSION}" --global COPY --link --from=go /usr/local/go /usr/local/go From f239e455cc896a9b333a1779df1d9799ef6ae4e5 Mon Sep 17 00:00:00 2001 From: Raymond Kroeker Date: Fri, 10 Jul 2026 14:15:14 -0700 Subject: [PATCH 13/19] Drop nodejs. Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index f0380ca..8385edd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,13 +18,6 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y curl unzip xz-utils COPY --link bin/scurl /usr/local/bin/ -FROM apt-base as apt-node -RUN apt-get install -y gnupg2 -ARG NODE_MAJOR=26 -RUN mkdir -p /etc/apt/keyrings && scurl https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg -RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" >/etc/apt/sources.list.d/nodesource.list -RUN apt-get update && apt-get install nodejs -y - # See https://apt.llvm.org/. FROM apt-base as apt-llvm RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gnupg2 @@ -345,6 +338,7 @@ RUN --mount=type=cache,from=apt-base,source=/etc/apt,target=/etc/apt,sharing=loc dnsutils \ file \ git \ + gnupg2 \ iproute2 \ jo \ jq \ From 2a9adbc824b508e9c3af7685ef8c66e24a194f41 Mon Sep 17 00:00:00 2001 From: "Anthony Turcios (anthoturc)" Date: Thu, 27 Aug 2026 12:05:46 -0400 Subject: [PATCH 14/19] feat(arm64,amd64): remove hardcoded arch from artifact locations (urls, packages) Signed-off-by: Anthony Turcios (anthoturc) --- Dockerfile | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8385edd..06795fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,13 +45,16 @@ RUN ln -s /usr/bin/json5 /usr/local/bin/j5j # just runs build/test recipes. Like `make` but a bit more ergonomic. FROM apt-base as just ARG JUST_VERSION=1.54.0 # repo=casey/just -RUN url="https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-x86_64-unknown-linux-musl.tar.gz" ; \ +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch64/'); \ + url="https://github.com/casey/just/releases/download/${JUST_VERSION}/just-${JUST_VERSION}-${arch}-unknown-linux-musl.tar.gz" ; \ scurl "$url" | tar zvxf - -C /usr/local/bin just # yq is kind of like jq, but for YAML. FROM apt-base as yq ARG YQ_VERSION=v4.53.3 # repo=mikefarah/yq -RUN url="https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64" ; \ +ARG TARGETARCH +RUN url="https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH}" ; \ scurl -o /yq "$url" && chmod +x /yq FROM scratch as tools-script @@ -64,21 +67,24 @@ COPY --link bin/scurl /bin/ # helm templates kubernetes manifests. FROM apt-base as helm ARG HELM_VERSION=v3.21.2 # repo=helm/helm -RUN url="https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz" ; \ - scurl "$url" | tar xzvf - --strip-components=1 -C /usr/local/bin linux-amd64/helm +ARG TARGETARCH +RUN url="https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz" ; \ + scurl "$url" | tar xzvf - --strip-components=1 -C /usr/local/bin "linux-${TARGETARCH}/helm" # helm-docs generates documentation from helm charts. FROM apt-base as helm-docs ARG HELM_DOCS_VERSION=v1.14.2 # repo=norwoodj/helm-docs -RUN arch=$(uname -m | sed -e 's/aarch/arm/'); \ +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/'); \ url="https://github.com/norwoodj/helm-docs/releases/download/$HELM_DOCS_VERSION/helm-docs_${HELM_DOCS_VERSION#v}_Linux_${arch}.tar.gz" ; \ scurl "$url" | tar xzvf - -C /usr/local/bin helm-docs # kubectl controls kubernetes clusters. FROM apt-base as kubectl ARG KUBECTL_VERSION=v1.36.2 # repo=kubernetes/kubernetes -RUN url="https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" ; \ +ARG TARGETARCH +RUN url="https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" ; \ scurl -o /usr/local/bin/kubectl "$url" && chmod +x /usr/local/bin/kubectl # k3d runs kubernetes clusters in docker. @@ -113,7 +119,8 @@ COPY --link --from=ghcr.io/anchore/grype:v0.96.1 /grype /bin/ # actionlint lints github actions workflows. FROM apt-base as actionlint ARG ACTIONLINT_VERSION=v1.7.12 # repo=rhysd/actionlint -RUN url="https://github.com/rhysd/actionlint/releases/download/${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION#v}_linux_amd64.tar.gz" ; \ +ARG TARGETARCH +RUN url="https://github.com/rhysd/actionlint/releases/download/${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION#v}_linux_${TARGETARCH}.tar.gz" ; \ scurl "$url" | tar xzvf - -C /usr/local/bin actionlint # checksec checks binaries for security issues. @@ -134,7 +141,10 @@ COPY --link bin/action-* bin/just-dev bin/just-sh /bin/ FROM apt-base as protobuf ARG PROTOC_VERSION=v35.1 # repo=protocolbuffers/protobuf -RUN url="https://github.com/google/protobuf/releases/download/$PROTOC_VERSION/protoc-${PROTOC_VERSION#v}-linux-$(uname -m).zip" ; \ +ARG TARGETARCH +# protobuf spells arm64 as `aarch_64`, with an underscore. +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch_64/'); \ + url="https://github.com/google/protobuf/releases/download/$PROTOC_VERSION/protoc-${PROTOC_VERSION#v}-linux-${arch}.zip" ; \ cd $(mktemp -d) && \ scurl -o protoc.zip "$url" && \ unzip protoc.zip bin/protoc include/** && \ @@ -150,31 +160,40 @@ RUN url="https://github.com/google/protobuf/releases/download/$PROTOC_VERSION/pr # cargo-action-fmt formats `cargo build` JSON output to Github Actions annotations. FROM apt-base as cargo-action-fmt ARG CARGO_ACTION_FMT_VERSION=v1.0.4 # ignore -RUN arch=$(uname -m); \ +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch64/'); \ url="https://github.com/olix0r/cargo-action-fmt/releases/download/release%2F${CARGO_ACTION_FMT_VERSION}/cargo-action-fmt-${CARGO_ACTION_FMT_VERSION}-${arch}-unknown-linux-musl.tar.gz" ; \ scurl "$url" | tar zvxf - -C /usr/local/bin cargo-action-fmt FROM apt-base as cargo-auditable ARG CARGO_AUDITABLE_VERSION=v0.7.5 # repo=rust-secure-code/cargo-auditable -RUN url="https://github.com/rust-secure-code/cargo-auditable/releases/download/${CARGO_AUDITABLE_VERSION}/cargo-auditable-x86_64-unknown-linux-gnu.tar.xz" ; \ - scurl "$url" | tar xJvf - --strip-components=1 -C /usr/local/bin cargo-auditable-x86_64-unknown-linux-gnu/cargo-auditable +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch64/'); \ + url="https://github.com/rust-secure-code/cargo-auditable/releases/download/${CARGO_AUDITABLE_VERSION}/cargo-auditable-${arch}-unknown-linux-gnu.tar.xz" ; \ + scurl "$url" | tar xJvf - --strip-components=1 -C /usr/local/bin "cargo-auditable-${arch}-unknown-linux-gnu/cargo-auditable" # cargo-deny checks cargo dependencies for licensing and RUSTSEC security issues. FROM apt-base as cargo-deny ARG CARGO_DENY_VERSION=0.19.9 # repo=EmbarkStudios/cargo-deny -RUN url="https://github.com/EmbarkStudios/cargo-deny/releases/download/${CARGO_DENY_VERSION}/cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl.tar.gz" ; \ - scurl "$url" | tar zvxf - --strip-components=1 -C /usr/local/bin "cargo-deny-${CARGO_DENY_VERSION}-x86_64-unknown-linux-musl/cargo-deny" +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch64/'); \ + url="https://github.com/EmbarkStudios/cargo-deny/releases/download/${CARGO_DENY_VERSION}/cargo-deny-${CARGO_DENY_VERSION}-${arch}-unknown-linux-musl.tar.gz" ; \ + scurl "$url" | tar zvxf - --strip-components=1 -C /usr/local/bin "cargo-deny-${CARGO_DENY_VERSION}-${arch}-unknown-linux-musl/cargo-deny" # cargo-nextest is a nicer test runner. FROM apt-base as cargo-nextest ARG NEXTEST_VERSION=0.9.138 # repo=nextest-rs/nextest,prefix=cargo-nextest- -RUN url="https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-${NEXTEST_VERSION}/cargo-nextest-${NEXTEST_VERSION}-x86_64-unknown-linux-gnu.tar.gz" ; \ +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch64/'); \ + url="https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-${NEXTEST_VERSION}/cargo-nextest-${NEXTEST_VERSION}-${arch}-unknown-linux-gnu.tar.gz" ; \ scurl "$url" | tar zvxf - -C /usr/local/bin cargo-nextest # cargo-tarpaulin is a code coverage tool. FROM apt-base as cargo-tarpaulin ARG CARGO_TARPAULIN_VERSION=0.35.5 # repo=xd009642/tarpaulin -RUN url="https://github.com/xd009642/tarpaulin/releases/download/${CARGO_TARPAULIN_VERSION}/cargo-tarpaulin-x86_64-unknown-linux-musl.tar.gz" ;\ +ARG TARGETARCH +RUN arch=$(echo "$TARGETARCH" | sed -e 's/amd64/x86_64/' -e 's/arm64/aarch64/'); \ + url="https://github.com/xd009642/tarpaulin/releases/download/${CARGO_TARPAULIN_VERSION}/cargo-tarpaulin-${arch}-unknown-linux-musl.tar.gz" ;\ scurl "$url" | tar xzvf - -C /usr/local/bin cargo-tarpaulin FROM scratch as tools-rust From 488c9bab9cc5055e7cd3d7229dcd58aef6cb3c65 Mon Sep 17 00:00:00 2001 From: Raymond Kroeker Date: Wed, 16 Sep 2026 10:55:28 -0700 Subject: [PATCH 15/19] feat(arm64,amd64): sync k3s images Signed-off-by: Anthony Turcios (anthoturc) --- k3s-images.json | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/k3s-images.json b/k3s-images.json index d821625..a77cf56 100644 --- a/k3s-images.json +++ b/k3s-images.json @@ -1,21 +1,23 @@ { "name": "docker.io/rancher/k3s", "channels": { - "stable": "v1.36.2-k3s1", - "latest": "v1.36.2-k3s1", + "stable": "v1.36.4-k3s1", + "latest": "v1.37.0-k3s1", "v1.31": "v1.31.14-k3s1", "v1.32": "v1.32.13-k3s1", - "v1.33": "v1.33.13-k3s1", - "v1.34": "v1.34.9-k3s1", - "v1.35": "v1.35.6-k3s1", - "v1.36": "v1.36.2-k3s1" + "v1.33": "v1.33.13-k3s2", + "v1.34": "v1.34.11-k3s1", + "v1.35": "v1.35.8-k3s1", + "v1.36": "v1.36.4-k3s1", + "v1.37": "v1.37.0-k3s1" }, "digests": { "v1.31.14-k3s1": "sha256:6c33f6a8ff6dd6ae63428d5c8e331e059a4111d5ec3f5beaa9df6c50ba6b7ce8", "v1.32.13-k3s1": "sha256:7534b63e02277917f77c584ed5532b31562c760d6bb8fe88059002e9bdeee033", - "v1.33.13-k3s1": "sha256:523cfdf26aaef2c3164eefa30a61f5f1dca86d1cf3f1d38beae62ac65905a3ab", - "v1.34.9-k3s1": "sha256:9c162556657a38e394d1f944081388ae7c0b85ec29134c509583083e287f804e", - "v1.35.6-k3s1": "sha256:9d6b9c15e8031c1aea7dd7f0cdc019f5e74a23c53b9eada564b7a8dc94efc14c", - "v1.36.2-k3s1": "sha256:6a47cea22c4b834d4ba72c89d291696b79ebe406251f90b446e4dff03513dd87" + "v1.33.13-k3s2": "sha256:ada5ff2e138120efe877f76d514dedda65b304122112b982eab532732c028c89", + "v1.34.11-k3s1": "sha256:5d52389a0f4fd7ebdb5a1fb2d7c67c35da966230782c4abb0667d86bcccea9c2", + "v1.35.8-k3s1": "sha256:59fe491fd3b73204e499e40b325240d85c42c7189c3ae50150d37b78243f3b32", + "v1.36.4-k3s1": "sha256:edad48e12bf81c3a09ac1c05c0c0ffaaa22145980b989d6fae84543a76b83657", + "v1.37.0-k3s1": "sha256:d33b1973401a60410681d66c007f5c3a51d565a7c03608904764aef3321fee4d" } } From 93246ff712c32ab68dd72a26f4b37b013841d2be Mon Sep 17 00:00:00 2001 From: "Anthony Turcios (anthoturc)" Date: Thu, 17 Sep 2026 16:29:40 +0000 Subject: [PATCH 16/19] chore: bump to v51 Signed-off-by: Anthony Turcios (anthoturc) --- .devcontainer/devcontainer.json | 2 +- actions/setup-tools/action.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bb2b907..5664b43 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { "name": "linkerd-dev", - "image": "ghcr.io/linkerd/dev:v50", + "image": "ghcr.io/linkerd/dev:v51", "customizations": { "vscode": { "extensions": [ diff --git a/actions/setup-tools/action.yml b/actions/setup-tools/action.yml index 4531482..d7fb4c1 100644 --- a/actions/setup-tools/action.yml +++ b/actions/setup-tools/action.yml @@ -5,7 +5,7 @@ inputs: # TODO(ver): CI should validate at this version matches the most recent release tag version: description: Container image version - default: v50 + default: v51 runs: using: composite From a6717aaed88518d9ccde58d7b0be462d788f18ec Mon Sep 17 00:00:00 2001 From: "Anthony Turcios (anthoturc)" Date: Thu, 17 Sep 2026 17:05:06 +0000 Subject: [PATCH 17/19] fix(dockerfile): run apt-get update before install gnupg2 --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 06795fe..7884bf2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,7 @@ COPY --link bin/scurl /usr/local/bin/ # See https://apt.llvm.org/. FROM apt-base as apt-llvm +RUN DEBIAN_FRONTEND=noninteractive apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gnupg2 RUN /usr/bin/curl --tlsv1.2 -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key |/usr/bin/tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc From 26c09dea58bd43bbdcbd997c4d4ef8f5a30d29e9 Mon Sep 17 00:00:00 2001 From: "Anthony Turcios (anthoturc)" Date: Fri, 18 Sep 2026 09:55:17 -0400 Subject: [PATCH 18/19] fix(justfile): make publishing step actually build arm64 prior to this commit, the arm64 and amd64 artifacts depended on the arch of the host machine. going forward, dev images that are being published should build both by default. --- README.md | 12 ++++++++++++ justfile | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 768b3b3..f0a0fbe 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,18 @@ all the images directly from your branch: :; just push=true version=vNN build ``` +This publishes each image for both `linux/amd64` and `linux/arm64` under a single +tag. Whichever architecture doesn't match your workstation is built under +emulation, so expect the publish to take a while. To confirm both architectures +made it into the manifest list: + +```sh +:; docker buildx imagetools inspect ghcr.io/linkerd/dev:vNN-tools +``` + +Local builds are not affected: without `push=true` only the host architecture is +built. Override either default with, for example, `docker_arch=linux/arm64`. + After publication you can then trigger the tests again and they should pass. Finally merge the branch and tag the release on `main`. diff --git a/justfile b/justfile index 4356eab..57435a5 100644 --- a/justfile +++ b/justfile @@ -13,7 +13,6 @@ _tag := if _version != '' { "--tag=" + image + ':' + _version } else { "" } k3s-image := 'docker.io/rancher/k3s' dry_run := 'false' -docker_arch := '' # Detect docker_bin if not specified: try docker first, then podman docker_bin := shell('which docker 2> /dev/null || which podman 2> /dev/null || (echo >&2 "$1error$2: neither docker nor podman found" && exit 1)', style('error'), NORMAL) @@ -38,6 +37,15 @@ targets := 'go rust rust-musl tools devcontainer' load := 'false' push := 'false' +# Platforms to build, as a comma-delimited list of os/arch pairs. Published +# images must support both architectures; local builds default to the host +# platform so that iterating on the Dockerfile stays fast (and because +# multi-platform images cannot be loaded into the local image store). +# See https://github.com/docker/buildx/issues/59 +docker_arch := if push == 'true' { 'linux/amd64,linux/arm64' } else { '' } + +_multi_arch := if docker_arch =~ ',' { 'true' } else { 'false' } + # Remote mode cannot use the --output flag output := if podman_remote == 'true' { '' @@ -159,6 +167,12 @@ _build *args='': #!/usr/bin/env bash set -euo pipefail + if [ '{{ _multi_arch }}' = 'true' ] && [[ '{{ output }}' == *type=docker* ]]; then + echo >&2 "{{ style('error') }}error{{ NORMAL }}: multi-platform images cannot be loaded into the local image store." + echo >&2 "Build a single platform, e.g. docker_arch=linux/arm64, or use push=true." + exit 64 + fi + cmd="{{ docker_bin }} buildx build . {{ _tag }} --pull{{ _pull_policy }} \ --progress='{{ DOCKER_PROGRESS }}' \ {{ output }} \ From 2e99a16b3c8c041fccfd4a05d30d97d41908fa2d Mon Sep 17 00:00:00 2001 From: "Anthony Turcios (anthoturc)" Date: Fri, 18 Sep 2026 15:29:38 -0400 Subject: [PATCH 19/19] fix(dockerfile): build j5j in docker image and copy missing tools j5j appears to only have artifacts for amd64 so it is being built manually in the docker image. just and yq are being copied over since they were missing in the last commit --- Dockerfile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Dockerfile b/Dockerfile index 7884bf2..09a76d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,6 +43,18 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y node-json5 # consumers use j5j as the interface to stripping comments from json RUN ln -s /usr/bin/json5 /usr/local/bin/j5j +# j5j turns JSON5 into plain old JSON (i.e. to be processed by jq). Upstream +# only publishes an x86_64 release asset, so it is built from source here to +# support both architectures. +FROM docker.io/library/rust:${RUST_TAG}-slim-${DEBIAN_RELEASE} as j5j +ARG J5J_VERSION=v0.2.0 # repo=olix0r/j5j +# Built against musl so the binary is static: it is copied into scratch-based +# images and unpacked onto CI runners whose glibc is older than this builder's. +RUN target="$(uname -m)-unknown-linux-musl" ; \ + rustup target add "$target" && \ + cargo install --git https://github.com/olix0r/j5j --tag "${J5J_VERSION}" \ + --target "$target" --root /usr/local + # just runs build/test recipes. Like `make` but a bit more ergonomic. FROM apt-base as just ARG JUST_VERSION=1.54.0 # repo=casey/just @@ -59,6 +71,9 @@ RUN url="https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linu scurl -o /yq "$url" && chmod +x /yq FROM scratch as tools-script +COPY --link --from=j5j /usr/local/bin/j5j /bin/ +COPY --link --from=just /usr/local/bin/just /bin/ +COPY --link --from=yq /yq /bin/ COPY --link bin/scurl /bin/ ##