Resolve all open questions, remove /health from main listener (ADR-022)
Resolve OQ-08 through OQ-12 after reviewing implementation findings: - OQ-08: Remove /health route from the main HTTPS listener entirely. Health checking belongs on port 9900 and admin socket only, not on the public-facing proxy. This eliminates upstream collision problems and special-case routing logic. (ADR-022) - OQ-09: Not an architectural unknown — ADR-015 already decided on a separate connect timeout. The implementation gap is a known issue. - OQ-10: Not an open question — acme_contact is already specified as required in config.md. The empty contact list is bug C2. - OQ-11: Hardcoded is_https=true is correct for a TLS-terminating proxy. HTTP listener redirects, doesn't proxy. Just needs a comment. - OQ-12: Access logging is already specified as mandatory/always-on in operations.md. Missing log_request! calls are bug W13. Updated docs: proxy.md, operations.md, overview.md, config.md, open-questions.md, README.md, ADR-013. Created ADR-022.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-06-11
|
||||
last_updated: 2026-06-12
|
||||
---
|
||||
|
||||
# Operations
|
||||
@@ -109,8 +109,7 @@ log entries:
|
||||
1. **Access logs**: Every proxied request is logged at `info` level with
|
||||
structured fields. Access logging is **always-on** — it is the primary
|
||||
observability mechanism for the proxy and is required for fail2ban
|
||||
integration. There is no configuration option to disable access logging
|
||||
(see OQ-12).
|
||||
integration. There is no configuration option to disable access logging.
|
||||
|
||||
```
|
||||
REQUEST client_ip=203.0.113.50 host=git.alk.dev method=GET path=/user/repo status=200 upstream=127.0.0.1:3000 duration_ms=45
|
||||
@@ -172,34 +171,37 @@ Configurable via `log_level` in StaticConfig.
|
||||
|
||||
### Local Health Check Port
|
||||
|
||||
The primary health check endpoint is served on a separate local port (default:
|
||||
9900), bound to `127.0.0.1` only. This ensures health checks work even when TLS
|
||||
is misconfigured. See ADR-013 for the rationale.
|
||||
The health check endpoint is served on a separate local port (default: 9900),
|
||||
bound to `127.0.0.1` only. It is not served on the main HTTPS listener —
|
||||
health checking is an operational concern that does not belong on the
|
||||
public-facing proxy. See ADR-013 and ADR-022.
|
||||
|
||||
```
|
||||
GET http://127.0.0.1:9900/health → 200 OK (empty body)
|
||||
```
|
||||
|
||||
The port is configurable via `health_check_port` in StaticConfig. Setting it
|
||||
to `0` disables the separate health check listener.
|
||||
to `0` disables the health check listener entirely.
|
||||
|
||||
### HTTPS Health Check (Fallback)
|
||||
The admin socket's `status` command provides an additional health/status
|
||||
mechanism that returns process information:
|
||||
|
||||
When the local health check port is enabled, `/health` is also available on the
|
||||
main HTTPS listener for cases where TLS-level health verification is desired.
|
||||
External monitoring should prefer the local health check for liveness checks
|
||||
and can use the HTTPS endpoint for TLS verification.
|
||||
```
|
||||
{"status": "ok", "uptime_secs": 1234, "sites": 2}
|
||||
```
|
||||
|
||||
### What It Checks
|
||||
|
||||
- Process is running and the tokio runtime is responsive
|
||||
- TLS listener is accepting connections (HTTPS endpoint only)
|
||||
- Config is loaded (StaticConfig and DynamicConfig are initialized)
|
||||
|
||||
It does **not** check upstream reachability. The health check answers "is the
|
||||
proxy process healthy?", not "is the upstream reachable?" — upstream health is
|
||||
a separate concern that would produce 502/504 responses in the proxy handler.
|
||||
|
||||
It also does **not** verify TLS configuration — that is the responsibility of
|
||||
external monitoring tools that connect to the public HTTPS port directly.
|
||||
|
||||
### Future Extensions
|
||||
|
||||
- `/health/ready` — readiness check that includes upstream reachability
|
||||
@@ -511,6 +513,7 @@ HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
|
||||
```
|
||||
|
||||
No port publishing is needed — the health check runs inside the container.
|
||||
There is no `/health` route on the main HTTPS listener.
|
||||
|
||||
### SSH Traffic
|
||||
|
||||
@@ -580,8 +583,14 @@ All design decisions are documented as ADRs in [decisions/](decisions/).
|
||||
|
||||
## Open Questions
|
||||
|
||||
Open questions are tracked in [open-questions.md](open-questions.md). Key
|
||||
questions affecting this document:
|
||||
Open questions are tracked in [open-questions.md](open-questions.md). All
|
||||
questions affecting this document have been resolved:
|
||||
|
||||
- ~~**OQ-03**: Should the health check endpoint be on a separate port?~~ (resolved
|
||||
— ADR-013: separate local port, default 9900, localhost only)
|
||||
— ADR-013: separate local port, default 9900, localhost only)
|
||||
- ~~**OQ-08**: Should `/health` use a less common path?~~ (resolved — ADR-022:
|
||||
no `/health` route on the main listener at all; health checking is via port
|
||||
9900 and admin socket only)
|
||||
- ~~**OQ-12**: Should request access logging be mandatory or optional?~~ (resolved
|
||||
— access logging is mandatory and always-on at `info` level; no configuration
|
||||
option to disable it)
|
||||
Reference in New Issue
Block a user