# Deploy to the Hermes box

Not done yet. Steps, in order. Each has a check.

1. **DNS** — A record `signon.lfcs.com.au` -> box IP. Check: `dig +short signon.lfcs.com.au`.
2. **Service account** — GCP console: create SA, download JSON, enable Drive API.
   Share the shared-Drive `Jobs` folder to the SA email as **Editor**. Get the `Jobs` folder ID
   from its URL. Check: `python -c "from app.storage import from_env; print(from_env().find_job('2630'))"`
   prints the 2630 folder name.
   NOTE: the existing `/root/.hermes/google_token.json` is Hermes's own OAuth token with write
   scope only on folders Hermes created — do NOT reuse it here.
3. **Code** — `git clone` to `/opt/lfcs-signon`, `python3 -m venv .venv`, `.venv/bin/pip install -r requirements.txt`,
   write `.env` (JOBS_ROOT_FOLDER_ID, GOOGLE_SERVICE_ACCOUNT_JSON=/opt/lfcs-signon/sa.json,
   PUBLIC_BASE_URL=https://signon.lfcs.com.au). `.env` and `sa.json` never committed.
4. **systemd** — `cp deploy/signon.service /etc/systemd/system/ && systemctl enable --now signon`.
   Check: `curl -s localhost:8080/j/2630 | head -c 200`.
5. **Caddy** — `apt install caddy`, drop `deploy/Caddyfile` in `/etc/caddy/Caddyfile`, `systemctl reload caddy`.
   Check: open `https://signon.lfcs.com.au/j/2630` on a phone on 4G.
6. **Seed a job** — drop one real PDF in `<job>/05. Safety & Compliance/Sign-On/Docs/` and a `Crew.txt`.
   Scan the QR on the phone, sign, confirm the PDF lands in `Signed/` on Drive.

Firewall: only 80/443 open. 8080 stays on loopback.
