Skip to content

Private Docker Registry (CI/CD Setup)

Registry URL: https://docker.registry.hochguertel.work UI URL: https://docker-ui.registry.hochguertel.work Auth: Authentik API tokens (CLI) + Authentik SSO forward-auth (UI)

Docker Registry Auth Architecture

  • CLI/CI login: Authentik API token as password — auth-bridge validates against Authentik API, issues RS256-signed JWT (15 min expiry), Docker Registry accepts JWT as Bearer token
  • Browser UI: Authentik SSO forward-auth via Traefik + Joxit preauth helper for per-user bearer tokens
  • Mirror: Pull-through cache for docker.io (internal, no auth)
  1. podman push docker.registry.hochguertel.work/myimage:latest
  2. Traefik routes /v2/ to Docker Registry
  3. Registry returns 401 with WWW-Authenticate: Bearer realm=...
  4. CLI sends GET /auth/token with Authorization: Basic base64(infra:<api-token>)
  5. auth-bridge validates the API token against Authentik /api/v3/core/users/me/
  6. Token server issues RS256-signed JWT with ACL claims
  7. CLI retries push with Authorization: Bearer <jwt>
  8. Registry validates JWT, checks ACL, accepts push
Authentik GroupPullPushDelete
adminsYesYesYes
developersYesYesNo
usersYesNoNo

The infra service account is in developers + users — can pull and push.

Terminal window
echo "<api-token>" | podman login docker.registry.hochguertel.work -u infra --password-stdin
Terminal window
echo "<api-token>" | docker login docker.registry.hochguertel.work -u infra --password-stdin
Terminal window
podman tag myapp:latest docker.registry.hochguertel.work/myorg/myapp:latest
podman push docker.registry.hochguertel.work/myorg/myapp:latest
podman pull docker.registry.hochguertel.work/myorg/myapp:latest
- name: Login to private registry
run: |
echo "${{ secrets.DOCKER_REGISTRY_TOKEN }}" | \
podman login ${{ secrets.DOCKER_REGISTRY_URL }} -u infra --password-stdin
- name: Build and push
run: |
IMAGE="${{ secrets.DOCKER_REGISTRY_URL }}/my-org/myapp:${{ github.ref_name }}"
podman build -t "${IMAGE}" .
podman push "${IMAGE}"
AspectDocker Registrynpm (Verdaccio)PyPI (DevPI)
AuthJWT (RS256) via auth-bridgehtpasswd (Basic)htpasswd (Basic)
TokenAuthentik API tokenhtpasswd passwordAuthentik API token
JWT expiry15 min (auto-renewed)N/AN/A
ACLGroup-basedScope-basedIndex-based
Push toolpodman pushnpm publishuv publish

The complete guide with troubleshooting, token management, operations, and mirror configuration is in the registries repo: /opt/services/registries/docs/docker-registry-guide.md