Skip to content

build: publish multi-arch container images to GHCR on release#2035

Open
waveywaves wants to merge 2 commits into
PlakarKorp:mainfrom
waveywaves:add-docker-publish
Open

build: publish multi-arch container images to GHCR on release#2035
waveywaves wants to merge 2 commits into
PlakarKorp:mainfrom
waveywaves:add-docker-publish

Conversation

@waveywaves

@waveywaves waveywaves commented Mar 14, 2026

Copy link
Copy Markdown
Contributor

Builds on PR #2004 (Dockerfile) to automatically publish container images to GHCR on tagged releases.

Related: #1533

Motivation

The Dockerfile landed in #2004, but there's no CI/CD pipeline to build and publish images. Users who want to run plakar in containers (Docker, Kubernetes, Tekton) currently have to build the image themselves.

Changes

  • .goreleaser.yml — adds dockers_v2 configuration to publish a multi-arch image to ghcr.io/plakarkorp/plakar using GoReleaser's pre-built plakar binaries.
  • .github/workflows/release.yml — adds QEMU, Docker Buildx, GHCR login, and keyless cosign signing steps. Adds packages: write and id-token: write permissions.
  • Dockerfile — reuses the existing Dockerfile by adding a goreleaser target that copies the pre-built $TARGETPLATFORM/plakar binary from GoReleaser's build context. The default Dockerfile behavior still performs the full source build for manual/standalone Docker builds.

Image tags

On a tagged release like v1.2.0:

  • ghcr.io/plakarkorp/plakar:v1.2.0 (multi-arch manifest)
  • ghcr.io/plakarkorp/plakar:latest (only for stable releases, not pre-releases like v1.2.0-beta)

Architectures: linux/amd64, linux/arm64

Signing

Published image tags are signed with cosign using GitHub Actions OIDC keyless signing. No private signing key is stored in the repository; the workflow receives an ephemeral certificate through the GitHub OIDC token.

Example verification:

cosign verify ghcr.io/plakarkorp/plakar:v1.2.0 \
  --certificate-identity-regexp 'https://github.com/PlakarKorp/plakar/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Usage

docker pull ghcr.io/plakarkorp/plakar:latest
docker run ghcr.io/plakarkorp/plakar version

Notes

  • The :latest tag uses the existing MAKE_LATEST_RELEASE logic — only pushed and signed when the tag has no hyphen
  • GoReleaser's dockers_v2 builds the multi-arch manifest directly, so the public release tags are :<version> and :latest rather than separate architecture-suffixed tags
  • The existing Dockerfile remains the source-build path for manual Docker builds; the goreleaser target is only for release packaging of GoReleaser's pre-built binary

@waveywaves
waveywaves force-pushed the add-docker-publish branch 2 times, most recently from f1d0d48 to 1803a14 Compare March 14, 2026 16:10
@waveywaves
waveywaves marked this pull request as ready for review March 14, 2026 16:16
Comment thread .github/workflows/release.yml
@waveywaves
waveywaves force-pushed the add-docker-publish branch 4 times, most recently from 7338c2d to b5b734a Compare March 18, 2026 08:39
@waveywaves

Copy link
Copy Markdown
Contributor Author

cc @omar-polo @mathieu-plak gentle nudge for a review

@waveywaves
waveywaves force-pushed the add-docker-publish branch 2 times, most recently from df9d3ff to ccb4b20 Compare April 14, 2026 16:09
@brmzkw

brmzkw commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Hello, and thank you for the PR.

A few questions:

  • Why do we need cosign? how does it work?
  • Apparently, dockers from goreleaser is deprecated. Why use it and not dockers_v2?
  • Is there any reason why not to use (and improve if necessary) the existing Dockerfile?

@poolpOrg

Copy link
Copy Markdown
Collaborator

@waveywaves nudge in case you didn't see @brmzkw 's question

@waveywaves
waveywaves force-pushed the add-docker-publish branch from ccb4b20 to 0912f9d Compare June 2, 2026 09:12
@waveywaves

