Production Deployment
Production Compose file
For production, use:
docker compose -f deployment/docker-compose.prod.yml up -dThe production configuration differs from development by:
- No source volume mounts (built from images)
restart: unless-stoppedfor all services- Resource limits (CPU, memory)
- No direct port access to the database or MinIO
Secrets in deployment/.env
All configuration values and secrets live in deployment/.env. It is a copy of deployment/.env.example, excluded from the repository by .gitignore, and the only place where secrets touch disk on the server:
cd deployment
cp .env.example .env
# fill in .env — values from your password manager
bash scripts/deploy.shThe deploy script reads .env directly; there is no encrypted secrets file in the repository and no decryption step. Keep the values in a password manager, not in Git (for the reference installation that is the project's Clavis V1 vault in 1Password). JWT_SECRET_KEY and HMAC_AUDIT_KEY are generated fresh for every installation, e.g. with openssl rand -base64 48.
TLS and reverse proxy
The application stack publishes no host ports and terminates no TLS. A reverse proxy in front of it serves the one public address (e.g. app.clavis-rallye.de) over HTTPS and routes by path:
| Path | Target |
|---|---|
/api/* (including the WebSocket upgrade) | clavis-api:8000 |
| everything else | clavis-web:80 |
The application is built for a single origin: API and frontend share one domain, the API under the /api path. The reference installation uses the server's Nginx Proxy Manager with a Let's Encrypt certificate for this. If you run the bundled all-in-one stack instead (docker-compose.yml at the root of the App repository), its Caddy service provides the same routing; its Caddyfile contains a commented-out production block with TLS settings per BSI TR-02102 where you enter your own domain.
Production environment variables
| Variable | Description |
|---|---|
IMAGE_TAG | Version of the container images pulled from the registry (required, see Updates) |
DATABASE_URL | Connection URL of the PostgreSQL database, including the password |
MINIO_ACCESS_KEY | MinIO access credentials |
MINIO_SECRET_KEY | MinIO secret key |
JWT_SECRET_KEY | JWT signing key (≥32 characters, random) |
HMAC_AUDIT_KEY | HMAC key for the audit log chain |
CORS_ORIGINS, WEBAUTHN_RP_ID, WEBAUTHN_ORIGIN | The installation's public domain / origin (e.g. app.clavis-rallye.de / https://app.clavis-rallye.de) |
All [SECRET]-marked variables from deployment/.env.example must be set.