Implement supported ingress and TLS profiles
This commit is contained in:
@@ -91,6 +91,8 @@ The private installation directory contains:
|
||||
| `compose.json` | Deterministic generated Compose definition |
|
||||
| `garage.toml` | Non-secret managed Garage server configuration |
|
||||
| `load-balancer.cfg` | Non-secret HAProxy WebUI/API discovery configuration |
|
||||
| `Caddyfile` | Non-secret managed-ingress route and ACME policy |
|
||||
| `existing-proxy.json` | Exact upstream, trusted-source, header, and health contract for an operator-owned proxy |
|
||||
| `plan.json` | Latest desired-state diff and readiness findings |
|
||||
| `receipt.json` | Last successfully applied immutable identities |
|
||||
| `distribution-manifest.json` | Canonical signed runtime/image selection adopted by the installer |
|
||||
@@ -184,12 +186,11 @@ a production distribution:
|
||||
5. **Deployment agent.** Web updates need a separate privileged reconciler with
|
||||
a typed command allowlist. The API and browser must never receive the Docker
|
||||
socket or arbitrary shell access.
|
||||
6. **Ingress and certificates.** The managed HAProxy service provides HTTP
|
||||
load balancing inside the deployment boundary; it does not issue or renew
|
||||
certificates. A self-hosted profile still needs an explicit choice
|
||||
between an existing reverse proxy and a supported managed ingress, including
|
||||
trusted-proxy boundaries, TLS certificate issuance, renewal, and health
|
||||
probing through the public route.
|
||||
6. **Ingress reachability evidence.** Managed Caddy ingress and the
|
||||
existing-proxy contract are implemented. A production claim still requires
|
||||
running `doctor` from the target host after public DNS/firewall changes and
|
||||
retaining the first successful container drill and public TLS/readiness
|
||||
evidence.
|
||||
|
||||
`apply --allow-unverified-images` is therefore restricted to the evaluation
|
||||
profile. It explicitly acknowledges both mutable image identities and
|
||||
@@ -263,7 +264,9 @@ must use a tested multi-node Garage cluster or another external S3 service.
|
||||
|
||||
### Load Balancing And Replicas
|
||||
|
||||
The generated Compose topology publishes only `load-balancer`. HAProxy uses
|
||||
The generated Compose topology publishes only `load-balancer` for local or
|
||||
existing-proxy profiles. With managed ingress, only Caddy publishes host ports
|
||||
and HAProxy remains private. HAProxy uses
|
||||
Docker DNS service discovery to distribute public traffic across WebUI replicas
|
||||
and WebUI API proxy traffic across API replicas. The WebUI and API services do
|
||||
not publish host ports. HAProxy has no Docker socket and discovers only the
|
||||
@@ -287,6 +290,49 @@ PostgreSQL advisory lock. The Celery scheduler is run under a renewable,
|
||||
fencing-token lease. Multiple API replicas are rejected when Redis is disabled
|
||||
because distributed throttling and queued work cannot then be shared correctly.
|
||||
|
||||
### Public Ingress And TLS
|
||||
|
||||
A self-hosted installation is fail-closed until one of these boundaries is
|
||||
selected:
|
||||
|
||||
- `existing-proxy` publishes HAProxy at `listen.address:listen.port` and emits
|
||||
`existing-proxy.json`. The operator-owned proxy must use the recorded host,
|
||||
upstream, and health paths. Only the exact CIDRs listed with repeated
|
||||
`--trusted-proxy-cidr` values may supply `X-Forwarded-*` headers. Public
|
||||
proxy addresses must be `/32` or `/128`; private ranges are limited to `/24`
|
||||
or narrower for IPv4 and `/64` or narrower for IPv6.
|
||||
- `managed` publishes Caddy on the selected HTTP/HTTPS ports, redirects HTTP to
|
||||
HTTPS, obtains and renews certificates through ACME, and keeps certificate
|
||||
material exclusively in the private `caddy-data` and `caddy-config` volumes.
|
||||
The application containers receive no ACME account or TLS private keys.
|
||||
|
||||
Example existing-proxy configuration:
|
||||
|
||||
```sh
|
||||
python govoplan-deploy.py configure \
|
||||
--directory /srv/govoplan \
|
||||
--ingress existing-proxy \
|
||||
--trusted-proxy-cidr 172.20.0.7/32
|
||||
```
|
||||
|
||||
Example managed configuration:
|
||||
|
||||
```sh
|
||||
python govoplan-deploy.py configure \
|
||||
--directory /srv/govoplan \
|
||||
--ingress managed \
|
||||
--acme-email operator@example.org
|
||||
```
|
||||
|
||||
Before managed ingress starts, public A/AAAA records must resolve to the target
|
||||
and inbound TCP 80/443 must reach it. Existing-proxy mode additionally requires
|
||||
the public proxy and valid certificate to be reachable before apply. After a
|
||||
successful receipt, `doctor` reports DNS resolution, certificate validity and
|
||||
remaining lifetime, public `/health/ready`, and the private HAProxy/WebUI path
|
||||
as separate checks. Reconfiguration retains the certificate volumes; bundle
|
||||
rollback never deletes or exposes their contents. Include both Caddy volumes
|
||||
in coordinated backup and restore evidence.
|
||||
|
||||
This is same-host scaling. Docker Compose uses a bridge network and does not
|
||||
place containers on another machine. See
|
||||
[Scaling And Multi-Host Deployment](SCALING_AND_MULTI_HOST_DEPLOYMENT.md) for
|
||||
|
||||
Reference in New Issue
Block a user