Tu Vu
08/11/2025, 10:42 AMMarvin
08/11/2025, 10:42 AMMarvin
08/11/2025, 10:46 AMgcloud auth configure-docker us-central1-docker.pkg.dev
This writes a credHelpers entry in your Docker config so Docker can fetch/refresh tokens automatically via gcloud.
- Verify from the same environment that your Prefect worker will use:
docker pull us-central1-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG
If this fails, Prefect will fail too.
Alternatives (useful for non-interactive or locked-down hosts)
- Short-lived token (simple, but expires ~1 hour):
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin <https://us-central1-docker.pkg.dev>
- Service account key (persists until key rotation; handle with care):
docker login -u _json_key -p "$(cat /path/to/key.json)" <https://us-central1-docker.pkg.dev>
Common gotchas
- Wrong user/HOME: Docker reads credentials from $DOCKER_CONFIG/config.json
or $HOME/.docker/config.json
. If you run the Prefect worker as a different user (systemd, container, sudo), it may not see your credentials.
- Either place config.json
under that user’s home, or set DOCKER_CONFIG
for the worker process.
- Example systemd override:
[Service]
Environment=DOCKER_CONFIG=/home/prefect/.docker
- Hostname mismatch: make sure the registry you log into matches exactly what you pull, e.g. us-central1-docker.pkg.dev
.
- Test outside Prefect first: run docker pull
from the same shell/service environment that runs prefect worker start
. If that fails, fix auth there before blaming the poor worker.
Quick checklist to fix your case
1. On the VM running the worker:
- gcloud auth configure-docker us-central1-docker.pkg.dev
- Confirm the active identity has access (or that gcloud is using the VM’s service account).
2. Ensure the Prefect worker process sees the same Docker config:
- If you start via CLI in a shell, it usually does.
- If it’s a service, set DOCKER_CONFIG
as above.
3. Test:
docker pull us-central1-docker.pkg.dev/mlops-461404/xxx/IMAGE:TAG
4. Restart the worker and try again:
prefect worker start -p <your-docker-work-pool>
If you’re on Prefect 2.x with a Docker work pool, the above still applies; Prefect 3.x primarily uses the Process worker, but either way, Docker auth is handled by the host.
Helpful docs
- Google Artifact Registry auth for Docker: GAR authentication docs
- Prefect 3 concepts: workers and execution (background on how workers interact with infra) Prefect 3: Workers
- Serverless/infra overview (for context) Prefect 3: Serverless/infra
If you can share:
- Prefect version (2.x Docker work pool vs 3.x)
- How you’re starting the worker (CLI vs systemd/container) and which user it runs as
- Whether docker pull ...
succeeds from that same environment
…I can point you to the exact incantation you need. I know, thrilling.Tu Vu
08/11/2025, 10:49 AMversion: "3.9"
services:
prefect-worker:
image: prefecthq/prefect:3-latest
container_name: prefect-worker-pool
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
environment:
- PREFECT_API_URL=<http://xxx:4200/api>
- PREFECT_API_AUTH_STRING=admin:xxx
- PREFECT_SERVER_API_AUTH_STRING=admin:xxx
- DOCKER_HOST=unix:///var/run/docker.sock
command: ["prefect", "worker", "start", "--install-policy", "always", "--pool", "my-docker-pool"]
Marvin
08/11/2025, 10:49 AMMarvin
08/11/2025, 10:52 AMdocker login -u _json_key -p "$(cat /path/to/gar-key.json)" <https://us-central1-docker.pkg.dev>
2) Mount that config into the worker container and use the same DOCKER_HOST:
version: "3.9"
services:
prefect-worker:
image: prefecthq/prefect:3-latest
container_name: prefect-worker-pool
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
- /root/.docker:/root/.docker:ro # adjust to wherever you ran `docker login`
environment:
- PREFECT_API_URL=<http://xxx:4200/api>
- PREFECT_API_AUTH_STRING=admin:xxx
- PREFECT_SERVER_API_AUTH_STRING=admin:xxx
- DOCKER_HOST=unix:///var/run/docker.sock
command: ["prefect", "worker", "start", "--install-policy", "always", "--pool", "my-docker-pool"]
Important: Do NOT use gcloud auth configure-docker
for this mount approach unless you also install the gcloud credential helper inside the container. The helper referenced in config.json must exist where the client runs (inside the container), not just on the host.
Option B — Login inside the container at startup using a Docker secret
If you don’t want to mount your host’s `~/.docker`:
version: "3.9"
services:
prefect-worker:
image: prefecthq/prefect:3-latest
container_name: prefect-worker-pool
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:rw
secrets:
- gar_key
environment:
- PREFECT_API_URL=<http://xxx:4200/api>
- PREFECT_API_AUTH_STRING=admin:xxx
- PREFECT_SERVER_API_AUTH_STRING=admin:xxx
- DOCKER_HOST=unix:///var/run/docker.sock
entrypoint: ["/bin/sh","-lc"]
command: >
docker login -u _json_key -p "$(cat /run/secrets/gar_key)" <https://us-central1-docker.pkg.dev> &&
prefect worker start --install-policy always --pool my-docker-pool
secrets:
gar_key:
file: ./gar-key.json
Option C — Use gcloud inside the container (only if you really want ADC/cred helpers)
Build a small image that installs gcloud and run gcloud auth configure-docker us-central1-docker.pkg.dev
in the container. This works, but it’s heavier than A/B.
Sanity checks
- Remove angle brackets around the API URL in compose: use <http://xxx:4200/api>
, not <http://...>
.
- From inside the running worker container, verify:
docker pull us-central1-docker.pkg.dev/mlops-461404/xxx/IMAGE:TAG
If this fails, Prefect will fail too.
- Make sure the service account you’re using has at least roles/artifactregistry.reader on the repo/project.
- The registry host must match exactly: us-central1-docker.pkg.dev
.
Docs, in case you like bedtime reading
- GAR auth for Docker: Google Artifact Registry authentication
- Prefect 3 workers overview: Prefect 3: Workers
If you tell me whether you prefer mounting a config (A) or logging in at start with a secret (B), I’ll hand you a ready-to-paste compose specific to your paths. I live to serve. Sort of.