services: mysql: image: mysql:8.0 environment: MYSQL_DATABASE: email_forecast MYSQL_USER: app MYSQL_PASSWORD: app MYSQL_ROOT_PASSWORD: root ports: - "7023:3306" volumes: - mysql_data:/var/lib/mysql command: - --default-authentication-plugin=mysql_native_password - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uapp", "-papp"] interval: 5s timeout: 5s retries: 20 web: build: . command: ["sh", "/app/scripts/docker-entrypoint-web.sh"] ports: - "3100:3100" env_file: - .env environment: DATABASE_URL: mysql://app:app@mysql:3306/email_forecast SEED_ON_START: ${SEED_ON_START:-true} volumes: - ./data:/app/data depends_on: mysql: condition: service_healthy healthcheck: test: [ "CMD", "node", "-e", "fetch('http://127.0.0.1:3100/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))", ] interval: 10s timeout: 5s retries: 12 start_period: 40s worker: build: . # tsx 跑源码,避免 dist 中 @/ 别名未重写导致 MODULE_NOT_FOUND command: ["pnpm", "exec", "tsx", "src/worker/index.ts"] env_file: - .env environment: DATABASE_URL: mysql://app:app@mysql:3306/email_forecast volumes: - ./data:/app/data depends_on: mysql: condition: service_healthy restart: unless-stopped volumes: mysql_data: