Ctrl K
ComunidadGuías…

docker-compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Open ACE - AI Computing Explorer - Docker Compose Configuration
# For production deployment with PostgreSQL database
#
# ============================================================================
# DEPLOYMENT MODES
# ============================================================================
#
# 🚀 Single-User Mode (DEFAULT):
#   This is the default mode. Container runs as non-root (uid 1000).
#   No additional configuration needed.
#
#   Quick start:
#     docker compose up -d
#     # Access http://localhost:19888
#
# 👥 Multi-User Workspace Mode:
#   Enables per-user workspace isolation. Container MUST run as root to create
#   system users (useradd, chown, sudo -u operations).
#
#   ⚠️ IMPORTANT: Do NOT modify this file to enable multi-user mode!
#   Use the dedicated overlay file instead:
#
#   Option 1 - One-click script (RECOMMENDED):
#     ./scripts/start-multi-user.sh
#
#   Option 2 - Docker Compose overlay:
#     docker compose -f docker-compose.yml -f docker-compose.multi-user.yml up -d
#
#   Why not modify this file?
#   - Security: Default config follows least-privilege principle (non-root)
#   - Safety: Entrypoint validates config consistency and fails fast on errors
#   - Best practice: Overlay pattern is the official Docker Compose recommendation
#
# 📦 Pull pre-built image from Docker Hub:
#   docker compose up -d
#
# 🔒 HTTPS reverse proxy:
#   Follow docs/guide/NGINX.md
#
# 🔧 Developer build (for local testing):
#   docker build -t open-ace:dev --target production .
#   IMAGE_NAME=open-ace:dev docker compose up -d
#
# ============================================================================
# MULTI-USER MODE DETAILS
# ============================================================================
#
# The docker-compose.multi-user.yml overlay adds:
#   - user: "0"                        # Run container as root
#   - WORKSPACE_ISOLATION_BACKEND=plain  # One OS account per user (#3446)
#   - OPENACE_ALLOW_ROOT_MULTI_USER=1  # Explicit root authorization
#   - OPENACE_CONFIG_DIR=/home/open-ace/.open-ace  # Config persistence
#
# For multi-user deployment guide, see:
#   docs/guide/MULTI_USER_WORKSPACE.md
#
# ============================================================================

services:
  # ===========================================================================
  # Main Application
  # ===========================================================================
  open-ace:
    # One-click deploy: docker compose up -d --build
    # Pull pre-built image: docker compose up -d (without --build)
    build:
      context: .
      dockerfile: Dockerfile
      target: production
      args:
        # Base image registry. Override for networks where Docker Hub is
        # unreachable (e.g. mainland China): BASE_REGISTRY=docker.m.daocloud.io
        BASE_REGISTRY: ${BASE_REGISTRY:-docker.io}
    image: ${IMAGE_NAME:-ghcr.io/open-ace/open-ace:latest}
    container_name: open-ace
    restart: unless-stopped
    ports:
      - "${PORT:-19888}:19888"
      # Multi-user workspace: expose port range for qwen-code-webui instances
      - "${WORKSPACE_PORT_RANGE_START:-3100}-${WORKSPACE_PORT_RANGE_END:-3200}:${WORKSPACE_PORT_RANGE_START:-3100}-${WORKSPACE_PORT_RANGE_END:-3200}"
    environment:
      - PYTHONUNBUFFERED=1
      # Secrets: empty by default — docker-entrypoint.sh auto-generates strong
      # random values on first start if unset (see ensure_secret_env). For
      # production, set them explicitly in .env (see .env.example).
      - SECRET_KEY=${SECRET_KEY:-}
      - OPENACE_ENCRYPTION_KEY=${OPENACE_ENCRYPTION_KEY:-}
      - UPLOAD_AUTH_KEY=${UPLOAD_AUTH_KEY:-}
      # Security mode (Issue #2331): Explicit configuration required for production
      # For one-click local dev: defaults to development
      # For production: set explicitly in .env: OPENACE_SECURITY_MODE=production
      # Valid values: production (strict), pilot (trial), development (local dev)
      - OPENACE_SECURITY_MODE=${OPENACE_SECURITY_MODE:-development}
      # Database (Issue #1893): Development mode uses dev-password-change-in-production.
      # Production mode requires explicit strong password via DB_PASSWORD env var.
      - DATABASE_URL=postgresql://${DB_USER:-ace}:${DB_PASSWORD:-dev-password-change-in-production}@postgres:5432/${DB_NAME:-ace}
      # Issue #3095: Pass DB_PASSWORD as standalone env var for security baseline check.
      # The entrypoint check_security_baseline() reads DB_PASSWORD directly, not from DATABASE_URL.
      - DB_PASSWORD=${DB_PASSWORD:-}
      # Multi-user Workspace
      - WORKSPACE_ISOLATION_BACKEND=${WORKSPACE_ISOLATION_BACKEND:-shared}
      # Workspace base directory (users' projects stored under /workspace/<username>/)
      - WORKSPACE_BASE_DIR=/workspace
      # Data fetch: container runs as root, use venv Python (Issue #1121)
      - FETCH_USE_SUDO=false
      # Server IP for URL configuration (Issue #1306)
      # Auto-detected from hostname -I if not set
      # Override via .env file if needed (e.g., SERVER_IP=192.168.1.169)
      - SERVER_IP=${SERVER_IP:-}
      # Pass CI environment variable for entrypoint CI detection (Issue #3109)
      - CI=${CI:-}
      # #3237: must match the scheduler service exactly.
      - OPENACE_AGENT_STATE_ROOT=/var/lib/openace/agent-state
    # Allow container to access host network (Issue #1260)
    # Required for host.docker.internal on Linux Docker 20.10+
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      # Config: Use named volume for persistence (Issue #1260)
      # Entrypoint will auto-generate config.json if not exists.
      # Mount under the non-root open-ace user's home (/home/open-ace) so uid
      # 1000 (the image default, Dockerfile `USER 1000`) can write to it. The
      # directory is pre-created and chowned in the Dockerfile so Docker's named
      # volume init copies uid-1000 ownership into the volume on first run.
      # Users can mount custom config: - ./my-config.json:/home/open-ace/.open-ace/config.json:ro
      - config-data:/home/open-ace/.open-ace
      - ./logs:/app/logs
      # Workspace data: per-user project directories, persisted across restarts
      - workspace-data:/workspace
      # #3237: carried CLI transcripts. SHARED with the scheduler service on
      # purpose — the scheduler writes them, but the stop/delete/override
      # routes that purge them run here. Two separate volumes meant those
      # purges deleted an unrelated empty directory while the real transcripts
      # were retained forever.
      - agent-state:/var/lib/openace
      # SSH credentials for remote host access (optional, uncomment if needed)
      # SECURITY WARNING: Mounting SSH keys exposes private keys to container processes
      # Recommend using dedicated SSH keys with restricted commands in authorized_keys
      # - ~/.ssh:/root/.ssh:ro
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:19888/readyz')"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - open-ace-network
    depends_on:
      postgres:
        condition: service_healthy
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

