Files
email_agent/docs/deploy-phase1.md
Sam Rolfe e846400338 docs: Phase 1 deploy verified, session secret configured (AUD-61)
Login and dashboard verified over public HTTPS; record the secret path and
the Paperclip card cascade limitation that forced direct configuration.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-11 20:17:15 +11:00

112 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 1 deployment runbook — `mail.lab.audasmedia.com.au`
Status: **prepared, not executed.** The deploy is [AUD-61](/AUD/issues/AUD-61) and is
blocked on [AUD-58](/AUD/issues/AUD-58) (Phase 1.1 skeleton) and
[AUD-59](/AUD/issues/AUD-59) (Phase 1.2 login + dashboard). Do not run these steps
until both are done.
## Target
| Item | Value |
|---|---|
| App host | `.13` (`192.168.20.13`), Docker, user `sam` (in the `docker` group, no sudo) |
| Container / compose project | `email-agent` — this project's own image and compose file |
| Listen port | `8790` (AGENTS.md §9) |
| Public URL | `https://mail.lab.audasmedia.com.au` |
| Reverse proxy | Caddy on `.35` (`192.168.20.35`), container `caddy`, config `/Docker/Containers/caddy/Caddyfile` |
## Verified facts (from [AUD-60](/AUD/issues/AUD-60), 2026-10-11)
- Port 8790 is free on `.13`. In 8780–8800 only 8787 (headroom) and 8788 (hub) are used.
- Deploy convention on `.13` is one directory per stack at
`/home/sam/Docker/Containers/<name>/` holding a `docker-compose.yml`, then
`docker compose up -d` as `sam`. Source stays in this repo.
- `*.lab.audasmedia.com.au` is a wildcard DNS record to the external IP. No new record is needed.
- Caddy issues the Let's Encrypt certificate on the first request. Peer hosts such as
`prefect.lab` already serve valid certificates.
- Caddy reload works: `docker exec caddy caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile`.
- Not confirmed: the external 80/443 port-forward to `.35`. It is inferred from the working
peer certificates. If `mail.lab` fails to obtain a certificate, check the port-forward first.
- `tokens.css` is readable at `/home/sam/Docker/Containers/family-home-lab/portal/static/tokens.css`
(needed by AUD-59, not by the deploy).
## Steps
1. **Confirm the blockers are done.** AUD-58 and AUD-59 are both `done`.
2. **Build and start on `.13`** from this repo:
```sh
docker compose build
docker compose up -d
docker compose ps
```
Set `EMAIL_AGENT_SESSION_SECRET` in the host environment before the login phase
(AUD-59 records the secret name; never commit the value).
3. **Check the service locally on `.13`**
```sh
curl -fsS http://127.0.0.1:8790/health
```
Expect HTTP 200 and `"status":"ok"`.
4. **Add the Caddy route on `.35`.** Append to `/Docker/Containers/caddy/Caddyfile`:
```
mail.lab.audasmedia.com.au {
reverse_proxy 192.168.20.13:8790
}
```
5. **Reload Caddy**
```sh
docker exec caddy caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
```
6. **Verify the public URL**
```sh
curl -fsS https://mail.lab.audasmedia.com.au/health
```
Expect HTTP 200 and a valid certificate.
## Phase 1 Definition of Done checklist
- [x] The app runs on `.13` (`docker compose ps` shows `email-agent` up and healthy).
- [x] Login works (redirect from `/` to login, log in with the configured password).
- [x] The empty dashboard renders.
- [x] `/health` returns ok — locally and through `https://mail.lab.audasmedia.com.au`.
- [ ] Verified from a phone browser (verified over public HTTPS instead; see the log).
## Rollback
1. Remove the `mail.lab.audasmedia.com.au` block from the Caddyfile and reload Caddy.
2. `docker compose down` in this repo (keeps the `email_agent_data` volume).
## Deployment log — 2026-10-11 (AUD-61)
Executed on `.13` and `.35` from commit `3c0030c`:
- Image `email-agent:latest` built; container `email-agent` started with its own compose
project (`name: email-agent`), healthy, published `0.0.0.0:8790->8790/tcp`.
- `https://mail.lab.audasmedia.com.au/health` → `200`
`{"status":"ok","env":"production","database":"ok"}`.
- `https://mail.lab.audasmedia.com.au/` → `303 /login?next=%2F`; `/login` renders the
Family Home Lab sign-in form.
- Caddy on `.35`: block appended at line 991 of `/Docker/Containers/caddy/Caddyfile`,
backup `Caddyfile.bak.aud61-20261011T200125`. `caddy validate` = *Valid configuration*;
`caddy reload` exit 0. The Let's Encrypt certificate was issued via HTTP-01 (challenge
served to `192.168.20.1`), which confirms the external 80/443 port-forward to `.35`.
- **Session secret configured.** `EMAIL_AGENT_SESSION_SECRET` was written to
`~/.config/environment.d/10-secrets.conf` on `.13` (mode 600, backup
`10-secrets.conf.bak.aud61-*`) and the container recreated to pick it up. The value is
never committed.
- **Login verified over public HTTPS:** wrong password → `401`; correct password →
`303 -> /` with an `email_agent_session` cookie; `GET /` → `200` dashboard with the
greeting and nav; `POST /logout` → `303 /login`.
- **Paperclip secret path:** the board accepted the **Confirm secret binding** card
(`c1a0ea92-...`), but the interaction-card approval calls `secretProposals.approve`
without `cascade`, so a binding that depends on a still-pending secret proposal always
fails `409` (`Binding proposal requires pending secret proposal …; retry with
cascade=true`). The secret was therefore configured directly; the redundant pending
proposal `c02b3052-...` was withdrawn.
### Changing the login password
The login password falls back to `EMAIL_AGENT_SESSION_SECRET` while `EMAIL_AGENT_PASSWORD`
is unset. To use a memorable password instead, add `EMAIL_AGENT_PASSWORD=…` to
`~/.config/environment.d/10-secrets.conf` on `.13` and recreate the container.