Tutorial 9 · Private images¶
Goal: run sessions from an image in a private registry — see how the fleet declares what it can pull, what happens when you aim outside that list, and the one operator step that makes private pulls work.
Prereq: tutorial 7 (templates), a private repo on a registry you can push to (GHCR is the easy case), and — for the operator step — access to the fleet's nodes (or an operator who has it; on the hosted beta that's the service).
1. See what the fleet can pull¶
The console's Templates page shows the declared list ("This fleet pulls from: …") when the operator has set one; the API answers the same:
curl -s -H "Authorization: Bearer $KEY" \
https://beta.barista.sh/v1/templates/-/registries
# {"allowed": ["docker.io", "ghcr.io"]} ({"allowed": []} = unrestricted)
2. Aim outside the list and watch it refuse early¶
With an allowlist set, registration fails at registration — the moment you can act on it — naming the allowed registries:
barista template build app --repo quay.io/you/private
# 422: registry 'quay.io' is not reachable by this fleet's nodes (allowed: docker.io, ghcr.io)
Without this gate the failure mode is far worse: the template registers, the create is admitted, and the instance simply never becomes ready — nothing tells you the node's pull was refused.
3. The operator step (once per node)¶
Nodes pull with the standard Docker credential keychain, read from the hypeman
service's HOME — /var/lib/hypeman/.docker/config.json (not /root;
the unit sets HOME=/var/lib/hypeman and a credential in the wrong home is
silently ignored):
mkdir -p /var/lib/hypeman/.docker && cat > /var/lib/hypeman/.docker/config.json <<'JSON'
{"auths": {"ghcr.io": {"auth": "<base64 of user:token>"}}}
JSON
chmod 600 /var/lib/hypeman/.docker/config.json
No restart: the keychain is consulted per pull (verified live — adding the file makes the next pull succeed; removing it makes the one after fail). Two honest caveats: the credential is fleet-wide (every tenant's pulls use it — per-tenant pull secrets are a recorded follow-up), and rotation is just replacing the file.
4. Build, register, create — same as any template¶
barista template build app --repo ghcr.io/you/private-agents --context .
barista create worker1 --template app -- sleep 3600
barista exec worker1 -- echo "pulled private, running"
From here everything in tutorial 7 applies unchanged: rebuilds replace the template in place, running sessions keep their pinned digest, and every create surface (CLI/REST/SDK/MCP) takes the template by name.