version: '3.8' services: # MySQL 数据库服务 db: image: mysql:8.0 container_name: performance-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: employee_performance MYSQL_USER: app_user MYSQL_PASSWORD: 123456 ports: - "33306:3306" volumes: - mysql_data:/var/lib/mysql - ./backend/src/db/init.sql:/docker-entrypoint-initdb.d/init.sql networks: - app-network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123456"] interval: 10s timeout: 5s retries: 5 start_period: 30s command: - --default-authentication-plugin=mysql_native_password - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci # 后端 API 服务 backend: build: context: ./backend dockerfile: Dockerfile container_name: performance-backend restart: unless-stopped depends_on: db: condition: service_healthy environment: DB_HOST: db DB_PORT: 3306 DB_USER: app_user DB_PASSWORD: 123456 DB_NAME: employee_performance JWT_SECRET: your_jwt_secret_here_change_in_production FASTGPT_API_KEY: ${FASTGPT_API_KEY:-your_fastgpt_api_key_here} FASTGPT_API_URL: https://api.fastgpt.in/api/v1/chat/completions FASTGPT_MODEL: gpt-4 PORT: 3001 NODE_ENV: development ports: - "33001:3001" volumes: - ./backend:/app - /app/node_modules networks: - app-network healthcheck: test: ["CMD", "node", "-e", "const http = require('http'); http.get('http://localhost:3001/api/health', (res) => { if (res.statusCode !== 200) throw new Error('Health check failed') }).on('error', (err) => { console.error(err); process.exit(1); })"] interval: 30s timeout: 5s retries: 3 start_period: 20s # 前端开发服务 frontend: build: context: ./frontend dockerfile: Dockerfile container_name: performance-frontend restart: unless-stopped depends_on: - backend environment: VITE_API_BASE_URL: http://47.238.126.111:33001 VITE_API_URL: http://backend:3001 ports: - "2000:3000" volumes: - ./frontend:/app - /app/node_modules networks: - app-network healthcheck: test: ["CMD", "node", "-e", "const http = require('http'); http.get('http://localhost:3000', (res) => { if (res.statusCode !== 200) throw new Error('Health check failed') }).on('error', (err) => { console.error(err); process.exit(1); })"] interval: 30s timeout: 5s retries: 3 start_period: 30s # 定义网络 networks: app-network: driver: bridge # 定义数据卷 volumes: mysql_data: driver: local