Add nanoserver:ltsc2025 and nanoserver:ltsc2025-arm64 helper images

Summary

Add nanoserver:ltsc2025 (amd64) and nanoserver:ltsc2025-arm64 variants of the gitlab-runner-helper container image, mirroring the servercore:ltsc2025 work shipped in !6033 (merged). This is part 4 of the 5-MR plan to deliver full Windows ARM64 support for the docker-windows executor, parent issue #39182 (closed).

Nanoserver images are roughly 10× smaller than servercore (see #39333), so this is the change that brings Windows helper image size on ARM64 down to something comparable with the linux variants.

Background

After review of !6033 (merged), @avonbertoldi and @shanushpt aligned on a 5-MR plan:

  1. MR 1 (done, !6033 (merged)) — Add servercore ltsc2025 and ltsc2025-arm64 helper images. The arm64 image bundles the amd64 helper binary under emulation as a documented workaround.
  2. MR 2 (#39416 (closed)) — Build the native arm64 gitlab-runner-helper.exe.
  3. MR 3 (#39417 (closed)) — Replace the amd64-via-emulation helper binary in the arm64 servercore image with the native arm64 binary from MR 2.
  4. MR 4 (this issue) — Add nanoserver 2025 support for arm64 and amd64.
  5. MR 5 — Fix gitlab-runner.exe host architecture detection and automatic arm64 helper image selection.

Why nanoserver 2025 only — not 2019/2022

@avonbertoldi documented during !6033 review that Microsoft only publishes ARM64 nanoserver from ltsc2025 onward:

> docker manifest inspect mcr.microsoft.com/windows/nanoserver:ltsc2019-arm64
no such manifest
> docker manifest inspect mcr.microsoft.com/windows/nanoserver:ltsc2022-arm64
no such manifest
> docker manifest inspect mcr.microsoft.com/windows/nanoserver:ltsc2025-arm64
{ ... 263 MB ... }

So this MR adds nanoserver only for ltsc2025. There is no upstream image to support nanoserver:ltsc2019-arm64 or nanoserver:ltsc2022-arm64.

Why this MR depends on MR 2 + MR 3

@shanushpt confirmed during !6033 review that nanoserver does not support amd64 binary emulation on ARM64 — the image is too minimal:

Unfortunately nanoserver does not support emulation of windows amd64 binaries on an arm platform (as it is too minimal). It might be possible to do crazy things like enabling it via FOD, but firstly I have not been able to successfully use FOD yet and secondly it requires actually building the image on windows which the CI infrastructure does not use.

This is why nanoserver was deliberately deferred until after MR 2 (build the native arm64 helper binary) and MR 3 (wire it into the arm64 servercore image). Without those, a nanoserver:ltsc2025-arm64 helper image would simply not run.

What needs to change

1. Add nanoserver 2025 entries to the docker-bake matrix

Extend the windows target matrix in dockerfiles/runner-helper/docker-bake.hcl so it includes the nanoserver variants alongside the existing servercore ones. Following the existing pattern from !6033 (merged):

item = [
  { version = "nanoserver:ltsc2019",       arch = "amd64" },
  { version = "nanoserver:ltsc2022",       arch = "amd64" },
  { version = "servercore:ltsc2019",       arch = "amd64" },
  { version = "servercore:ltsc2022",       arch = "amd64" },
  { version = "servercore:ltsc2025",       arch = "amd64" },
  { version = "servercore:ltsc2025-arm64", arch = "arm64" },
+ { version = "nanoserver:ltsc2025",       arch = "amd64" },
+ { version = "nanoserver:ltsc2025-arm64", arch = "arm64" }
]

2. Add CI build jobs

Update .gitlab/ci/build.gitlab-ci.yml so the new images are built and the existing prebuilt helper images windows 2025 / prebuilt helper images windows 2025 arm64 jobs include them. Watch out for the artifact-size limit (@avonbertoldi reported 413 Request Entity Too Large at ~4.85 GB combined in !6033 (merged)). Nanoserver is much smaller than servercore (~270 MB vs ~2.5 GB) so this should not blow the limit, but confirm during the first pipeline run; split further if needed.

3. Add pusher entries

Add the corresponding entries in scripts/pusher/helper-images.json, following the native naming convention agreed in MR 3. Indicative shape:

"windows-nanoserver-ltsc2025-x86_64": [
    "x86_64-%-nanoserver24H2"
],
"windows-nanoserver-ltsc2025-arm64": [
    "arm64-%-nanoserver24H2"
]

(Exact tag names should match what MR 2 / MR 3 publish so that the arm64 entry references the native arm64 helper binary, not a x86_64-binary-arm64-platform-... placeholder.)

4. Documentation

  • Add nanoserver 2025 (amd64 and arm64) to the supported helper image matrix in the runner docs.
  • Note in the changelog that nanoserver 2025 helper images are now available for both amd64 and arm64. Reference #39333 so customers tracking that issue see the path forward.

Out of scope

  • Adding nanoserver:ltsc2019-arm64 or nanoserver:ltsc2022-arm64 — Microsoft does not publish these base images.
  • Making nanoserver the default helper image on Windows. It is a behavioural change and a separate decision; track separately if pursued.
  • Dropping ltsc2019 servercore/nanoserver helper images. Discussed in !6033, @avonbertoldi to raise at the team meeting. Out of scope here.
  • Runtime architecture detection in gitlab-runner.exe and automatic selection of the arm64 helper image — that is MR 5. After MR 4, customers still need to manually set helper_image to the variant they want.
  • Changes to helpers/container/helperimage/windows_info.go to add a baseImage25H2 constant (raised in !6033 review) — deferred to MR 5.

Risk and mitigations

  • FOD / emulation experiments. Do not attempt to enable amd64 emulation inside nanoserver via Feature on Demand. @shanushpt confirmed the CI infrastructure cannot build such an image and it would be brittle even if it worked. Native arm64 binary (from MR 2) is the only supported path.
  • Asymmetric matrix. @avonbertoldi flagged the asymmetric support matrix in !6033. After this MR, the matrix becomes symmetric for ltsc2025 (servercore + nanoserver, both amd64 and arm64) and remains amd64-only for ltsc2019 / ltsc2022 (because Microsoft does not publish arm64 base images for those). Document that explicitly so users do not file follow-up bugs asking for nanoserver:ltsc2022-arm64.
  • CI artifact size. Nanoserver is small but the per-arch split introduced in !6033 (merged) must be preserved when bundling nanoserver into the existing 2025 prebuilt jobs. Confirm artifact size after the first pipeline run.

Acceptance criteria

  • gitlab-runner-helper:windows-nanoserver-ltsc2025-x86_64 and gitlab-runner-helper:windows-nanoserver-ltsc2025-arm64 (or equivalent published tags) are built and pushed by the release pipeline.
  • The arm64 nanoserver image bundles the native arm64 gitlab-runner-helper.exe from MR 2 (no TARGETARCH = "amd64" override, no x86_64-binary-arm64-platform-... pusher entry).
  • Both new images are listed in the supported helper-image matrix in the runner docs.
  • Changelog entry mentions the new nanoserver 2025 variants and references #39333.
  • A docker-windows job using windows-nanoserver-ltsc2025-arm64 on a Windows ARM64 host completes successfully end-to-end.
  • A docker-windows job using windows-nanoserver-ltsc2025 on a Windows amd64 host completes successfully end-to-end.
  • CI artifact-size limits are not exceeded.