services: mysql: image: mysql:8.0 restart: always environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} TZ: "Asia/Shanghai" volumes: - mysql_data:/var/lib/mysql command: - --default-authentication-plugin=mysql_native_password - --character-set-server=utf8mb4 - --collation-server=utf8mb4_0900_ai_ci healthcheck: test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p$${MYSQL_ROOT_PASSWORD} --silent"] interval: 5s timeout: 5s retries: 20 redis: image: redis:7-alpine restart: always command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD}"] volumes: - redis_data:/data healthcheck: test: ["CMD-SHELL", "redis-cli -a \"$${REDIS_PASSWORD}\" ping"] interval: 5s timeout: 3s retries: 20 rabbitmq: image: rabbitmq:3-management restart: always environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS} volumes: - rabbitmq_data:/var/lib/rabbitmq healthcheck: test: ["CMD-SHELL", "rabbitmq-diagnostics -q ping"] interval: 5s timeout: 5s retries: 20 backend: image: ${REGISTRY}/${OWNER}/${REPO}/backend-api:${TAG} restart: always environment: CONFIG_PATH: /app/configs/config.yaml # Docker 内部服务发现 —— 覆盖 baked-in config.yaml 中的 localhost MYSQL_HOST: mysql REDIS_HOST: redis RABBITMQ_HOST: rabbitmq # 密码和密钥 —— 从 .env 注入 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} REDIS_PASSWORD: ${REDIS_PASSWORD} RABBITMQ_USER: ${RABBITMQ_USER} RABBITMQ_PASS: ${RABBITMQ_PASS} JWT_SECRET: ${JWT_SECRET} volumes: - backend_uploads:/app/.run/uploads depends_on: mysql: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy healthcheck: test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/healthz || exit 1"] interval: 10s timeout: 5s retries: 3 worker: image: ${REGISTRY}/${OWNER}/${REPO}/backend-worker:${TAG} restart: always environment: CONFIG_PATH: /app/configs/config.yaml MYSQL_HOST: mysql REDIS_HOST: redis RABBITMQ_HOST: rabbitmq MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} REDIS_PASSWORD: ${REDIS_PASSWORD} RABBITMQ_USER: ${RABBITMQ_USER} RABBITMQ_PASS: ${RABBITMQ_PASS} JWT_SECRET: ${JWT_SECRET} depends_on: mysql: condition: service_healthy redis: condition: service_healthy rabbitmq: condition: service_healthy healthcheck: test: ["CMD-SHELL", "pgrep worker || exit 1"] interval: 15s timeout: 5s retries: 3 frontend: image: ${REGISTRY}/${OWNER}/${REPO}/frontend:${TAG} restart: always ports: - "127.0.0.1:9001:80" volumes: - ./nginx.prod.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - backend healthcheck: test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:80/ || exit 1"] interval: 10s timeout: 5s retries: 3 volumes: mysql_data: redis_data: rabbitmq_data: backend_uploads: