name: dc-cms services: reverse-proxy: image: caddy:2-alpine restart: unless-stopped env_file: - .env ports: - "${CMS_HTTP_BIND:-127.0.0.1:8210}:80" - "${CMS_AUTH_HTTP_BIND:-127.0.0.1:8211}:80" - "${CMS_AUTH_ADMIN_HTTP_BIND:-127.0.0.1:8212}:80" volumes: - ./reverse-proxy/Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data - caddy-config:/config depends_on: cms-app: condition: service_started authentik-server: condition: service_started networks: cms-edge: aliases: - ${CMS_DOMAIN:-cms.local.nodedc} - ${CMS_AUTH_DOMAIN:-cms-auth.local.nodedc} - ${CMS_AUTH_ADMIN_DOMAIN:-cms-auth-admin.local.nodedc} cms-app: build: context: .. restart: unless-stopped env_file: - .env environment: HOST: 0.0.0.0 PORT: 8090 SITE_ROOT: /sites/nodedc CMS_AUTH_ENABLED: ${CMS_AUTH_ENABLED:-true} CMS_OIDC_ISSUER: ${CMS_OIDC_ISSUER:?cms oidc issuer required} CMS_OIDC_CLIENT_ID: ${CMS_OIDC_CLIENT_ID:?cms oidc client id required} CMS_OIDC_CLIENT_SECRET: ${CMS_OIDC_CLIENT_SECRET:?cms oidc client secret required} CMS_OIDC_REDIRECT_URI: ${CMS_OIDC_REDIRECT_URI:?cms oidc redirect uri required} CMS_OIDC_LOGGED_OUT_REDIRECT_URI: ${CMS_OIDC_LOGGED_OUT_REDIRECT_URI:?cms oidc logged out redirect uri required} CMS_REQUIRED_GROUPS: ${CMS_REQUIRED_GROUPS:-dc-cms:owner,dc-cms:admin,dc-cms:editor,dc-cms:publisher} CMS_SESSION_SECRET: ${CMS_SESSION_SECRET:?cms session secret required} COOKIE_SECURE: ${COOKIE_SECURE:-false} COOKIE_DOMAIN: ${COOKIE_DOMAIN:-} expose: - "8090" volumes: - ../projects:/app/projects - ${CMS_NODEDC_SITE_PATH:-../../NODEDC_SITE}:/sites/nodedc depends_on: authentik-server: condition: service_started networks: - cms-edge postgresql-authentik: image: docker.io/library/postgres:16-alpine restart: unless-stopped env_file: - .env environment: POSTGRES_DB: ${PG_DB:-authentik} POSTGRES_PASSWORD: ${PG_PASS:?database password required} POSTGRES_USER: ${PG_USER:-authentik} healthcheck: test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] interval: 30s timeout: 5s retries: 5 start_period: 20s volumes: - authentik-database:/var/lib/postgresql/data networks: - cms-edge authentik-server: image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2} command: server restart: unless-stopped env_file: - .env environment: AUTHENTIK_POSTGRESQL__HOST: postgresql-authentik AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:?database password required} AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required} AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS: ${AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS:-127.0.0.0/8,172.16.0.0/12} AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING__ENABLED:-false} AUTHENTIK_BOOTSTRAP_EMAIL: ${AUTHENTIK_BOOTSTRAP_EMAIL:-} AUTHENTIK_BOOTSTRAP_PASSWORD: ${AUTHENTIK_BOOTSTRAP_PASSWORD:-} AUTHENTIK_BOOTSTRAP_TOKEN: ${AUTHENTIK_BOOTSTRAP_TOKEN:-} depends_on: postgresql-authentik: condition: service_healthy expose: - "9000" - "9443" shm_size: 512mb volumes: - authentik-data:/data - ./authentik/custom-templates:/templates:ro networks: - cms-edge authentik-worker: image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2.2} command: worker restart: unless-stopped user: root env_file: - .env environment: AUTHENTIK_POSTGRESQL__HOST: postgresql-authentik AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS:?database password required} AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required} AUTHENTIK_ERROR_REPORTING__ENABLED: ${AUTHENTIK_ERROR_REPORTING__ENABLED:-false} depends_on: postgresql-authentik: condition: service_healthy shm_size: 512mb volumes: - authentik-data:/data - authentik-certs:/certs - ./authentik/custom-templates:/templates:ro - ./authentik/bootstrap-cms.py:/bootstrap/bootstrap-cms.py:ro networks: - cms-edge networks: cms-edge: volumes: authentik-database: authentik-data: authentik-certs: caddy-data: caddy-config: