services: dispatcher: build: . ports: - "8030:8000" environment: TZ: ${TZ:-Asia/Shanghai} ADMIN_USERNAME: ${ADMIN_USERNAME:-admin} ADMIN_PASSWORD: ${ADMIN_PASSWORD:-change-me-now} SESSION_SECRET: ${SESSION_SECRET:-replace-with-a-long-random-secret} WEBHOOK_TOKEN: ${WEBHOOK_TOKEN:-} RETENTION_DAYS: ${RETENTION_DAYS:-30} MAX_DELIVERY_ATTEMPTS: ${MAX_DELIVERY_ATTEMPTS:-3} RETRY_BACKOFF_SECONDS: ${RETRY_BACKOFF_SECONDS:-60} FEISHU_TIMEOUT_SECONDS: ${FEISHU_TIMEOUT_SECONDS:-10} DISPATCH_INLINE: ${DISPATCH_INLINE:-false} DISPATCH_WAKEUP_ON_RECEIVE: ${DISPATCH_WAKEUP_ON_RECEIVE:-true} DELIVERY_BATCH_SIZE: ${DELIVERY_BATCH_SIZE:-100} DELIVERY_CONCURRENCY: ${DELIVERY_CONCURRENCY:-5} volumes: - dispatcher-data:/data worker: build: . command: ["python", "-m", "app.worker"] environment: TZ: ${TZ:-Asia/Shanghai} ADMIN_USERNAME: ${ADMIN_USERNAME:-admin} ADMIN_PASSWORD: ${ADMIN_PASSWORD:-change-me-now} SESSION_SECRET: ${SESSION_SECRET:-replace-with-a-long-random-secret} WEBHOOK_TOKEN: ${WEBHOOK_TOKEN:-} RETENTION_DAYS: ${RETENTION_DAYS:-30} MAX_DELIVERY_ATTEMPTS: ${MAX_DELIVERY_ATTEMPTS:-3} RETRY_BACKOFF_SECONDS: ${RETRY_BACKOFF_SECONDS:-60} FEISHU_TIMEOUT_SECONDS: ${FEISHU_TIMEOUT_SECONDS:-10} DISPATCH_INLINE: ${DISPATCH_INLINE:-false} DISPATCH_WAKEUP_ON_RECEIVE: ${DISPATCH_WAKEUP_ON_RECEIVE:-true} DELIVERY_BATCH_SIZE: ${DELIVERY_BATCH_SIZE:-100} DELIVERY_CONCURRENCY: ${DELIVERY_CONCURRENCY:-5} WORKER_INTERVAL_SECONDS: ${WORKER_INTERVAL_SECONDS:-2} volumes: - dispatcher-data:/data volumes: dispatcher-data: