# 非 host 版本, 容器内部使用桥接通信
# (各项参数均有详细的说明，理论情况下保持默认即可运行)
#version: '3'
services:
  comfyAI-web:
    container_name: comfyAI-web
    #更新修改冒号后面的版本号
    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/one-ai:${VERSION}
    #端口冲突时，只需要修改前面的端口比如修改为，3011:3010
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    ports:
      - "${WEB_PORT}:3010"
    read_only: true
    volumes:
      # 这一行是关键。它将一个名为 './data/forend/.pm2' 的持久化卷挂载到容器内的 /app/.pm2 目录
      - ./data/forend/.pm2:/app/.pm2
    networks:
      comfyai:
        ipv4_address: 172.21.0.8
    depends_on:
      - comfy-server
    restart: unless-stopped
    environment:
      # 默认服务器地址，本地不需要更改，云服务需要修改为云端IP，并放行对应端口
      - NUXT_PUBLIC_BASE_APIURL=${NUXT_PUBLIC_BASE_APIURL}
      #增加服务端渲染配置，保持默认即可，不需要修改！
      - NUXT_PUBLIC_BASE_SSRURL=http://172.21.0.6:3001
      # 默认的服务器websocket地址，本地不需要更改，云服务需要修改为云端IP，并放行对应端口
      - NUXT_PUBLIC_BASE_SOCKETURL=${NUXT_PUBLIC_BASE_SOCKETURL}
      - NUXT_APP_CDN_URL=${NUXT_APP_CDN_URL}
    # 日志大小设置，避免日志文件过大
    env_file:
      - .env
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
    # 资源限制，防止内存溢出
    deploy:
      resources:
        limits:
          memory: 1500MB
        reservations:
          memory: 600MB
  comfy-server:
    container_name: comfy-server
    # 阿里云镜像地址
    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/comfy-server:${VERSION} # 阿里云
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    ports:
      - "${SERVER_HTTP_PORT}:3001"    #http端口
    read_only: true
    networks:
      comfyai:
        ipv4_address: 172.21.0.6
    depends_on:
      - mongo
      - redis
      - rabbitmq
    volumes:
      - ./data/upload:/app/upload
      - ./data/backups:/app/backups
      - ./data/restores:/app/restores
      - ./data/backend/app/tmp:/app/tmp
      - ./data/tmp:/tmp
      - ./data/backend/.pm2:/app/.pm2
