services: backend: build: context: . dockerfile: infra/docker/Dockerfile.backend image: dealerhub-backend:latest restart: unless-stopped environment: DJANGO_SETTINGS_MODULE: config.settings.prod DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:?required} DJANGO_ALLOWED_HOSTS: "*" DATABASE_URL: postgres://dealerhub:${POSTGRES_PASSWORD}@pg-main:5432/dealerhub REDIS_URL: redis://dsp-redis:6379/2 GRANIAN_WORKERS: "4" depends_on: pg-bootstrap: condition: service_completed_successfully networks: - pg-shared - dsp-net ports: - "18050:8000" healthcheck: test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/api/v1/ping/"] interval: 10s timeout: 3s retries: 10 worker: image: dealerhub-backend:latest restart: unless-stopped environment: DJANGO_SETTINGS_MODULE: config.settings.prod DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY:?required} DJANGO_ALLOWED_HOSTS: "*" DATABASE_URL: postgres://dealerhub:${POSTGRES_PASSWORD}@pg-main:5432/dealerhub REDIS_URL: redis://dsp-redis:6379/2 TASK_BROKER: redis depends_on: - backend networks: - pg-shared - dsp-net command: ["dramatiq", "config.dramatiq", "--processes", "1", "--threads", "4"] # 覆盖镜像内 curl:8000 健康检查(worker 不监听 HTTP),改为检查 PID 1 存活 healthcheck: test: ["CMD-SHELL", "kill -0 1"] interval: 30s timeout: 5s retries: 3 pg-bootstrap: image: postgres:16-alpine networks: - pg-shared environment: PGPASSWORD: ${POSTGRES_PASSWORD:?required} entrypoint: - sh - -c - | set -e echo "[pg-bootstrap] waiting for pg-main..." until pg_isready -h pg-main -p 5432 -U postgres; do sleep 1; done echo "[pg-bootstrap] ensuring role+db..." psql -h pg-main -U postgres -tc "SELECT 1 FROM pg_roles WHERE rolname='dealerhub'" | grep -q 1 || \ psql -h pg-main -U postgres -c "CREATE ROLE dealerhub LOGIN PASSWORD '$$POSTGRES_PASSWORD'" psql -h pg-main -U postgres -tc "SELECT 1 FROM pg_database WHERE datname='dealerhub'" | grep -q 1 || \ psql -h pg-main -U postgres -c "CREATE DATABASE dealerhub OWNER dealerhub" echo "[pg-bootstrap] done" restart: "no" networks: pg-shared: external: true # 连到 1Panel 既有的 pg-shared 网络(pg-main 在这) dsp-net: external: true name: deploy_dsp-net # 复用 dsp 项目栈的无密码 redis(dsp-redis)做任务队列