Skip to content

feat: add OCI multi-registry support (ghcr.io, quay.io, mcr.microsoft.com, etc.) - #7

Open
EpicTGuy wants to merge 1 commit into
jjlin:mainfrom
EpicTGuy:feat/oci-multi-registry-support
Open

feat: add OCI multi-registry support (ghcr.io, quay.io, mcr.microsoft.com, etc.)#7
EpicTGuy wants to merge 1 commit into
jjlin:mainfrom
EpicTGuy:feat/oci-multi-registry-support

Conversation

@EpicTGuy

Copy link
Copy Markdown

Summary

The script was previously hardcoded for Docker Hub only. This PR adds support for any OCI Distribution Spec compliant registry by dynamically discovering the auth endpoint via the WWW-Authenticate header returned on a 401 response.

Tested against: docker.io, ghcr.io, quay.io, registry.gitlab.com, mcr.microsoft.com.

Changes

Script

  • Registry detection: if the first path component of the image spec contains a dot (e.g. ghcr.io/user/image), it is treated as a registry hostname
  • Dynamic auth discovery: probe GET /v2/ to capture the WWW-Authenticate header, then parse realm and service to build the token URL
  • No-auth registries: if /v2/ returns 200 with no WWW-Authenticate (e.g. mcr.microsoft.com), proceed without a token
  • Multi-arch index support: handle both application/vnd.oci.image.index.v1+json and application/vnd.docker.distribution.manifest.list.v2+json for platform resolution
  • Docker Hub backward compat: the original flow (via hub.docker.com API + auth.docker.io) is fully preserved

README

  • Document OCI registry support and how auth discovery works
  • Update examples to include a GHCR pull

Implementation notes

  • Use GET instead of HEAD for the /v2/ probe — some registries (e.g. ghcr.io) return 405 on HEAD
  • Use tr -d '"[:space:]"' before parsing the manifest list JSON — registries may return pretty-printed JSON; spaces break the grep/sed pipeline (safe because OCI manifest list string values never contain spaces)
  • Take only head -1 from extract '"mediaType"' to avoid matching nested entries in the manifests array

Test results

Registry Image Result
docker.io hello-world:latest PASS
docker.io alpine:3.18 PASS
ghcr.io toeverything/affine:stable PASS (48 794 files)
ghcr.io toeverything/affine:sha256:44c65e... PASS (digest ref)
quay.io prometheus/prometheus:latest PASS
registry.gitlab.com gitlab-org/gitlab-runner:latest PASS
mcr.microsoft.com hello-world PASS

The script was previously hardcoded for Docker Hub only. This patch adds
support for any OCI Distribution Spec compliant registry by dynamically
discovering the auth endpoint via the WWW-Authenticate header returned
on a 401 response.

Changes:
- Detect registry prefix from image spec (hostname containing a dot)
- For non-Docker Hub registries: probe /v2/ to discover Bearer auth realm
  and service via WWW-Authenticate header
- Handle registries that require no auth (e.g. mcr.microsoft.com returns
  200 on /v2/ with no WWW-Authenticate)
- Support both OCI image index (vnd.oci.image.index.v1+json) and Docker
  manifest list (vnd.docker.distribution.manifest.list.v2+json) for
  multi-arch platform resolution
- Use GET instead of HEAD for /v2/ probe (some registries return 405 on HEAD)
- Keep Docker Hub flow (hub.docker.com API) fully intact for backward compat

Tested against: docker.io, ghcr.io, quay.io, registry.gitlab.com, mcr.microsoft.com

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EpicTGuy pushed a commit to EpicTGuy/AFFiNE_ynh that referenced this pull request Apr 22, 2026
AFFiNE's server image is hosted on ghcr.io, which requires OCI Bearer
auth not supported by the vendored docker-image-extract in YunoHost 12.1.x.

Embeds the patched script from jjlin/docker-image-extract#7 as a workaround
until YunoHost/yunohost#2293 is merged. Applied in both install and upgrade.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant