ultisuite-backend/deploy/docker-compose.yml
R3D347HR4Y 0466a1c169
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
wow
2026-06-11 01:22:52 +02:00

232 lines
7.5 KiB
YAML

services:
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./nginx/default.conf.template:/etc/nginx/templates/default.conf.template:ro
environment:
DOMAIN: ${DOMAIN:-localhost}
MAIL_FRONTEND_UPSTREAM: ${MAIL_FRONTEND_UPSTREAM:-host.docker.internal:3004}
env_file: ../.env.resolved
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- ulti-net
depends_on:
ultid:
condition: service_started
authentik-server:
condition: service_started
ultid:
build:
context: ..
dockerfile: Dockerfile
restart: unless-stopped
env_file: ../.env.resolved
networks:
- ulti-net
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/healthz >/dev/null 2>&1 || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
depends_on:
postgres:
condition: service_healthy
keydb:
condition: service_healthy
rustfs:
condition: service_started
authentik-server:
condition: service_healthy
postgres:
image: postgres:16-alpine
restart: unless-stopped
env_file: ../.env.resolved
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh:ro
networks:
- ulti-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
start_period: 10s
keydb:
image: eqalpha/keydb:latest
restart: unless-stopped
command: keydb-server --appendonly yes
volumes:
- keydb_data:/data
networks:
- ulti-net
healthcheck:
test: ["CMD", "keydb-cli", "-h", "127.0.0.1", "ping"]
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
rustfs:
image: rustfs/rustfs:latest
restart: unless-stopped
command: server /data
ports:
- "9002:9000"
- "9003:9001"
environment:
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY}
volumes:
- rustfs_data:/data
networks:
- ulti-net
authentik-server:
image: ghcr.io/goauthentik/server:latest
restart: unless-stopped
command: server
environment:
# Required at compose parse time — empty ${VAR} would override env_file with "".
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?Set AUTHENTIK_SECRET_KEY in .env and use ./deploy/compose-up.sh}
AUTHENTIK_POSTGRESQL__HOST: ${AUTHENTIK_POSTGRESQL__HOST:-postgres}
AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRESQL__USER:?Set AUTHENTIK_POSTGRESQL__USER in .env}
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRESQL__PASSWORD:?Set AUTHENTIK_POSTGRESQL__PASSWORD in .env}
AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRESQL__NAME:-authentik}
AUTHENTIK_REDIS__HOST: ${AUTHENTIK_REDIS__HOST:-keydb}
AUTHENTIK_WEB__PATH: /auth/
AUTHENTIK_HOST: http://${DOMAIN:-localhost}
env_file: ../.env.resolved
volumes:
- ./authentik/blueprints:/blueprints/custom:ro
- ./authentik/branding/ultisuite-logo-light.png:/web/dist/assets/branding/ultisuite-logo-light.png:ro
- ./authentik/branding/ultisuite-logo-dark.png:/web/dist/assets/branding/ultisuite-logo-dark.png:ro
- ./authentik/branding/ultisuite-favicon.png:/web/dist/assets/branding/ultisuite-favicon.png:ro
- ./authentik/branding/ultisuite-favicon-light.png:/web/dist/assets/branding/ultisuite-favicon-light.png:ro
- ./authentik/branding/ultisuite-favicon-dark.png:/web/dist/assets/branding/ultisuite-favicon-dark.png:ro
networks:
- ulti-net
healthcheck:
test: ["CMD", "ak", "healthcheck"]
interval: 15s
timeout: 10s
retries: 10
start_period: 90s
depends_on:
postgres:
condition: service_healthy
keydb:
condition: service_healthy
authentik-worker:
image: ghcr.io/goauthentik/server:latest
restart: unless-stopped
command: worker
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?Set AUTHENTIK_SECRET_KEY in .env and use ./deploy/compose-up.sh}
AUTHENTIK_POSTGRESQL__HOST: ${AUTHENTIK_POSTGRESQL__HOST:-postgres}
AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRESQL__USER:?Set AUTHENTIK_POSTGRESQL__USER in .env}
AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRESQL__PASSWORD:?Set AUTHENTIK_POSTGRESQL__PASSWORD in .env}
AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRESQL__NAME:-authentik}
AUTHENTIK_REDIS__HOST: ${AUTHENTIK_REDIS__HOST:-keydb}
AUTHENTIK_WEB__PATH: /auth/
AUTHENTIK_HOST: http://${DOMAIN:-localhost}
env_file: ../.env.resolved
volumes:
- ./authentik/blueprints:/blueprints/custom:ro
- ./authentik/branding/ultisuite-logo-light.png:/web/dist/assets/branding/ultisuite-logo-light.png:ro
- ./authentik/branding/ultisuite-logo-dark.png:/web/dist/assets/branding/ultisuite-logo-dark.png:ro
- ./authentik/branding/ultisuite-favicon.png:/web/dist/assets/branding/ultisuite-favicon.png:ro
- ./authentik/branding/ultisuite-favicon-light.png:/web/dist/assets/branding/ultisuite-favicon-light.png:ro
- ./authentik/branding/ultisuite-favicon-dark.png:/web/dist/assets/branding/ultisuite-favicon-dark.png:ro
networks:
- ulti-net
depends_on:
postgres:
condition: service_healthy
keydb:
condition: service_healthy
authentik-server:
condition: service_healthy
healthcheck:
test: ["CMD", "ak", "healthcheck"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
prometheus:
image: prom/prometheus:v2.54.1
restart: unless-stopped
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --web.enable-lifecycle
volumes:
- ./observability/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./observability/prometheus/alerts.yml:/etc/prometheus/rules/alerts.yml:ro
- prometheus_data:/prometheus
ports:
- "9090:9090"
networks:
- ulti-net
depends_on:
ultid:
condition: service_started
grafana:
image: grafana/grafana:11.3.0
restart: unless-stopped
environment:
GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin}
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin}
GF_USERS_ALLOW_SIGN_UP: "false"
volumes:
- ./observability/grafana/provisioning:/etc/grafana/provisioning:ro
- ./observability/grafana/ultid-baseline.json:/etc/grafana/dashboards/ultid-baseline.json:ro
- grafana_data:/var/lib/grafana
ports:
- "3002:3000"
networks:
- ulti-net
depends_on:
prometheus:
condition: service_started
suite-frontend:
build:
context: ../../gmail-interface-clone
dockerfile: Dockerfile
restart: unless-stopped
environment:
- ULTI_PROXY_ORIGIN=http://nginx
- NEXT_PUBLIC_API_URL=/api/v1
- NEXT_PUBLIC_APP_URL=http://${DOMAIN:-localhost}
- OIDC_CLIENT_SECRET=${ULTID_OIDC_CLIENT_SECRET:-changeme}
- NEXT_PUBLIC_OIDC_ISSUER=http://${DOMAIN:-localhost}/auth/application/o/ulti/
- NEXT_PUBLIC_OIDC_CLIENT_ID=${ULTID_OIDC_CLIENT_ID:-ulti-backend}
- NEXT_PUBLIC_ONLYOFFICE_URL=http://${DOMAIN:-localhost}/office
networks:
- ulti-net
depends_on:
- ultid
networks:
ulti-net:
driver: bridge
volumes:
postgres_data:
keydb_data:
rustfs_data:
prometheus_data:
grafana_data: