Files
spoon/docs/server-deploy-changes.md
T
Gabriel Brown 8d2a089268
Build and Push Spoon Images / quality (push) Failing after 7s
Build and Push Spoon Images / build-images (push) Has been skipped
docs: server deploy changes (terminal, dotfiles, Fedora, Phase 2)
2026-06-24 10:32:45 -04:00

4.7 KiB

Server deploy changes (terminal + dotfiles + Fedora + Phase 2)

Everything the production host / compose / .env needs for the workspace terminal, personalized dev environment, Nerd Font, and the per-user container. Most items have safe defaults; the Required ones are the only must-dos.

Required

  1. Build-time env for the Next image — add to the build env file (the one CI / scripts/build-next-app passes as build args; e.g. DOTENV_PROD):

    NEXT_PUBLIC_SPOON_AGENT_WORKER_WS_URL=wss://worker.spoon.gbrown.org
    

    This is a NEXT_PUBLIC (build-time) var — it must be present when the spoon-next image is built, not just at runtime. Already wired into docker/Dockerfile + docker/compose.yml build args. Without it, the workspace Terminal tab shows "not configured".

  2. nginx: expose the worker for the terminal WebSocket. Add a TLS server block proxying the worker domain to the worker on the shared network, with WS upgrade:

    server {
      listen 443 ssl;
      server_name worker.spoon.gbrown.org;     # + your ssl_certificate lines
      location / {
        proxy_pass http://spoon-agent-worker:3921;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
      }
    }
    
  3. Rebuild + redeploy all three images (CI does this on push to main): spoon-next, spoon-agent-worker, and spoon-agent-job (now Fedora). The worker auto-docker pulls the job image once per process, so a worker restart picks up the new Fedora job image. Make sure the prod registry has the new spoon-agent-job:latest.

  4. Deploy Convex functions (new tables userDotfiles, userEnvironment). SPOON_ENCRYPTION_KEY (or INSTANCE_SECRET) is already required and is what encrypts dotfiles at rest — no change, just confirm it's set.

  5. Confirm SPOON_AGENT_HOST_WORKDIR on the spoon-agent-worker service is the absolute host path backing SPOON_AGENT_WORKDIR (the fix from the terminal work). The per-user homes live under ${SPOON_AGENT_WORKDIR}/homes/{username} and are bind-mounted into the box via the host daemon — this only resolves if the host-workdir translation is correct. (No new var; just verify.)

Optional (safe defaults — only set to override)

On the spoon-agent-worker service:

Var Default Purpose
SPOON_AGENT_TERMINAL_SECRET falls back to SPOON_AGENT_WORKER_INTERNAL_TOKEN HMAC secret for terminal tokens (must match the Next app's, which also falls back). Leave unset to use the shared token.
SPOON_AGENT_BOX_IDLE_MS 1800000 (30m) How long a per-user box survives idle before being reaped.
SPOON_AGENT_TERMINAL_IDLE_MS 1800000 (Legacy; box idle now governs cleanup.)

No new env is needed for dotfiles, the per-user home, or the Nerd Font.

Notes / one-time cleanup

  • Layout change: thread checkouts moved from ${WORKDIR}/{jobId}/repo to ${WORKDIR}/homes/{username}/Code/{spoon}/{branch} (persistent). Old per-job dirs are orphaned and safe to delete.
  • Containers: per-thread agent containers (docker run --rm) and per-job terminal containers (spoon-agent-term-*) are gone; everything runs in one spoon-box-{username} per user. Any lingering spoon-agent-term-* containers can be removed.
  • Resources: each active user holds one box (4 GB mem cap, sleep infinity) until 30m idle. Single-user = one box.
  • Compose already mounts /var/run/docker.sock into the worker (unchanged) — the box is created/exec'd through it.

Quick post-deploy checks

docker exec spoon-agent-worker docker --version            # CLI present (29.x)
docker run --rm git.gbrown.org/gib/spoon-agent-job:latest codex --version  # 0.142
docker run --rm git.gbrown.org/gib/spoon-agent-job:latest bash -lc 'eza --version; zoxide --version; oh-my-posh --version'
# then: open a thread → Terminal tab; Settings → Dotfiles add a .bashrc alias.