#      - ./data/backend/pm2.config.js:/app/pm2.config.js
    restart: unless-stopped
    environment:
      #  MongoDB配置，用户管理，不会配置的话保持默认即可
      - CONFIG_DB_MONGO_URI=mongodb://172.21.0.3:27017
      - CONFIG_DB_MONGO_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - CONFIG_DB_MONGO_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
      #  Redis配置，队列缓存，不会配置的话保持默认即可
      - CONFIG_COMFYUI_QUENE_REDIS_HOST=172.21.0.4
      - CONFIG_COMFYUI_QUENE_REDIS_PORT=6379
      - CONFIG_COMFYUI_QUENE_REDIS_USERNAME=${CONFIG_COMFYUI_QUENE_REDIS_USERNAME}
      - CONFIG_COMFYUI_QUENE_REDIS_PASSWORD=${CONFIG_COMFYUI_QUENE_REDIS_PASSWORD}
      #队列使用的DB
      - CONFIG_COMFYUI_QUENE_REDIS_DB=${CONFIG_COMFYUI_QUENE_REDIS_DB}
      #普通缓存使用的DB
      - CONFIG_COMFYUI_CACHE_REDIS_DB=${CONFIG_COMFYUI_CACHE_REDIS_DB}
      #日志与调试
      - LOG_LEVEL=${LOG_LEVEL}
      #Token过期时间，单位秒
      - CONFIG_TOKEN_EXPIRE=${CONFIG_TOKEN_EXPIRE}
      - CONFIG_JWT_SECRET=${CONFIG_JWT_SECRET}
      # 代理服务器
      - CONFIG_PROXY_URL=${CONFIG_PROXY_URL}
      #禁用文档 true/false/留空
      - CONFIG_DOCS_DISABLE=false
      #MQ
      - CONFIG_MQ_PROTOCOL=${CONFIG_MQ_PROTOCOL}
      - CONFIG_MQ_USER=${CONFIG_MQ_USER}
      - CONFIG_MQ_PASSWORD=${CONFIG_MQ_PASSWORD}
      - CONFIG_MQ_HOST=rabbitmq
      - CONFIG_MQ_PORT=${CONFIG_MQ_PORT}
      - CONFIG_MQ_VHOST=${CONFIG_MQ_VHOST}
      # 视频编辑接口
      - CONFIG_VIDEO_EDIT_API_URL=http://video-edit:8000
      # 沙箱环境baseURL
      - SANDBOX_SERVICE_BASE_URL=${SANDBOX_SERVICE_BASE_URL:-http://sandbox:8000}
    # 日志大小设置，避免日志文件过大
    env_file:
      - .env
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
  ws-gateway:
    container_name: easyai-wsgateway  # websocket网关
    # 阿里云镜像地址
    image: registry.cn-shanghai.aliyuncs.com/easyaigc/wsgateway:latest # 阿里云
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    ports:
      - "${SERVER_WS_PORT}:3002"    #http端口
    read_only: true
    networks:
      - comfyai
    depends_on:
      - redis
      - rabbitmq
    volumes:
      - ./data/wsgateway/.pm2:/app/.pm2
    restart: unless-stopped
    environment:
      #  Redis配置，队列缓存，不会配置的话保持默认即可
      - CONFIG_COMFYUI_QUENE_REDIS_HOST=172.21.0.4
      - CONFIG_COMFYUI_QUENE_REDIS_PORT=6379
      - CONFIG_COMFYUI_QUENE_REDIS_PASSWORD=
      #日志与调试
      - LOG_LEVEL=${LOG_LEVEL}
      #MQ
      - CONFIG_MQ_USER=${CONFIG_MQ_USER}
      - CONFIG_MQ_PASSWORD=${CONFIG_MQ_PASSWORD}
      - CONFIG_MQ_HOST=rabbitmq
      - CONFIG_MQ_PORT=${CONFIG_MQ_PORT}
    # 日志大小设置，避免日志文件过大
    env_file:
      - .env
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
  mongo:
    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/mongo-aliyun:latest
#    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/mongo-aliyun:4.4
    container_name: mongo
    restart: unless-stopped
    privileged: true
    # 生产环境建议不要暴露
    ports:
      - ${MONGO_PORT+${MONGO_PORT}:27017}
    networks:
      comfyai:
        ipv4_address: 172.21.0.3
    environment:
      # 这里的配置只有首次运行生效。修改后，重启镜像是不会生效的。需要把持久化数据删除再重启，才有效果
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}
    volumes:
#      - /usr/local/mongo/data:/data/db
      - mongo_data:/data/db  # 使用docker volume存储数据，提高性能，避免兼容性问题
    healthcheck:
      test: ["CMD", "bash", "-c", "echo > /dev/tcp/localhost/${MONGO_PORT}"]
      interval: 30s
      retries: 3
      timeout: 10s
      start_period: 60s
    # 日志大小设置，避免日志文件过大
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
  redis:
    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/redis-aliyun:latest
    container_name: redis
    restart: always
    volumes:
      - ./redis.conf:/etc/redis/redis.conf  # 挂载本地 redis.conf
    command: [ "redis-server", "/etc/redis/redis.conf" ]  # 让 Redis 读取配置文件
#    ports:
#      - ${REDIS_PORT+${REDIS_PORT}:6379}
    read_only: true
    networks:
      comfyai:
        ipv4_address: 172.21.0.4
    # 日志大小设置，避免日志文件过大
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
  rabbitmq:
    image: registry.cn-shanghai.aliyuncs.com/easyaigc/mq:latest #阿里云镜像加速
#    image: rabbitmq:4-management #官方原版镜像
    container_name: rabbitmq
    restart: unless-stopped
    environment:
      RABBITMQ_DEFAULT_USER: ${CONFIG_MQ_USER}        # 登录用户名
      RABBITMQ_DEFAULT_PASS: ${CONFIG_MQ_PASSWORD}    # 登录密码
    ports:
      - "${CONFIG_MQ_PORT}:${CONFIG_MQ_PORT}"    # 应用连接端口 (AMQP)
      - "${CONFIG_MQ_ADMIN_PORT}:15672"  # Web 管理界面
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq  # 持久化数据
    networks:
      comfyai:
        ipv4_address: 172.21.0.12
  watchtower:
    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/watchtower-aliyun:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: --debug --http-api-update
    restart: always
    environment:
      - WATCHTOWER_HTTP_API_TOKEN=sk-ofJoA4atj9dki6AvDtI1qwxdcejjDQ
    labels:
      - "com.centurylinklabs.watchtower.enable=false"
