fix(docker): make Tentacle images OCI-compliant (FD-492)#1259
Draft
todthomson wants to merge 5 commits into
Draft
fix(docker): make Tentacle images OCI-compliant (FD-492)#1259todthomson wants to merge 5 commits into
todthomson wants to merge 5 commits into
Conversation
8b1e093 to
a909c62
Compare
Strict OCI clients such as Podman reject the Tentacle Kubernetes agent image when it is used as a base image: buildx emits a manifest that mixes Docker and OCI layer media types and wraps it in an OCI index containing provenance attestation manifests. - Build the Kubernetes agent image (which must be multi-arch, so it has to use buildx) with `type=image,oci-mediatypes=true,push=true` and `--provenance=false`, so the whole manifest uses a single, consistent OCI media type with no attestation index. - Replace the deprecated `org.label-schema.*` labels with the standard `org.opencontainers.image.*` annotation keys across all Dockerfiles, and use the SPDX `Apache-2.0` license identifier. Note: the customer-reported `octopusdeploy/tentacle` (docker/linux) image is amd64-only and is built in the TeamCity pipeline, not in this repo. Like Octopus Server's Linux image, the simplest fix there is a classic single- arch `docker build` (no buildx manifest list / provenance); if that pipeline uses buildx, apply the same flags as above. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
a909c62 to
70a0178
Compare
…IONS (FD-492) Use BUILDX_NO_DEFAULT_ATTESTATIONS=1 instead of --provenance=false so the k8s agent buildx build here matches the docker buildx bake step in the TeamCity Linux image build (OctopusDeploy/TeamCity-Configuration#112). The env var is identical across buildx build and bake, covers all default attestations (not just provenance), and avoids passing a CLI flag after the positional build path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/manifests (FD-492) The Dockerfile LABELs set org.opencontainers.image.* on the image config; this also stamps the same metadata as OCI annotations on the image index and each platform manifest (via the buildx image-exporter annotation-index.* / annotation.* options), which is the spec-preferred location that registries and OCI tooling read. Verified locally that the annotations land on both the index and the per-platform manifests. Note: the linux octopusdeploy/tentacle :latest index is assembled by a separate 'docker manifest create' step (TeamCity-Configuration); annotating that index is deferred to the manifest-step follow-up that switches it to 'docker buildx imagetools create --annotation'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review nit (E14): the org.opencontainers.image.* metadata is duplicated across the Dockerfile LABELs, the k8s annotations in Build.Pack.cs, and the TeamCity manifest step. Add short keep-in-sync comments pointing at the sibling definitions so the duplication doesn't silently drift. Comment-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Test seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
…FD-492) Review nit (E16): capture DateTime.UtcNow once and reuse it for both the BUILD_DATE build arg (feeding the Dockerfile created LABEL) and the created OCI annotation, so the image config and manifest annotation report the same instant instead of two UtcNow calls milliseconds apart. Compile-verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Customer FD-492 (Zendesk 209584, ARUP Laboratories) reported that the
octopusdeploy/tentacleDocker image is not OCI compliant: Podman rejects it when it is used as a base image (FROM octopusdeploy/tentacle …).The root cause is not Dockerfile content and not the Debian 11→12 base-image upgrade (#1218 / EFT-3311) — that PR does not touch the manifest format, and building the old vs new image locally shows no difference. The actual problem is inconsistent/mixed manifest media types produced by the build/push pipeline. Docker tolerates this; strict OCI clients like Podman do not.
What Octopus Server actually does (verified in the OctopusDeploy repo)
The triage note claimed Server "fixed the same issue in Jan 2026." I checked the Server repo history directly and that framing is not accurate. There is no
oci-mediatypes/--provenanceflag combination anywhere in Server's history (git log -Sfinds zero hits). Instead, Server builds its Linux image single-architecture (linux/amd64) with the classic Docker builder (DockerTasks.DockerBuild+DockerTasks.DockerPush,nuke-build/Build.DockerImages.cs), producing one self-consistent Docker schema2 manifest with no manifest list and no attestation index. Server avoids the problem by never producing a multi-arch/attestation manifest, rather than by fixing one with flags.Why this PR uses buildx flags instead of copying Server
The Tentacle Kubernetes agent image is genuinely multi-arch (
linux/arm64,linux/amd64) and therefore must be built with buildx and a manifest list — it can't adopt Server's single-arch classic-build approach without dropping arm64. For a multi-arch buildx image, the correct equivalent remedy is to force a single OCI media type and drop the attestation index.Manifest evidence (verified against the published registry)
octopusdeploy/tentacle:latest(the customer's image) — confirmed two distinct OCI violations:The OCI index mixes manifest formats:
application/vnd.oci.image.manifest.v1+json(OCI — buildx)application/vnd.docker.distribution.manifest.v2+json(Docker schema2 — classicdocker build/push)A strict OCI consumer rejects an OCI index that references a Docker-schema2 manifest.
Even the linux/amd64 manifest mixes layer media types —
application/vnd.docker.image.rootfs.diff.tar.gzip×4 (inheriteddebianbase layers) +application/vnd.oci.image.layer.v1.tar+gzip×8 (new layers). This is the literal "mixes two layer format standards", normalized byoci-mediatypes=true.kubernetes-agent-tentacle:latest(this repo's image) — current published index contains 4 manifests: arm64, amd64, plus twounknown/unknownattestation-manifestentries (buildx provenance). Its per-platform layers are already uniformly OCI, so here the defect is purely the attestation index — removed by disabling default attestations (BUILDX_NO_DEFAULT_ATTESTATIONS=1). (Per-platform layer types verified all-OCI.)Changes
Build the Kubernetes agent image with consistent OCI media types (
build/Build.Pack.cs)--output type=image,oci-mediatypes=true,push=trueandBUILDX_NO_DEFAULT_ATTESTATIONS=1so the whole manifest uses a single OCI media type with no attestation index.--loadpath (used by tests/dev) is unchanged.Modernize image labels across all four Dockerfiles
org.label-schema.*namespace (retired 2016) with the standardorg.opencontainers.image.*annotation keys.Apache-2.0for the license.The customer-reported image,
octopusdeploy/tentacle(docker/linux/Dockerfile), is amd64-only on Linux but published in a multi-platform tag alongside the Windows image, and is built in the TeamCity pipeline, not in this repo's NUKE build. Closing FD-492 for that image requires, in TeamCity: (a) build/push the Linux image withoci-mediatypes=trueso its layers are uniformly OCI, and (b) assemble the multi-platform tag so the Windows manifest is also OCI (otherwise the OCI index keeps referencing a Docker-schema2 manifest). This PR fixes the Kubernetes agent image (built here) and the shared label metadata.Testing notes
dotnet build build/_build.csprojsucceeds.docker buildx imagetools inspect --raw <tag>: the index should contain only the two platform manifests (nounknown/unknownattestation manifests), and every layermediaTypeshould beapplication/vnd.oci.image.layer.v1.tar+gzip. Plus apodman pull/FROMsmoke test.🤖 Generated with Claude Code
Note (review follow-up): the attestation switch is standardised on
BUILDX_NO_DEFAULT_ATTESTATIONS=1to match thedocker buildx bakestep in OctopusDeploy/TeamCity-Configuration#112 (identical across buildxbuildandbake, covers all default attestations, and avoids a post-PATH CLI flag).OCI annotations (review follow-up): in addition to the Dockerfile
LABELs (which setorg.opencontainers.image.*on the image config), the k8s agent build now also stamps those annotations onto the image index and each platform manifest via the buildx exporterannotation-index.*/annotation.*options — the spec-preferred location registries/OCI tooling read. Verified locally on a multi-arch build. The linuxoctopusdeploy/tentacle:latestindex is assembled by a separatedocker manifest createstep (TeamCity-Configuration), so its index annotations are deferred to the manifest-step follow-up (switching todocker buildx imagetools create --annotation).