Add container deployment model (ADR-020) and fix review issues
- ADR-020: Document defense-in-depth rationale for running in a minimal Docker container (memory-safe language + container isolation), flexible upstream addressing (Docker DNS, loopback, LAN, tunnel endpoints), file-primary logging for fail2ban, and volume mount strategy - ADR-016: Add allow_wildcard_bind override for container deployments where 0.0.0.0 is correct inside the container network namespace - operations.md: Add container deployment section with Docker Compose example, networking table, volume mounts, and health check integration; flip logging to file-primary for fail2ban reliability; note systemd as alternative to container deployment - config.md: Restructure logging fields into nested LoggingConfig (matching TOML [logging] section), add allow_wildcard_bind, shutdown_timeout_secs, and log_file_path fields; clarify upstream addressing supports Docker DNS and tunnel endpoints; update validation rule for 0.0.0.0 override - overview.md: Update architecture diagram for container model with Docker networking and volume mounts; add ADR-020 reference - proxy.md: Clarify X-Forwarded-Proto is determined by listener port, not hardcoded 80/443 - ADR-013: Fix health_check_port default contradiction (default is 9900, not 0/disabled as previously stated)
This commit is contained in:
@@ -81,36 +81,51 @@ details.
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌────────────────────────────────────┐
|
||||
│ reverse-proxy (Rust/axum) │
|
||||
config.toml ───────► │ StaticConfig + DynamicConfig │
|
||||
│ (ArcSwap for hot-reload) │
|
||||
│ │
|
||||
│ ┌─ Listener 1 ─────────────────┐ │
|
||||
bind_addr_1:80 ───► │ │ HTTP → 301 redirect │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
bind_addr_1:443 ───► │ │ TLS listener (tokio-rustls) │ │
|
||||
│ │ ├─ ACME or Manual TLS config │ │
|
||||
│ │ └─ axum router │ │
|
||||
│ │ ├─ Host-based routing │ │
|
||||
│ │ ├─ git.alk.dev → :3000 │ │
|
||||
│ │ └─ Rate limiting, headers │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Listener N ─────────────────┐ │
|
||||
bind_addr_N:80 ───► │ │ HTTP → 301 redirect │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
bind_addr_N:443 ───► │ │ TLS listener (tokio-rustls) │ │
|
||||
│ │ ├─ Manual TLS cert │ │
|
||||
│ │ └─ axum router │ │
|
||||
│ │ ├─ alk.dev → :8080 │ │
|
||||
│ │ └─ Rate limiting, headers │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
│ /health → 200 OK (port 9900) │
|
||||
└────────────────────────────────────┘
|
||||
┌────────────────────────────────────┐
|
||||
│ reverse-proxy container (Rust/axum)│
|
||||
config.toml ───────► │ StaticConfig + DynamicConfig │
|
||||
(volume mount) │ (ArcSwap for hot-reload) │
|
||||
│ │
|
||||
│ ┌─ Listener 1 ─────────────────┐ │
|
||||
bind_addr:80 ────► │ │ HTTP → 301 redirect │ │
|
||||
(published) │ └────────────────────────────────┘ │
|
||||
│ │
|
||||
bind_addr:443 ────► │ │ TLS listener (tokio-rustls) │ │
|
||||
(published) │ │ ├─ ACME or Manual TLS config │ │
|
||||
│ │ └─ axum router │ │
|
||||
│ │ ├─ Host-based routing │ │
|
||||
│ │ ├─ git.alk.dev → gitea:3000 │ │
|
||||
│ │ └─ Rate limiting, headers │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Listener N ─────────────────┐ │
|
||||
bind_addr_N:80 ───► │ │ HTTP → 301 redirect │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
bind_addr_N:443 ───► │ │ TLS listener (tokio-rustls) │ │
|
||||
│ │ ├─ Manual TLS cert │ │
|
||||
│ │ └─ axum router │ │
|
||||
│ │ ├─ alk.dev → app:8080 │ │
|
||||
│ │ └─ Rate limiting, headers │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
│ /health → 200 OK (port 9900) │
|
||||
└────────────────────────────────────┘
|
||||
│ │
|
||||
┌──────┘ └──────┐
|
||||
│ │
|
||||
Docker network Volume mounts:
|
||||
(upstream DNS) ├─ config (ro)
|
||||
├─ gitea:3000 ├─ ACME cache (rw)
|
||||
├─ app:8080 ├─ log dir (rw, fail2ban)
|
||||
└─ admin socket (rw)
|
||||
```
|
||||
|
||||
In container deployments (ADR-020), the proxy runs in a minimal container with
|
||||
`0.0.0.0` bind address and Docker port publishing. Upstream addresses use Docker
|
||||
DNS names for same-host containers (e.g., `gitea:3000`) but also support
|
||||
loopback, LAN, and tunnel endpoints for multi-host deployments.
|
||||
|
||||
## Crate Dependencies
|
||||
|
||||
### Core
|
||||
@@ -180,6 +195,7 @@ All design decisions are documented as ADRs in [decisions/](decisions/).
|
||||
| [017](decisions/017-upstream-connection-defaults.md) | Upstream connection defaults | HTTP/1.1, no redirects, connection pooling |
|
||||
| [018](decisions/018-body-size-limit.md) | Request body size limit | 100 MB default matching nginx, Gitea push compatibility |
|
||||
| [019](decisions/019-multi-config-listeners.md) | Multi-config listeners | `[[listeners]]` supporting both dedicated-IP and shared-IP deployment models |
|
||||
| [020](decisions/020-container-deployment.md) | Container deployment model | Defense-in-depth via container isolation; file-primary logging; flexible upstream addressing |
|
||||
|
||||
## Open Questions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user