waveywaves commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @brmzkw, and thanks for the nudge @poolpOrg. Sorry I missed this.

I've pushed an update addressing the points:

  • Switched from the deprecated dockers + docker_manifests config to dockers_v2. GoReleaser now builds the multi-arch manifest directly and publishes ghcr.io/plakarkorp/plakar:<tag> plus :latest for stable releases.
  • Reused the existing Dockerfile instead of keeping a separate Dockerfile.goreleaser. The Dockerfile now has a goreleaser target that copies GoReleaser's pre-built $TARGETPLATFORM/plakar binary, while the default Dockerfile path still performs the full source build for manual/standalone Docker builds.
  • Kept cosign intentionally: it uses GitHub Actions OIDC keyless signing (id-token: write), so there is no private signing key to manage. The release workflow signs the version tag, and also signs :latest when the release is stable. This gives users a way to verify the GHCR image provenance with cosign verify.

I also validated the updated GoReleaser config with:

MAKE_LATEST_RELEASE=true go run github.com/goreleaser/goreleaser/v2@latest check

and tested the Dockerfile's goreleaser target with a minimal $TARGETPLATFORM/plakar build context.

Add GoReleaser docker configuration to build and publish container
images to ghcr.io/plakarkorp/plakar on tagged releases. Images are
built for linux/amd64 and linux/arm64 with a multi-arch manifest.

The release workflow gains QEMU, Buildx, and GHCR login steps.
A minimal Dockerfile.goreleaser is used by GoReleaser to package the
pre-built binary (the existing Dockerfile remains for manual builds).

The :latest tag is only pushed for stable releases (tags without
hyphens), matching the existing MAKE_LATEST_RELEASE logic.

Co-authored-by: Claude <noreply@anthropic.com>
@waveywaves
waveywaves force-pushed the add-docker-publish branch from 0912f9d to 5396fce Compare June 9, 2026 11:23
@waveywaves

Copy link
Copy Markdown
Contributor Author

Rebased this on latest main; CI is green again.

I also re-ran the GoReleaser config check locally:

MAKE_LATEST_RELEASE=true go run github.com/goreleaser/goreleaser/v2@latest check

Gentle nudge for another look when you get a chance.

@waveywaves

Copy link
Copy Markdown
Contributor Author

@brmzkw in a rush I didn't answer your question earlier. Cosign is required in supply chain security to cryptographically verify authenticity, ensure code integrity, and establish provenance for software artifacts. Here is exactly how it works at a glance. Signing: A developer uses a cryptographic key (or a "keyless" method) to create a digital signature for their compiled software or container image. Storage: Cosign pushes this digital signature directly to an Open Container Initiative (OCI) registry (like Docker Hub, GHCR or a private registry) right alongside the software itself. Verification: Before deploying the software, the target system uses the developer’s corresponding public key to verify that the signature matches the software artifact.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds automated publishing of multi-architecture container images to GitHub Container Registry (GHCR) as part of the tagged release process, leveraging GoReleaser-built binaries and signing images via keyless cosign.

Changes:

  • Add GoReleaser dockers_v2 config to build/push a multi-arch image (linux/amd64, linux/arm64) to ghcr.io/plakarkorp/plakar.
  • Extend the release GitHub Actions workflow to set up QEMU/Buildx, authenticate to GHCR, and sign published images with cosign (OIDC).
  • Refactor the Dockerfile to introduce a shared runtime base and a GoReleaser-specific target that copies in the prebuilt binary.

Reviewed changes

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

File Description
Dockerfile Introduces runtime-base and a goreleaser target to package GoReleaser-built binaries while preserving source-build behavior for manual builds.
.goreleaser.yml Adds dockers_v2 configuration to publish a multi-arch image to GHCR with appropriate OCI labels.
.github/workflows/release.yml Updates release workflow to run only on v* tags, enable GHCR publishing, set up multi-arch tooling, and sign images with cosign via OIDC.

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

Comment thread .github/workflows/release.yml Outdated
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.

4 participants