name: overcooked-e x-logging: &logging driver: json-file options: max-size: 10m max-file: "5" services: postgres: image: postgres:17-alpine restart: unless-stopped environment: POSTGRES_DB: product_e POSTGRES_USER: product_e POSTGRES_PASSWORD: ${PRODUCT_E_POSTGRES_PASSWORD:?required} POSTGRES_INITDB_ARGS: --data-checksums volumes: - e-postgres:/var/lib/postgresql/data - e-backup-staging:/backup healthcheck: test: ["CMD-SHELL", "pg_isready -U product_e -d product_e"] interval: 5s timeout: 3s retries: 20 networks: [backend] security_opt: [no-new-privileges:true] logging: *logging mem_limit: 2g valkey: image: valkey/valkey:8-alpine restart: unless-stopped environment: VALKEY_PASSWORD: ${PRODUCT_E_VALKEY_PASSWORD:?required} command: ["sh", "-ec", "exec valkey-server --appendonly yes --save 60 1 --requirepass \"$${VALKEY_PASSWORD}\""] volumes: - e-valkey:/data healthcheck: test: ["CMD-SHELL", "valkey-cli -a \"$${VALKEY_PASSWORD}\" --no-auth-warning ping | grep -q PONG"] interval: 5s timeout: 3s retries: 20 networks: [backend] security_opt: [no-new-privileges:true] logging: *logging mem_limit: 1g e-server: image: ${PRODUCT_E_IMAGE:?required} restart: unless-stopped init: true depends_on: postgres: {condition: service_healthy} valkey: {condition: service_healthy} ports: - ${PRODUCT_E_HTTP_PORT_MAPPING:-0.0.0.0:8096:8096} read_only: true tmpfs: - /tmp:size=64m,mode=1777 volumes: - e-data:/data - e-plugin-data:/data/plugins - ${OVERCOOKED_ROOT:-/opt/overcooked}/config/e-server.production.yaml:/etc/overcooked-e/config.yaml:ro - ${OVERCOOKED_ROOT:-/opt/overcooked}/control-plane:/run/overcooked-control-plane:ro environment: PRODUCT_E_CONFIG: /etc/overcooked-e/config.yaml PRODUCT_E_ENVIRONMENT: production PRODUCT_E_INSTANCE_ID: ${PRODUCT_E_INSTANCE_ID:-production-e-1} PRODUCT_E_DATABASE_URL: ${PRODUCT_E_DATABASE_URL:?required} PRODUCT_E_VALKEY_ADDRESS: valkey:6379 PRODUCT_E_VALKEY_PASSWORD: ${PRODUCT_E_VALKEY_PASSWORD:?required} PRODUCT_E_CONTROL_PLANE_URL: ${PRODUCT_E_CONTROL_PLANE_URL:?required} PRODUCT_E_CONTROL_PLANE_KEY_ID: ${PRODUCT_E_CONTROL_PLANE_KEY_ID:?required} PRODUCT_E_CONTROL_PLANE_SHARED_SECRET: ${PRODUCT_E_CONTROL_PLANE_SHARED_SECRET:?required} PRODUCT_E_CONTROL_PLANE_TLS_CERT_FILE: ${PRODUCT_E_CONTROL_PLANE_TLS_CERT_FILE:?required} PRODUCT_E_CONTROL_PLANE_TLS_KEY_FILE: ${PRODUCT_E_CONTROL_PLANE_TLS_KEY_FILE:?required} PRODUCT_E_CONTROL_PLANE_TLS_CA_FILE: ${PRODUCT_E_CONTROL_PLANE_TLS_CA_FILE:?required} PRODUCT_E_LICENSE_ENABLED: ${PRODUCT_E_LICENSE_ENABLED:-true} PRODUCT_E_AUTH_URL: ${PRODUCT_E_AUTH_URL:?required} PRODUCT_E_AUTH_ALLOW_INSECURE_HTTP: ${PRODUCT_E_AUTH_ALLOW_INSECURE_HTTP:-false} PRODUCT_E_AUTH_ACTIVATION_CODE: ${PRODUCT_E_AUTH_ACTIVATION_CODE:-} PRODUCT_E_AUTH_PUBLIC_KEYS: ${PRODUCT_E_AUTH_PUBLIC_KEYS:?required} PRODUCT_E_PLAYBACK_TICKET_SECRET: ${PRODUCT_E_PLAYBACK_TICKET_SECRET:?required} PRODUCT_E_PLAYBACK_TICKET_KEY_ID: ${PRODUCT_E_PLAYBACK_TICKET_KEY_ID:?required} PRODUCT_E_PLAYBACK_TICKET_PREVIOUS_PUBLIC_KEYS: ${PRODUCT_E_PLAYBACK_TICKET_PREVIOUS_PUBLIC_KEYS:-{}} PRODUCT_E_PLAYBACK_LEASE_KEY: ${PRODUCT_E_PLAYBACK_LEASE_KEY:?required} PRODUCT_E_STORAGE_CREDENTIAL_KEY: ${PRODUCT_E_STORAGE_CREDENTIAL_KEY:?required} PRODUCT_E_STORAGE_CREDENTIAL_KEY_ID: ${PRODUCT_E_STORAGE_CREDENTIAL_KEY_ID:?required} PRODUCT_E_STORAGE_CREDENTIAL_PREVIOUS_KEYS: ${PRODUCT_E_STORAGE_CREDENTIAL_PREVIOUS_KEYS:-{}} PRODUCT_E_PLUGIN_ENABLED: "true" PRODUCT_E_PLUGIN_UNSIGNED_POLICY: require-signature PRODUCT_E_PLUGIN_TRUSTED_PUBLISHERS: ${PRODUCT_E_PLUGIN_TRUSTED_PUBLISHERS:-{}} PRODUCT_E_PLUGIN_SECRET_KEY_ID: ${PRODUCT_E_PLUGIN_SECRET_KEY_ID:?required} PRODUCT_E_PLUGIN_SECRET_KEY: ${PRODUCT_E_PLUGIN_SECRET_KEY:?required} PRODUCT_E_PLUGIN_PREVIOUS_SECRET_KEYS: ${PRODUCT_E_PLUGIN_PREVIOUS_SECRET_KEYS:-{}} PRODUCT_E_TMDB_TOKEN: ${PRODUCT_E_TMDB_TOKEN:-} PRODUCT_E_BANGUMI_TOKEN: ${PRODUCT_E_BANGUMI_TOKEN:-} healthcheck: test: ["CMD-SHELL", "wget -q -O /dev/null http://127.0.0.1:8096/health/live || exit 1"] interval: 10s timeout: 3s start_period: 20s retries: 6 stop_grace_period: 45s networks: backend: control-plane: aliases: [product-e] egress: security_opt: [no-new-privileges:true] cap_drop: [ALL] logging: *logging mem_limit: 4g networks: backend: internal: true control-plane: external: true name: overcooked-control egress: volumes: e-postgres: e-valkey: e-data: e-plugin-data: e-backup-staging: