Skip to content

fix: publish distroless Docker image with dockers v2#716

Open
Siddhant-K-code wants to merge 3 commits into
openfga:mainfrom
Siddhant-K-code:fix/distroless-dockers-v2
Open

fix: publish distroless Docker image with dockers v2#716
Siddhant-K-code wants to merge 3 commits into
openfga:mainfrom
Siddhant-K-code:fix/distroless-dockers-v2

Conversation

@Siddhant-K-code

@Siddhant-K-code Siddhant-K-code commented Jun 28, 2026

Copy link
Copy Markdown
Member

Summary

  • Move the Docker image from scratch to gcr.io/distroless/static-debian13:nonroot so public CA roots are available in the container.
  • Replace per-arch dockers + docker_manifests with GoReleaser dockers_v2, which is no longer experimental as of GoReleaser v2.16.
  • Sign the published Docker image by immutable digest and select the released multi-platform digest by exact Git tag and platform metadata.

Docs

  • README Docker section now notes public CA support and calls out that private/internal CAs still need to be provided by the user.

Validation

Ran:

  • make build
  • go test ./...
  • goreleaser release --clean --config .goreleaser.yaml --snapshot --skip sign,publish,announce,docker
  • focused dockers_v2 GoReleaser validation with a local fake Docker shim
  • GoReleaser v2.16 Docker signing tests for DockerImageV2 artifact selection
  • workflow digest jq check against a representative multi-platform Docker Image artifact

Reviewer command with Docker available:

  • goreleaser release --clean --config .goreleaser.yaml --snapshot --skip sign,publish,announce

Reference: https://goreleaser.com/blog/goreleaser-v2.16/#docker-v2-is-no-longer-experimental

Fixes #639

Copilot AI review requested due to automatic review settings June 28, 2026 04:57
@Siddhant-K-code Siddhant-K-code requested review from a team as code owners June 28, 2026 04:57
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6413edc7-f0c0-408e-9d57-f84f4f6d1e03

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Switches the Docker base image from scratch to gcr.io/distroless/static-debian13:nonroot, adopts GoReleaser's dockers_v2 for native multi-platform builds (linux/amd64, linux/arm64), updates the CI digest step to select the new artifact type, and adds a README note about CA certificates.

Changes

Distroless Multi-Platform Docker Migration

Layer / File(s) Summary
Dockerfile and GoReleaser multi-platform config
.goreleaser.Dockerfile, .goreleaser.yaml
Dockerfile switches from scratch to gcr.io/distroless/static-debian13:nonroot, adds ARG TARGETPLATFORM, and copies the binary from ${TARGETPLATFORM}/fga. GoReleaser replaces the dockers + docker_manifests blocks with a single dockers_v2 block targeting both platforms, with unified OCI-labeled tags.
CI image digest step
.github/workflows/main.yaml
Updates the "Image digest" step to select a Docker Image artifact matching openfga/cli:${GITHUB_REF_NAME} with both linux/amd64 and linux/arm64 platforms, and parses the image name from the artifact's .path field via jq.
README Docker section
README.md
Adds a note that the Docker image is multi-platform and includes CA certificates for HTTPS connections to OpenFGA endpoints.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • SoulPancake
  • curfew-marathon
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR addresses the issue by replacing scratch with distroless, preserving multi-platform GoReleaser publishing, and keeping the release flow stable.
Out of Scope Changes check ✅ Passed The changes stay within scope: Docker image base, GoReleaser config, digest extraction, and related docs for the publishing flow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately captures the main change: publishing a distroless Docker image via GoReleaser dockers v2.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the release pipeline to publish a multi-platform Docker image based on a distroless (static, nonroot) base so that CA certificates are present at runtime, fixing TLS failures when the CLI runs in Docker and connects to HTTPS endpoints.

Changes:

  • Switch .goreleaser.Dockerfile from scratch to distroless static nonroot and adjust the binary copy path.
  • Replace per-arch dockers + docker_manifests with a single multi-platform dockers_v2 configuration in GoReleaser v2.
  • Update the GitHub Actions workflow logic that extracts/publishes the released image digest from GoReleaser artifacts, and document the CA cert behavior in the README.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
README.md Documents the Docker image’s multi-platform nature and CA certificate availability.
.goreleaser.yaml Migrates Docker publishing configuration to dockers_v2 for multi-platform builds.
.goreleaser.Dockerfile Moves the runtime base image to distroless static nonroot and updates how the binary is copied in.
.github/workflows/main.yaml Adjusts digest extraction to match dockers_v2 “Docker Image” artifacts for provenance/verification steps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
Comment thread .goreleaser.yaml
Comment thread .github/workflows/main.yaml Outdated

