Repository navigation
build(release): build the container image with melange + apko - #25
Merged
Merged
Conversation
Replace the hand-rolled multi-stage Dockerfile with melange (compiles the binary into a signed Wolfi apk) + apko (assembles a minimal, multi-arch, nonroot image). GoReleaser still owns the binary release assets. - melange.yaml + apko.yaml: go/build pipeline (-trimpath, -buildid=, -s -w, CGO_ENABLED=0; version/commit/date via --vars-file), distroless-equivalent runtime (uid 65532, ca-certificates, tzdata, no shell). The Wolfi base floats to latest (fresh CAs, low CVE); exact versions are recorded in the per-build SBOM + provenance attestation rather than pinned. - release.yml container path: melange-build native matrix (amd64 + arm64, no QEMU) -> apko publish multi-arch index -> 2-arch manifest assertion -> keyless cosign sign -> attest-build-provenance -> syft image SBOM + attest-sbom. Per-arch ephemeral signing keys (distinct filenames; private key never leaves its runner). binary-release-assets unchanged except setup-go now reads go.mod. - release-dry-run.yml + security-scan.yml mirrored to melange/apko. - compose.yaml: drop build:, run the prebuilt template-go-api:dev image; new mise tasks image-local / stack-up build it locally (melange --runner docker, so it works on macOS). release-please extra-files bump melange.yaml + apko.yaml. - Delete Dockerfile, .dockerignore, .go-version (both setup-go steps read go.mod). - Prose updated (README/CONTRIBUTING/DELETE_ME/docs). Verified locally: melange build -> apko assemble -> docker run smoke (--version + openapi 3.0.3), nonroot uid 65532; and `mise run image-local` + `docker compose up` brings up postgres/migrate/seed/api with GET /v1/todos returning the seeded todos (401 without a key). The tag-triggered publish/sign/attest path is structurally complete but is only fully exercised by a real tag (validate with a throwaway prerelease tag against a scratch GHCR namespace before relying on a release). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
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.
Summary
PR 2 of 2 in the dev-tooling migration. Replaces the hand-rolled multi-stage
Dockerfilewith melange (compiles the binary into a signed Wolfi apk) + apko (assembles a minimal, multi-arch, nonroot OCI image), and adds a keyless cosign signature. Builds on PR #24 (mise tooling). GoReleaser, the binary release assets, and Release Please are unchanged (GoReleaser still owns the downloadable binaries).What changed
melange.yaml+apko.yaml(new) —go/buildpipeline (-trimpath,-buildid=,-s -w,CGO_ENABLED=0;version/commit/datestamped via--vars-file); runtime is the distroless equivalent (uid 65532,ca-certificates-bundle,tzdata, no shell). The image is built without a Dockerfile.release.yml— the two buildx jobs are replaced by:melange-build(native matrixamd64/ubuntu-24.04+arm64/ubuntu-24.04-arm, no QEMU, per-arch ephemeral keys) →container-image-release(apko publishmulti-arch index → 2-arch manifest assertion → smoke test → keylesscosign sign→attest-build-provenance→ syft image SBOM +attest-sbom).binary-release-assetsunchanged exceptsetup-go→go.mod.release-dry-run.yml+security-scan.yml— mirrored to melange/apko (dry-run builds + assembles without push/sign/attest; Trivy scans the apko image).compose.yaml— dropsbuild:; runs the prebuilttemplate-go-api:dev. Newmise run image-local/mise run stack-uptasks build it locally (melange--runner docker, works on macOS).release-please-config.jsongainsextra-filesto bumpmelange.yaml/apko.yaml.Dockerfile,.dockerignore,.go-version.README.md,CONTRIBUTING.md,DELETE_ME.md,docs/docs/index.md).Base pinning decision
apko.lock.jsonwas evaluated and not adopted:apko lockrequires resolving the per-build@localapp package (for all arches), and a committed lock would pin a stale app checksum that breaks the next release. Instead the Wolfi base floats to latest (fresh CA bundle/timezones, low CVE surface) and the exact resolved versions are captured in the per-build SBOM + provenance attestation — the idiomatic Wolfi posture.Supply chain (preserve-or-better)
sbom:trueprovenance: mode=maxattest-build-provenanceon the index digestimagetools inspect)Verification
melange build→apko build→docker runsmoke (--version+openapi: 3.0.3), image runs as uid 65532, ~24 MB.mise run image-local+docker compose up→ postgres/migrate/seed/api all healthy;GET /v1/todoswithdev-user-keyreturns the seeded todos,401without a key.moon run root:checkgreen.release-dry-run(dispatch) and a throwaway prerelease tag against a scratch GHCR namespace before the first real release.docker buildx imagetools inspectrelies on buildx being preinstalled on the runner (it is onubuntu-24.04).🤖 Generated with Claude Code