Skip to content

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.