@SoulPancake SoulPancake left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dockers_v2 is currently still experimental.
There will be a stable release with goreleaser v3 launch, so we probably shouldn't use it right now

@SoulPancake

Copy link
Copy Markdown
Member

@Siddhant-K-code Siddhant-K-code force-pushed the fix/distroless-dockers-v2 branch from c365b63 to bab9eeb Compare June 28, 2026 13:29
@Siddhant-K-code Siddhant-K-code changed the title fix: publish distroless Docker image with GoReleaser v2 fix: publish distroless Docker image with stable GoReleaser config Jun 28, 2026
@Siddhant-K-code

Copy link
Copy Markdown
Member Author

Good call. I pushed bab9eeb and removed dockers_v2 completely.

This now stays on the documented dockers + docker_manifests flow and only changes the per-arch image builds from use: buildx to use: docker: https://goreleaser.com/customization/package/docker/

That keeps the existing manifest publishing shape, avoids the experimental dockers_v2 path, and does not add the PR #632 buildx --provenance=false workaround. The repo's SLSA image-provenance job is unchanged.

I also folded in the smaller review notes:

  • clarified that the bundled CA roots cover publicly trusted CAs, not private/internal PKI
  • removed duplicate exact-version Docker tag templates ({{ .Tag }} is the canonical vX.Y.Z tag)
  • removed the unused workflow variable

One caveat: GoReleaser v2.16 now marks dockers/docker_manifests as deprecated in favor of dockers_v2: https://goreleaser.com/deprecations#dockers. I think that is the right tradeoff here given the concern about dockers_v2 still evolving before v3.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@SoulPancake

Copy link
Copy Markdown
Member

Oh wait, I think my earlier concern here is outdated.

This note from May means dockers_v2 is no longer experimental:
goreleaser/goreleaser@e8d5686
https://goreleaser.com/blog/goreleaser-v2.16/?utm_source=chatgpt.com#docker-v2-is-no-longer-experimental

I think it should be fine to move to dockers_v2 after all.Sorry for the back and forth on this, Let's do dockers_v2
@Siddhant-K-code

@Siddhant-K-code Siddhant-K-code force-pushed the fix/distroless-dockers-v2 branch from bab9eeb to c7f6dc4 Compare June 28, 2026 18:05
@Siddhant-K-code Siddhant-K-code changed the title fix: publish distroless Docker image with stable GoReleaser config fix: publish distroless Docker image with dockers v2 Jun 28, 2026
@Siddhant-K-code

Copy link
Copy Markdown
Member Author

Yep, that changes the decision. I pushed c7f6dc4 and moved this back to dockers_v2.

I kept the other review fixes in place:

  • no duplicate exact-version tags ({{ .Tag }} is the exact vX.Y.Z tag)
  • README now says public CAs, with private/internal CAs called out separately
  • workflow digest lookup selects the Docker Image artifact for the exact tag and checks both linux/amd64 and linux/arm64

I also updated the PR description and added the v2.16 reference. Local focused dockers_v2 validation is green, and the generated buildx command does not include the old --provenance=false workaround.

@SoulPancake SoulPancake left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dockers_v2 produces multiplatform image artifacts
docker_signs still targets the artifacts: manifests
So will this work with dockers_v2? I think it might remain unsigned

Maybe we should do something like this https://github.com/enix/x509-certificate-exporter/blob/a1a454659e5f8b403f7eeb33ad97f167a9e22e4d/.goreleaser.yaml#L304

@Siddhant-K-code

Copy link
Copy Markdown
Member Author

Good catch. I pushed 2796ba5 to make this explicit.

The config now uses docker_signs.artifacts: images and signs ${artifact}@${digest}. That lines up with GoReleaser v2.16’s dockers_v2 path:

Validated locally with:

  • make build
  • go test ./...
  • goreleaser release --clean --config .goreleaser.yaml --snapshot --skip sign,publish,announce,docker
  • focused fake-Docker dockers_v2 run
  • GoReleaser v2.16 go test ./internal/pipe/sign -run 'TestDockerSign(Default|Artifacts)$'

So the published image will be signed by digest during the release publish flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move Docker image to distroless while preserving GoReleaser compatibility

3 participants