--- arc42: "7 — Deployment View" status: stub --- ## 7.1 Hetzner Deployment Diagram ```plantuml @startuml deploy node "Hetzner CX22\n(2 vCPU, 4GB RAM, Ubuntu 24.04)" as hetzner { component [Caddy\n:80, :443] as caddy component [API Service\n:8000 (internal)] as api component [Portal Service\n:8001 (internal)] as portal component [Spider Service\n(no exposed port)] as spider database [PostgreSQL 16\n:5432 (internal)] as db folder "Hetzner Volume\n(20GB)" as vol } cloud "Internet" { actor Agent actor Registrant } cloud "Let's Encrypt" as le Agent --> caddy : HTTPS :443 Registrant --> caddy : HTTPS :443 caddy --> api caddy --> portal caddy <--> le : ACME cert renewal api --> db spider --> db db --> vol : data persistence @enduml ``` ## 7.2 Environment Table | Setting | Dev | Prod (Hetzner) | |---|---|---| | TLS | None (HTTP only) | Auto via Caddy + Let's Encrypt | | DB | postgres:16 local container | postgres:16 container, data on Hetzner volume | | Spider interval | 2 min (fast feedback) | 15 min | | API key | `dev-key-insecure` | Strong random key, env var only | | Log level | DEBUG | INFO | | Port exposure | All ports exposed to host | Only :80, :443 via Caddy; all others internal | ## 7.3 Backup and Restore - `backup.sh` runs via cron daily at 03:00 UTC - Executes `pg_dump` into `/backup/apix_$(date +%Y%m%d).sql.gz` - Backup directory mounted on Hetzner volume (separate from DB data volume) - Retain last 7 dumps; older files deleted by script - Restore: `psql < apix_YYYYMMDD.sql.gz` — documented in `infra/hetzner/RESTORE.md` ## 7.4 Domain and DNS TODO: Confirm domain name (OQ-MVP-01). Planned DNS setup: - `registry.apix.dev` (or `index.botstandards.org`) → Hetzner VPS IP (A record) - TTL: 300s initially for fast propagation during setup Caddy will automatically obtain and renew the TLS certificate once the A record resolves to the server IP.