Task graph covers all Phase 1 concerns: config system, TLS termination, proxy handler, operations (rate limiting, logging, health check, admin socket, signals, shutdown, body size limit), deployment artifacts, and two review checkpoints. No circular dependencies. Critical path length of 7. Risk distribution: 3 high-risk (ACME, TLS listener setup, startup orchestration), 7 medium, 11 low, 2 trivial.
3.1 KiB
3.1 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | |
|---|---|---|---|---|---|---|---|---|
| deploy/systemd-and-container | Create systemd unit file, Dockerfile, and docker-compose.yml for production deployment | pending |
|
moderate | low | component | implementation |
Description
Create the deployment artifacts: systemd unit file, Dockerfile, and docker-compose.yml template.
Systemd Unit File
[Unit]
Description=Reverse Proxy
After=network.target
Wants=network-online.target
[Service]
Type=notify
NotifyAccess=all
ExecStart=/usr/local/bin/reverse-proxy --config /etc/reverse-proxy/config.toml
Restart=on-failure
RestartSec=5
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/reverse-proxy /var/log/reverse-proxy
# ACME challenge cache directory
StateDirectory=reverse-proxy
[Install]
WantedBy=multi-user.target
The proxy signals readiness to systemd via sd_notify("READY=1") after binding listeners and completing initial configuration load.
Dockerfile
Multi-stage build:
- Build stage:
rust:alpinewithx86_64-unknown-linux-musltarget for static linking - Run stage:
alpine(orscratchfor absolute minimum) - The
aws_lc_rscrypto provider is statically linked — no OpenSSL dependency - Binary is self-contained, no runtime dependencies beyond libc for DNS resolution
Docker Compose Template
Example template showing:
- Reverse proxy with volume mounts for config, ACME cache, logs, and admin socket
allow_wildcard_bind = truefor container deployments- Health check using
wgetagainst local health endpoint - Network configuration for upstream services
Fail2ban Configuration
- Filter definition matching the
RATE_LIMITlog prefix - Jail configuration for rate-limiting offenders
Acceptance Criteria
- Systemd unit file at
deploy/reverse-proxy.service Type=notifywithsd_notify("READY=1")integration in binary- Security hardening directives in unit file
ReadWritePathsfor ACME cache and log directory- Dockerfile with multi-stage build (
rust:alpine→alpine/scratch) - Static linking with
x86_64-unknown-linux-musltarget - Docker Compose template at
deploy/docker-compose.yml - Volume mounts for config (ro), ACME cache (rw), logs (rw), admin socket (rw)
- Health check in Docker Compose using
wgetagainsthttp://127.0.0.1:9900/health - Fail2ban filter definition at
deploy/fail2ban/filter.d/reverse-proxy.conf - Fail2ban jail configuration at
deploy/fail2ban/jail.d/reverse-proxy.conf docker buildsucceeds- Container starts and responds to health check
References
- docs/architecture/operations.md — systemd, container deployment, fail2ban, health check
- docs/architecture/decisions/020-container-deployment.md — container model rationale
Notes
The Dockerfile should use
muslfor static linking. Theaws_lc_rscrypto provider is statically linked. The resulting binary has no runtime dependencies beyond libc for DNS resolution (whichmuslprovides).
Summary
To be filled on completion