version: "3.8" # 天工智能体平台 — 生产环境 Docker Compose # 启动: docker compose -f docker-compose.prod.yml up -d # 停止: docker compose -f docker-compose.prod.yml down services: # ─── MySQL ─────────────────────────────────────────────────── mysql: image: mysql:8.0 container_name: aiagent-mysql restart: always environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-change-me} MYSQL_DATABASE: agent_db MYSQL_CHARSET: utf8mb4 MYSQL_COLLATION: utf8mb4_unicode_ci ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql - ./backend/init.sql:/docker-entrypoint-initdb.d/init.sql:ro healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 start_period: 30s networks: - aiagent-net # ─── Redis ─────────────────────────────────────────────────── redis: image: redis:7-alpine container_name: aiagent-redis restart: always command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 networks: - aiagent-net # ─── FastAPI 后端 ──────────────────────────────────────────── backend: build: context: ./backend dockerfile: Dockerfile container_name: aiagent-backend restart: always environment: - DATABASE_URL=mysql+pymysql://root:${MYSQL_ROOT_PASSWORD:-change-me}@mysql:3306/agent_db?charset=utf8mb4 - REDIS_URL=redis://redis:6379/0 - JWT_SECRET_KEY=${JWT_SECRET_KEY:-prod-jwt-secret-change-me} - SECRET_KEY=${SECRET_KEY:-prod-secret-change-me} - CORS_ORIGINS=${CORS_ORIGINS:-http://localhost:8038,http://localhost:3000} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-} - EXTERNAL_URL=${EXTERNAL_URL:-http://localhost} ports: - "8037:8037" depends_on: mysql: condition: service_healthy redis: condition: service_healthy volumes: - agent_workspaces:/app/agent_workspaces - uploads:/app/uploads - logs:/app/logs healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8037/docs"] interval: 30s timeout: 10s retries: 3 networks: - aiagent-net # ─── Celery Worker ─────────────────────────────────────────── celery-worker: build: context: ./backend dockerfile: Dockerfile container_name: aiagent-celery-worker restart: always command: celery -A app.core.celery_app worker --loglevel=info --concurrency=4 environment: - DATABASE_URL=mysql+pymysql://root:${MYSQL_ROOT_PASSWORD:-change-me}@mysql:3306/agent_db?charset=utf8mb4 - REDIS_URL=redis://redis:6379/0 - JWT_SECRET_KEY=${JWT_SECRET_KEY:-prod-jwt-secret-change-me} - SECRET_KEY=${SECRET_KEY:-prod-secret-change-me} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-} depends_on: mysql: condition: service_healthy redis: condition: service_healthy volumes: - agent_workspaces:/app/agent_workspaces - uploads:/app/uploads - logs:/app/logs networks: - aiagent-net # ─── Celery Beat (定时调度) ────────────────────────────────── celery-beat: build: context: ./backend dockerfile: Dockerfile container_name: aiagent-celery-beat restart: always command: celery -A app.core.celery_app beat --loglevel=info environment: - DATABASE_URL=mysql+pymysql://root:${MYSQL_ROOT_PASSWORD:-change-me}@mysql:3306/agent_db?charset=utf8mb4 - REDIS_URL=redis://redis:6379/0 - JWT_SECRET_KEY=${JWT_SECRET_KEY:-prod-jwt-secret-change-me} - SECRET_KEY=${SECRET_KEY:-prod-secret-change-me} depends_on: mysql: condition: service_healthy redis: condition: service_healthy networks: - aiagent-net # ─── 前端 (Nginx) ─────────────────────────────────────────── frontend: build: context: ./frontend dockerfile: Dockerfile container_name: aiagent-frontend restart: always ports: - "8038:80" depends_on: - backend networks: - aiagent-net # ─── Prometheus 监控 ─────────────────────────────────────────── prometheus: image: prom/prometheus:v2.53.0 container_name: aiagent-prometheus restart: always ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./prometheus-alert-rules.yml:/etc/prometheus/alert_rules.yml:ro - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' - '--web.enable-lifecycle' networks: - aiagent-net # ─── Grafana 可视化 ──────────────────────────────────────────── grafana: image: grafana/grafana:11.0.0 container_name: aiagent-grafana restart: always environment: - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin} - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin123} - GF_INSTALL_PLUGINS=grafana-piechart-panel - GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana - GF_USERS_ALLOW_SIGN_UP=false ports: - "3000:3000" volumes: - ./grafana/datasources:/etc/grafana/provisioning/datasources:ro - ./grafana/dashboards:/etc/grafana/provisioning/dashboards:ro - ./grafana/dashboards/tiangong-overview.json:/var/lib/grafana/dashboards/tiangong-overview.json:ro - grafana_data:/var/lib/grafana depends_on: - prometheus networks: - aiagent-net # ─── ELK 日志聚合 ───────────────────────────────────────────────── elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0 container_name: aiagent-elasticsearch restart: always environment: - discovery.type=single-node - ES_JAVA_OPTS=-Xms512m -Xmx1g - xpack.security.enabled=false ports: - "9200:9200" volumes: - es_data:/usr/share/elasticsearch/data healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q 'green\|yellow'"] interval: 15s timeout: 10s retries: 10 networks: - aiagent-net kibana: image: docker.elastic.co/kibana/kibana:8.15.0 container_name: aiagent-kibana restart: always environment: - ELASTICSEARCH_HOSTS=http://elasticsearch:9200 ports: - "5601:5601" depends_on: elasticsearch: condition: service_healthy networks: - aiagent-net filebeat: image: docker.elastic.co/beats/filebeat:8.15.0 container_name: aiagent-filebeat restart: always volumes: - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro - logs:/app/logs:ro depends_on: - elasticsearch networks: - aiagent-net volumes: mysql_data: driver: local redis_data: driver: local agent_workspaces: driver: local uploads: driver: local logs: driver: local prometheus_data: driver: local grafana_data: driver: local es_data: driver: local networks: aiagent-net: driver: bridge