Build the backend as a fully static musl binary (rust:1-alpine + x86_64-unknown-linux-musl) and run it in a scratch image with only the binary and the compiled frontend: 32 MB instead of ~110 MB, no shell, package manager or libc, running as the numeric user 10001:10001. The binary moves to /usr/local/bin/tavolo so `tavolo migrate` and `tavolo serve` resolve on PATH in compose and Kubernetes. TLS for OIDC and Postgres validates against Mozilla's roots embedded in the binary by webpki-roots, so no certificate files are needed; the OTLP client is built without a TLS backend, so OTEL_EXPORTER_OTLP_ENDPOINT must be http:// (documented). The Docker HEALTHCHECK is removed since scratch has no curl: Kubernetes probes /api/health over HTTP and Compose gates on its dependency checks. `strip = "symbols"` trims the release binary. Validated with docker compose up --build: migrations, sessions, lobby creation, the OIDC discovery redirect and the SPA all work, proving musl DNS resolution for the postgres/redis/mockoauth service names.
This commit is contained in:
+17
-2
@@ -50,6 +50,14 @@ WebSocket endpoint.
|
||||
|
||||
OpenAPI documentation is served at `/api/docs` (`/api/openapi.json`).
|
||||
|
||||
The release image is a **scratch image** containing a fully static musl
|
||||
binary and the compiled frontend: no shell, package manager or libc. It runs
|
||||
as the numeric user `10001:10001` and has no Docker `HEALTHCHECK` (scratch has
|
||||
no `curl`); Kubernetes probes `/api/health` over HTTP, and Compose gates on
|
||||
the Postgres/Redis/OIDC dependency checks. To debug a running container use
|
||||
`docker debug` (Docker Desktop) or `kubectl debug` with an ephemeral
|
||||
container.
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration comes from environment variables (see `.env.example`):
|
||||
@@ -87,7 +95,7 @@ All configuration comes from environment variables (see `.env.example`):
|
||||
| `CORS_MAX_AGE` | `600` | Seconds browsers may cache the preflight response |
|
||||
| `OTEL_ENABLED` | `false` | `1`/`true`/`yes`/`on` enable OpenTelemetry traces, metrics and logs (compiled in by default) |
|
||||
| `OTEL_SERVICE_NAME` | `tavolo` | `service.name` resource attribute of the exported telemetry |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | unset | Base URL of an OTLP/HTTP collector (e.g. `http://localhost:4318`); unset uses the exporter default |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | unset | Base URL of an OTLP/HTTP collector (e.g. `http://localhost:4318`; unset uses that default). Must be `http://`: the OTLP client is built without a TLS backend |
|
||||
| `OTEL_EXPORTER_OTLP_HEADERS` | unset | Comma-separated `key=value` headers sent to the collector (e.g. authentication) |
|
||||
| `OTEL_EXCLUDED_PATHS` | `/api/health` | Comma-separated paths excluded from tracing and metrics (exact matches) |
|
||||
| `OTEL_METRIC_EXPORT_INTERVAL_MILLIS` | `60000` | How often the OTLP metric reader exports |
|
||||
@@ -161,6 +169,13 @@ cluster-wide counts, in-memory stores the process's own). With multiple
|
||||
replicas each process reports the same global counts: aggregate with `max`,
|
||||
not `sum`.
|
||||
|
||||
The OTLP client is built without a TLS backend, so
|
||||
`OTEL_EXPORTER_OTLP_ENDPOINT` must use `http://`; terminate TLS in front of
|
||||
the collector (or run a local sidecar) if the collector is remote. The
|
||||
OIDC/Postgres clients do not use this client and validate HTTPS against
|
||||
Mozilla's roots embedded in the binary (no certificate files are needed, and
|
||||
private CAs are not trusted by them).
|
||||
|
||||
## Data model
|
||||
|
||||
### Redis (live games)
|
||||
@@ -411,7 +426,7 @@ crates/tavolo-app/ # deployable app: composition root (own crate)
|
||||
src/{main,app,config,cors,logging,static_files,telemetry}.rs
|
||||
migrations/ # embedded sqlx migrations
|
||||
dev/mockoauth/ # dev OIDC provider image (compose)
|
||||
Dockerfile # web-builder + cargo + slim runtime
|
||||
Dockerfile # web-builder + musl cargo + scratch runtime
|
||||
.env.example
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user