Docker Compose Deploy
Step-by-step walkthrough for `docker compose -f docker-compose.traefik.yml up -d`.
Docker Compose Deploy
The production compose file lives at the repo root: docker-compose.traefik.yml. It wires up 19 services behind Traefik, exposes only 80/443 on the host, and sources every secret from the environment.
Prerequisites
- Docker Engine 25+ with the Compose V2 plugin.
- A host with at least 4 vCPU / 8 GiB RAM (see Overview).
- Public DNS records in place (see DNS setup).
- Outbound network to
ghcr.iofor images,acme-v02.api.letsencrypt.orgfor TLS.
Step 1: Clone the repo (or pull the release tarball)
git
Only docker-compose.traefik.yml and deploy/docker/ are needed at runtime -- the services/, apps/, packages/ source trees ship inside the container images.
Step 2: Copy the env template
cp .env.example .env.production
$EDITOR .env.productionAt minimum you must set:
DOMAIN_API,DOMAIN_WEB,DOMAIN_DOCS,DOMAIN_POLIS,DOMAIN_SAML,DOMAIN_GRAFANA,DOMAIN_MINIOPOSTGRES_PASSWORD+ the four per-service Postgres passwordsHYDRA_SYSTEM_SECRET,KRATOS_COOKIE_SECRET,KRATOS_CIPHER_SECRETVALKEY_PASSWORD,MINIO_ROOT_USER,MINIO_ROOT_PASSWORDSMTP_CONNECTION_URI,SMTP_FROM_ADDRESS
See Environment variables for the full reference.
Step 3: Bring the stack up
docker compose -f docker-compose.traefik.yml --env-file .env.production up -dFirst boot takes ~2 minutes. docker compose ps should show every service healthy:
NAME STATUS
avnology-postgres Up (healthy)
avnology-valkey Up (healthy)
avnology-nats Up (healthy)
avnology-minio Up (healthy)
avnology-pgbouncer Up (healthy)
avnology-kratos Up (healthy)
avnology-hydra Up (healthy)
avnology-keto Up (healthy)
avnology-oathkeeper Up (healthy)
avnology-polis Up (healthy)
avnology-gateway Up (healthy)
avnology-audit Up (healthy)
avnology-risk Up (healthy)
avnology-webhook Up (healthy)
avnology-saml Up (healthy)
avnology-web Up (healthy)
avnology-docs Up (healthy)Step 4: Verify the public endpoints
curl -I https://$DOMAIN_API/healthz # gateway
curl -I https://$DOMAIN_WEB/ # web dashboard
curl -I https://$DOMAIN_DOCS/ # docsAll three should return 200 OK with valid TLS.
Step 5: Create the first admin user
Use the built-in admin bootstrap endpoint (only runs when zero identities exist):
curl -X POST "https://$DOMAIN_API/v1/admin/bootstrap" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "..."
}'Once the first identity exists the bootstrap endpoint is disabled.