Docker CLI Walkthrough: Login, Pull & Push¶
This is a hands-on walkthrough of the plain Docker CLI against Portalcrane's
registry proxy — login, pull, push, and logout — using
traefik/whoami as a disposable
test image. whoami is a tiny (~8 MB) HTTP server that echoes back request
and network info, which makes it a convenient smoke test: once it's running,
a single curl immediately proves the whole pull/push chain actually
worked.
The two scenarios below show exactly what changes when
REGISTRY_PROXY_AUTH_ENABLED is true (the default) versus false.
Before you start¶
- Portalcrane is reachable at
<host>:8000. - You have an account — local, OIDC, or the built-in admin — with
can_pullandcan_pushon the destination folder. Since we pushwhoamiwith no namespace prefix, it lands in the__root__folder; make sure your account (or a group it belongs to) has both permissions granted there. See Folder-Based Access Control if you need to set that up first. - A Personal Access Token with the
Docker scope. This is not optional: the registry proxy's
docker loginonly accepts a Docker-scoped PAT as the password — your account's real password is rejected there, even for the built-in admin. Generate one from the account menu → Personal Access Tokens before continuing.
Scenario A — Authentication enabled (default)¶
This is the out-of-the-box behavior (REGISTRY_PROXY_AUTH_ENABLED=true).
1. Log in¶
Use your Docker-scoped Personal Access Token as the password — not your account's real password:
If you try your real account password instead, the proxy rejects it outright, even for the built-in admin:
$ docker login <host>:8000
Username: alice
Password:
Error response from daemon: login attempt to https://<host>:8000/v2/ failed with status: 401 Unauthorized
Login succeeding isn't the same as having access
A valid PAT only proves your identity. Whether a given pull or
push is actually allowed is decided per request, against the
folder permissions of the image path you're touching — see step 3 for
what a denied push looks like.
2. Pull whoami from Docker Hub¶
This goes straight to Docker Hub, onto your local machine — Portalcrane isn't involved yet:
$ docker pull traefik/whoami
Using default tag: latest
latest: Pulling from traefik/whoami
...
Status: Downloaded newer image for traefik/whoami:latest
3. Tag it for Portalcrane and push¶
With push access on the folder, you'll see:
$ docker push <host>:8000/whoami:latest
The push refers to repository [<host>:8000/whoami]
...
latest: digest: sha256:2fc8... size: 856
Without it, the proxy returns 403 and Docker surfaces Portalcrane's own
error message:
4. Pull it back from Portalcrane¶
Remove the local copy first so the next pull can only come from Portalcrane, not Docker's local cache:
5. Run it and confirm¶
docker run --rm -d --name whoami-test -p 8080:80 <host>:8000/whoami:latest
curl http://localhost:8080
Hostname: 3f1a9c8e2b4d
IP: 127.0.0.1
IP: 172.17.0.3
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/8.5.0
Accept: */*
6. Log out¶
Docker's credential store is now cleared for that host. Try pulling again without logging back in:
$ docker pull <host>:8000/whoami:latest
Error response from daemon: Head "https://<host>:8000/v2/whoami/manifests/latest": unauthorized
With no Authorization header on the request, the proxy responds 401
Unauthorized — exactly the same as if you'd never logged in at all.
Scenario B — Authentication disabled¶
Set REGISTRY_PROXY_AUTH_ENABLED=false and restart Portalcrane. The proxy
now grants every request unconditionally, before even looking at
credentials or folder permissions — there's no docker login step, and no
permission check runs for anyone, admin or not:
docker pull traefik/whoami
docker tag traefik/whoami <host>:8000/whoami:latest
docker push <host>:8000/whoami:latest # succeeds, no docker login ever run
docker pull <host>:8000/whoami:latest # anyone can pull, no credentials needed
docker logout <host>:8000 is a no-op here, since nothing was ever
authenticated in the first place.
Only for fully trusted networks
This isn't "anonymous read access with folder rules still enforced" —
it's a genuinely open registry: any client that can reach port
8000 can push or pull any image, regardless of folders, groups, or
admin status. Only use this on a network you fully control, and never
expose that port to the internet while it's set this way.
At a glance¶
| Auth enabled (default) | Auth disabled | |
|---|---|---|
docker login required |
Yes | No |
| Credentials checked | Docker-scoped PAT only (a real password is rejected) | Not checked at all |
| Folder permissions enforced | Yes, per pull/push, per folder | No — bypassed entirely |
docker logout effect |
Clears local credentials; next request gets 401 |
No-op |
See Environment Variables → Registry
for the underlying setting, and
Folder-Based Access Control for how can_pull
and can_push are resolved when auth is enabled.