# ===========================================================================
# Scheduler Worker (Issue #2187)
# ===========================================================================
# Independent scheduler process for background tasks.
# Uses leader election to ensure only one active scheduler.
# For single-instance development, omit this service.
  scheduler:
    image: ${IMAGE_NAME:-ghcr.io/open-ace/open-ace:latest}
    container_name: open-ace-scheduler
    restart: unless-stopped
    profiles:
      - scheduler
    environment:
      - FLASK_ENV=production
      - PYTHONUNBUFFERED=1
      - SCHEDULER_MODE=scheduler
      # Issue #3133: the entrypoint treats SCHEDULER_MODE=scheduler as a
      # production-capable path and requires an explicit OPENACE_SECURITY_MODE,
      # so starting the scheduler from this base file alone crashed on boot.
      # Default to development, matching the app service above; production
      # deployments must set OPENACE_SECURITY_MODE explicitly in .env (the
      # multi-user overlay already defaults it to production).
      - OPENACE_SECURITY_MODE=${OPENACE_SECURITY_MODE:-development}
      - SECRET_KEY=${SECRET_KEY:-}
      - OPENACE_ENCRYPTION_KEY=${OPENACE_ENCRYPTION_KEY:-}
      - UPLOAD_AUTH_KEY=${UPLOAD_AUTH_KEY:-}
      - DATABASE_URL=postgresql://${DB_USER:-ace}:${DB_PASSWORD:-dev-password-change-in-production}@postgres:5432/${DB_NAME:-ace}
      # Issue #3095: Pass DB_PASSWORD as standalone env var for security baseline check.
      - DB_PASSWORD=${DB_PASSWORD:-}
      - SCHEDULER_HEARTBEAT_INTERVAL=${SCHEDULER_HEARTBEAT_INTERVAL:-10}
      - SCHEDULER_HEARTBEAT_TIMEOUT=${SCHEDULER_HEARTBEAT_TIMEOUT:-60}
      - SCHEDULER_LOCK_TIMEOUT=${SCHEDULER_LOCK_TIMEOUT:-1800}
      - SCHEDULER_METRICS_PORT=9090
      # #3237: must match the app service exactly.
      - OPENACE_AGENT_STATE_ROOT=/var/lib/openace/agent-state
    volumes:
      - config-data:/home/open-ace/.open-ace
      - ./logs:/app/logs
      - workspace-data:/workspace
      # #3237: the same volume the app service mounts, at the same path.
      - agent-state:/var/lib/openace
    # Issue #3455: under compose this service runs the same web entrypoint as
    # the app service (SCHEDULER_MODE=scheduler starts the scheduler services
    # in-process); only the standalone app/scheduler_worker.py used by the k8s
    # deployment serves :9090/metrics. Probe /readyz on the port this
    # container actually serves, like the open-ace service above.
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:19888/readyz')"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    networks:
      - open-ace-network
    depends_on:
      postgres:
        condition: service_healthy
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

# ===========================================================================
# PostgreSQL Database (required for production)
# ===========================================================================
  postgres:
    # Same registry override as the app build (BASE_REGISTRY). When unset this
    # resolves to docker.io's postgres:15-alpine via the library/ auto-prefix.
    image: ${BASE_REGISTRY:-docker.io}/postgres:15-alpine
    container_name: open-ace-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_USER=${DB_USER:-ace}
      # Issue #1893: Development mode uses a fixed dev password for convenience.
      # Production mode requires explicit strong password via DB_PASSWORD env var.
      # The entrypoint will warn on dev password and reject in production mode.
      - POSTGRES_PASSWORD=${DB_PASSWORD:-dev-password-change-in-production}
      - POSTGRES_DB=${DB_NAME:-ace}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - open-ace-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-ace} -d ${DB_NAME:-ace}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

# =============================================================================
# Networks
# =============================================================================
networks:
  open-ace-network:
    driver: bridge

# =============================================================================
# Volumes
# =============================================================================
volumes:
  # #3237: carried CLI transcripts, shared by the app and scheduler services.
  agent-state:
    driver: local
  config-data:
    driver: local
  postgres-data:
    driver: local
  workspace-data:
    driver: local