2026-06-14 17:36:58 +02:00
|
|
|
# reverse_proxy
|
|
|
|
|
|
|
|
|
|
Boma's standard Caddy reverse proxy (ADR-024). Runs on `askari` (the off-site
|
2026-06-14 18:11:20 +02:00
|
|
|
Hetzner host) and terminates TLS for all public-facing services via ACME HTTP-01.
|
|
|
|
|
Uses the official `caddy:2` image — no custom build, no DNS plugin, no token required.
|
2026-06-14 17:36:58 +02:00
|
|
|
|
|
|
|
|
## How TLS works
|
|
|
|
|
|
2026-06-14 18:11:20 +02:00
|
|
|
Caddy obtains per-hostname certificates using the ACME HTTP-01 challenge. Port 80
|
|
|
|
|
must be reachable from the internet for the challenge to succeed. Each `host` in
|
|
|
|
|
`reverse_proxy__routes` gets its own certificate automatically.
|
|
|
|
|
|
|
|
|
|
> **DNS-01 (for mesh/LAN-only cluster services) is deferred to Phase 2.** The
|
|
|
|
|
> `caddy-dns/gandi` plugin failed to issue certificates during M4a and needs
|
|
|
|
|
> investigation before it can be used.
|
2026-06-14 17:36:58 +02:00
|
|
|
|
|
|
|
|
## Route catalog — `reverse_proxy__routes`
|
|
|
|
|
|
|
|
|
|
Services register themselves as routes by appending an entry to
|
|
|
|
|
`reverse_proxy__routes` in `group_vars/all/reverse_proxy.yml`:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
reverse_proxy__routes:
|
2026-06-14 18:11:20 +02:00
|
|
|
- {host: app.askari.wingu.me, upstream: "app:8080"}
|
|
|
|
|
- {host: health.askari.wingu.me, respond: "ok"}
|
2026-06-14 17:36:58 +02:00
|
|
|
```
|
|
|
|
|
|
2026-06-14 18:11:20 +02:00
|
|
|
Each entry renders a separate server block in the Caddyfile:
|
2026-06-14 17:36:58 +02:00
|
|
|
|
|
|
|
|
```
|
2026-06-14 18:11:20 +02:00
|
|
|
app.askari.wingu.me {
|
|
|
|
|
reverse_proxy app:8080
|
2026-06-14 17:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
2026-06-14 18:11:20 +02:00
|
|
|
health.askari.wingu.me {
|
|
|
|
|
respond "ok" 200
|
|
|
|
|
}
|
|
|
|
|
```
|
2026-06-14 17:36:58 +02:00
|
|
|
|
2026-06-14 18:11:20 +02:00
|
|
|
Use `upstream` to proxy to a Docker service, or `respond` to return a static string.
|
2026-06-14 17:36:58 +02:00
|
|
|
|
|
|
|
|
## Variables
|
|
|
|
|
|
|
|
|
|
| Variable | Default | Description |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `reverse_proxy__base_dir` | `/opt/services/reverse_proxy` | Working directory for Compose project |
|
|
|
|
|
| `reverse_proxy__acme_email` | `admin@example.test` | ACME registration email |
|
2026-06-14 18:11:20 +02:00
|
|
|
| `reverse_proxy__routes` | `[]` | List of `{host, upstream}` or `{host, respond}` entries |
|
2026-06-14 17:36:58 +02:00
|
|
|
| `reverse_proxy__manage` | `true` | Set `false` in Molecule to skip Docker tasks |
|
|
|
|
|
|
|
|
|
|
Production overrides live in
|
|
|
|
|
`inventories/production/group_vars/all/reverse_proxy.yml`.
|
|
|
|
|
|
|
|
|
|
## `reverse_proxy__manage` toggle
|
|
|
|
|
|
2026-06-14 18:11:20 +02:00
|
|
|
Docker operations (`docker compose up`) are gated on `reverse_proxy__manage | bool`.
|
|
|
|
|
Set it to `false` in Molecule so the role can be tested (template rendering, directory
|
|
|
|
|
creation) without a Docker daemon.
|
2026-06-14 17:36:58 +02:00
|
|
|
|
|
|
|
|
## Secrets
|
|
|
|
|
|
2026-06-14 18:11:20 +02:00
|
|
|
None. HTTP-01 requires no credentials.
|