#    ports:
#      - "${WATCHTOWER_PORT}:8080"
    read_only: true
    networks:
      comfyai:
        ipv4_address: 172.21.0.9
    # 日志大小设置，避免日志文件过大
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "10"
  video-edit:
    image: registry.cn-shanghai.aliyuncs.com/easyaigc/videoedit:latest
    container_name: video-edit
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    volumes:
      - ./data/videoedit/temp:/app/temp
    ports:
      - "${VIDEO_EDIT_PORT}:8000"
    environment:
      - PYTHONUNBUFFERED=1
      - OMP_NUM_THREADS=4
      - OPENBLAS_NUM_THREADS=4
    env_file:
      - .env.tools
    shm_size: 2g
    restart: unless-stopped
    networks:
      comfyai:
        ipv4_address: 172.21.0.10
    healthcheck:
      test: [ "CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/docs')" ]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
  dozzle:
    container_name: dozzle
    image: registry.cn-shanghai.aliyuncs.com/easyaigc/dozzle:latest
    environment:
      DOZZLE_BASE: /logs-web
#      DOZZLE_AUTH_PROVIDER: simple
      DOZZLE_AUTH_TTL: 72h
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/data
    ports:
      - 8080:8080
  sandbox:
    image: registry.cn-shanghai.aliyuncs.com/easyaigc/sandbox:latest
    container_name: sandbox
    networks:
      - comfyai
    #沙箱环境默认不对外暴露
#    ports:
#      - "${SANDBOX_PORT}:8000"
#      - "${SANDBOX_JUPYTERLAB_PORT}:8888"
    labels:
      - "com.centurylinklabs.watchtower.enable=true"
    volumes:
      - ./sandbox-data:/app/data
      - ./local_packages:/app/local_packages
      - ./env/python-packages:/root/.local
      - ./env/node-modules:/app/node_modules_extra
    tmpfs:
      - /app/tmp:mode=1777
      - /tmp:mode=1777
# 需要更加强的安全性，可以将ready only设置为true，可能影响使用Jupterlab 操作容器改动
#    read_only: true
    security_opt:
      - no-new-privileges:true
    environment:
      - NODE_PATH=/app/node_modules:/app/node_modules_extra/node_modules
      - NODE_MODULES_EXTRA=/app/node_modules_extra
      - NODE_MODULES_EXTRA_PATH=/app/node_modules_extra/node_modules
      - SANDBOX_TMPDIR=/app/tmp
      - PIP_CACHE_DIR=/app/tmp/.pip
      - TMPDIR=/app/tmp
      - NPM_CONFIG_CACHE=/app/tmp/.npm
      - PYTHON_EXTRA_DIR=/root/.local/lib/python3.12/site-packages
      - PYTHON_EXTRA_PATH=/root/.local/lib/python3.12/site-packages
      # Jupyter 运行时与数据写到可写目录，避免挂载 /root/.local 导致无法写入
      - JUPYTER_DATA_DIR=/app/tmp/jupyter_data
      - JUPYTER_RUNTIME_DIR=/app/tmp/jupyter_runtime
      - JUPYTER_CONFIG_DIR=/app/tmp/jupyter_config
      # Jupyter 访问 token：不设或为空则无需 token；设置后打开 JupyterLab 需填写该 token
      - JUPYTER_TOKEN=${SANDBOX_JUPYTER_TOKEN}
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 1G
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8000/health" ]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
#  portainer:
#    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/portainer-ce:2.21.5
#    container_name: portainer
#    restart: always
#    volumes:
#      - /var/run/docker.sock:/var/run/docker.sock
#      - portainer_data:/data
#    networks:
#      comfyai:
#        ipv4_address: 172.21.0.11
#    # 日志大小设置，避免日志文件过大
#    logging:
#      driver: "json-file"
#      options:
#        max-size: "100m"
#        max-file: "10"
##    ports:
##      - "${PORTAINER_PORT}:9000"
##      - "${PORTAINER_HTTPS_PORT}:9443"
#    read_only: true
# 如果需要部署minio，取消下方的注释即可
#  minio:
#    #    image: minio/minio
#    image: registry.cn-shanghai.aliyuncs.com/comfy-ai/minio:latest
#    ports:
#      - "9000:9000"
#      - "9001:9001" # MinIO Console (UI) 端口
#    volumes:
#      - ./miniodata:/data # **修改这里：将 ./data 替换为你的本地路径**
#    environment:
#      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
#      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} # 生产环境请务必修改
#    command: server /data --console-address ":9001"
#    healthcheck:
#      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
#      interval: 30s
#      timeout: 20s
#      retries: 3
#    restart: always
volumes:
  mongo_data:
  portainer_data:
  rabbitmq_data:
networks:
  comfyai:
    driver: bridge
    ipam:
      config:
        - subnet: 172.21.0.0/16
          gateway: 172.21.0.1


