feat(docker-publish): reusable chunked docker publish workflow#13
Merged
Conversation
Add a reusable workflow that builds a container image and pushes it to the Harbor registry using chunked blob uploads via regctl, avoiding 413/504 failures when a layer exceeds a proxy's request-body limit (e.g. Cloudflare's 100 MB). Plain docker/buildx push cannot chunk a blob, so the image is built to an OCI archive and pushed with regctl (--blob-chunk / --blob-max). Optionally signs the manifest digest with cosign. Generic inputs (image-name, version, context, optional Gradle build-command, tags, chunk size, sign toggle) make it consumable by any OneLiteFeather project. Documented in the README with usage examples and required secrets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ping regctl registry login performs a verification ping that fails with "unauthorized" against Harbor even when the credentials are valid. Use the proven docker/login-action to write ~/.docker/config.json (which regctl reuses for auth) and have regctl only attach the blob-chunk host config with --skip-check, so no separate regctl auth ping runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ogin Harbor is fronted by a Cloudflare tunnel that blocks `docker login` (403) but allows regctl (the intended chunked client). Authenticate with regctl and pass --skip-check so its anonymous connectivity ping (answered with 401 by a private registry) does not fail the step; credentials are exercised during the push. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expose req-concurrent (concurrent layer uploads; chunks within a layer stay sequential per the registry protocol) and document that larger blob-chunk values reduce round-trips and storage-backend multipart parts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Align the reusable workflow with the proven Otis pipeline: sign keyless using the GitHub Actions OIDC identity instead of a cosign key/password. Drop the COSIGN_KEY/COSIGN_PASSWORD secrets, add id-token: write, and document that the calling job must grant id-token: write when signing. Bump the default regctl-version to v0.11.5. 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.
Summary
Adds a reusable workflow
docker-publish.ymlthat builds a container image and pushes it to the OneLiteFeather Harbor registry using chunked blob uploads viaregctl.Why
Plain
docker push/buildxuploads each layer blob in a single monolithic request. When a layer exceeds the request-body limit of a proxy in front of the registry (e.g. Cloudflare's 100 MB), the push fails with413 Request Entity Too Largeor504 Gateway Timeout.buildxhas no chunk-size knob.This workflow builds the image to an OCI archive (no push), then pushes it with
regctl, which splits blobs above--blob-maxinto--blob-chunk-sized PATCH requests (default 50 MiB — safely below 100 MB). Remaining tags are added via in-registry copy (blob mount), and the manifest digest is signed once with cosign.Generic inputs
image-name,version,context, optional Gradlebuild-command+setup-java,extra-tags,blob-chunk,sign,regctl-version. Secrets:HARBOR_REGISTRY/HARBOR_USERNAME/HARBOR_PASSWORD(required) andCOSIGN_KEY/COSIGN_PASSWORD(whensign: true). Outputs:image,digest.Docs
README updated: workflows table, usage examples (Gradle-built context + plain Dockerfile), required secrets.
🤖 Generated with Claude Code