Pull from a private registry
A private container image deploys exactly like a public one — Koo just needs credentials to pull it from your registry. Private images are available on every plan.
Add credentials when you create the service
- Open the environment canvas, click New service (or right-click the canvas), and choose Docker Image.
- Paste the image reference, as for any container deploy.
- Expand Private image and enter your registry username and an access token — a personal access token (PAT) works as the pull password.
- Click Add service, then press Deploy on the changes bar.
The two fields go together: enter both or neither. Docker Hub needs your real account username alongside the token; most other registries (GHCR, GitLab) accept any non-empty username.
Manage credentials on an existing service
Open the service's drawer and go to Settings — the Registry credentials field under Source shows whether credentials are stored, never the values themselves.
- Update credentials stages a new username + token pair, replacing the stored one.
- Remove stages their removal — right for an image that has become public.
Like other service edits, both apply on the next Deploy.
The API shape
Credentials ride the write-only imageCredentials field beside the image source — see the Services API:
{ "source": { "type": "image", "image": { "ref": "ghcr.io/acme/web:1.4.2" } }, "imageCredentials": { "username": "acme", "token": "<registry access token>" }}They are write-only end to end: no read ever returns them — a service read exposes only the boolean imagePullCredentialsSet. On a PATCH, omitting the field leaves the stored credentials unchanged, sending a new object rotates them, and sending null clears them.
Supplying the same credentials on several services stores them once — one stored secret, not a copy per service.
The registry host is pinned
When credentials are written, they are pinned to the image's registry host. Pointing the service at an image on a different registry host is refused until you re-supply credentials (or remove the stored ones) — a safety guard, so your stored credentials can never be presented to a registry they weren't created for.
Troubleshooting
A failed pull shows an image_pull_failed error on the service's status, carrying the registry's own reason. The usual causes: an expired or revoked token, the wrong username form for the registry (Docker Hub wants the account name), or a tag that doesn't exist.