x-unidesk-log-rotation: &unidesk-log-rotation
  driver: json-file
  options:
    max-size: "${UNIDESK_DOCKER_LOG_MAX_SIZE:-20m}"
    max-file: "${UNIDESK_DOCKER_LOG_MAX_FILE:-3}"

services:
  database:
    image: postgres:16-alpine
    container_name: unidesk-database
    restart: unless-stopped
    expose:
      - "5432"
    ports:
      - "${UNIDESK_DATABASE_BIND_HOST}:${UNIDESK_DATABASE_PORT}:5432"
    environment:
      POSTGRES_USER: "${UNIDESK_DATABASE_USER}"
      POSTGRES_PASSWORD: "${UNIDESK_DATABASE_PASSWORD}"
      POSTGRES_DB: "${UNIDESK_DATABASE_NAME}"
    command:
      - "postgres"
      - "-c"
      - "config_file=/etc/postgresql/postgresql.conf"
      - "-c"
      - "hba_file=/etc/postgresql/pg_hba.conf"
      - "-c"
      - "logging_collector=on"
      - "-c"
      - "log_directory=/var/log/unidesk/${UNIDESK_LOG_DAY}"
      - "-c"
      - "log_filename=${UNIDESK_LOG_PREFIX}_database.log"
      - "-c"
      - "log_connections=on"
      - "-c"
      - "log_disconnections=on"
    volumes:
      - unidesk_pgdata_10gb:/var/lib/postgresql/data
      - ./src/components/database/init:/docker-entrypoint-initdb.d:ro
      - ./src/components/database/config/postgresql.conf:/etc/postgresql/postgresql.conf:ro
      - ./src/components/database/config/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${UNIDESK_DATABASE_USER} -d ${UNIDESK_DATABASE_NAME}"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  backend-core:
    image: unidesk-backend-core
    build:
      context: .
      dockerfile: src/components/backend-core/Dockerfile
    container_name: unidesk-backend-core
    restart: unless-stopped
    depends_on:
      - database
      - code-queue-mgr
    ports:
      - "${UNIDESK_PROVIDER_INGRESS_PORT}:8081"
    expose:
      - "8080"
    environment:
      PORT: "8080"
      PROVIDER_PORT: "8081"
      DATABASE_URL: "postgres://${UNIDESK_DATABASE_USER}:${UNIDESK_DATABASE_PASSWORD}@database:5432/${UNIDESK_DATABASE_NAME}"
      PROVIDER_TOKEN: "${UNIDESK_PROVIDER_TOKEN}"
      DATABASE_POOL_MAX: "${UNIDESK_BACKEND_CORE_DATABASE_POOL_MAX:-4}"
      HEARTBEAT_TIMEOUT_MS: "${UNIDESK_HEARTBEAT_TIMEOUT_MS}"
      TASK_PENDING_TIMEOUT_MS: "${UNIDESK_TASK_PENDING_TIMEOUT_MS:-600000}"
      DATABASE_VOLUME_NAME: "${UNIDESK_DATABASE_VOLUME}"
      DATABASE_VOLUME_SIZE: "${UNIDESK_DATABASE_VOLUME_SIZE}"
      PGDATA_BACKUP_STAGING_DIR: "/data/baidu-netdisk-staging"
      BAIDU_NETDISK_INTERNAL_URL: "http://baidu-netdisk:4244"
      CODE_QUEUE_MGR_INTERNAL_URL: "http://code-queue-mgr:4278"
      MICROSERVICES_JSON: "${UNIDESK_MICROSERVICES_JSON:-[]}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_DEPLOY_REF:-deploy.json#environments.prod.services.backend-core}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_DEPLOY_SERVICE_ID:-backend-core}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_DEPLOY_REQUESTED_COMMIT:-}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_backend-core.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
      - ./.state/baidu-netdisk/staging:/data/baidu-netdisk-staging
    healthcheck:
      test:
        - "CMD-SHELL"
        - "if command -v backend-core >/dev/null 2>&1; then backend-core --fetch-json http://127.0.0.1:8080/health --require-ok; elif command -v bun >/dev/null 2>&1; then bun -e \"fetch('http://127.0.0.1:8080/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\"; else exit 1; fi"
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  code-queue-mgr:
    image: code-queue-mgr
    build:
      context: .
      dockerfile: src/components/microservices/code-queue-mgr/Dockerfile
    container_name: code-queue-mgr-backend
    restart: unless-stopped
    depends_on:
      - database
    expose:
      - "4278"
    environment:
      HOST: "0.0.0.0"
      PORT: "4278"
      DATABASE_URL: "postgres://${UNIDESK_DATABASE_USER}:${UNIDESK_DATABASE_PASSWORD}@database:5432/${UNIDESK_DATABASE_NAME}"
      CODE_QUEUE_TRACE_DATABASE_URL: "${UNIDESK_CODE_QUEUE_TRACE_DATABASE_URL}"
      CODE_QUEUE_MGR_DATABASE_POOL_MAX: "${UNIDESK_CODE_QUEUE_MGR_DATABASE_POOL_MAX:-2}"
      CODE_QUEUE_TRACE_DATABASE_POOL_MAX: "${UNIDESK_CODE_QUEUE_TRACE_DATABASE_POOL_MAX:-1}"
      CODE_QUEUE_MAIN_PROVIDER_ID: "${UNIDESK_CODE_QUEUE_MAIN_PROVIDER_ID:-D601}"
      CODE_QUEUE_WORKDIR: "/workspace"
      CODE_QUEUE_REMOTE_WORKDIR: "${UNIDESK_CODE_QUEUE_REMOTE_WORKDIR:-/home/ubuntu}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_code-queue-mgr.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
      UNIDESK_CODE_QUEUE_MGR_DEPLOY_REF: "${UNIDESK_CODE_QUEUE_MGR_DEPLOY_REF:-deploy.json#environments.prod.services.code-queue-mgr}"
      UNIDESK_CODE_QUEUE_MGR_DEPLOY_SERVICE_ID: "${UNIDESK_CODE_QUEUE_MGR_DEPLOY_SERVICE_ID:-code-queue-mgr}"
      UNIDESK_CODE_QUEUE_MGR_DEPLOY_REPO: "${UNIDESK_CODE_QUEUE_MGR_DEPLOY_REPO:-}"
      UNIDESK_CODE_QUEUE_MGR_DEPLOY_COMMIT: "${UNIDESK_CODE_QUEUE_MGR_DEPLOY_COMMIT:-}"
      UNIDESK_CODE_QUEUE_MGR_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_CODE_QUEUE_MGR_DEPLOY_REQUESTED_COMMIT:-}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD", "code-queue-mgr", "--healthcheck"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  code-agent-sandbox:
    image: code-agent-sandbox
    build:
      context: .
      dockerfile: src/components/microservices/code-agent-sandbox/Dockerfile
    container_name: code-agent-sandbox-backend
    restart: unless-stopped
    expose:
      - "4260"
    environment:
      HOST: "0.0.0.0"
      PORT: "4260"
      CODE_AGENT_SANDBOX_DATA_DIR: "/var/lib/unidesk/code-agent-sandbox"
      CODE_AGENT_SANDBOX_STATE_FILE: "/var/lib/unidesk/code-agent-sandbox/state.json"
      CODE_AGENT_SANDBOX_ADAPTER_SUMMARY_FILE: "/var/lib/unidesk/code-agent-sandbox/adapters.json"
      CODE_AGENT_SANDBOX_ENV_FILE_PATH: "/var/lib/unidesk/code-agent-sandbox/env.json"
      CODE_AGENT_SANDBOX_CONFIG_TOML_PATH: "/var/lib/unidesk/code-agent-sandbox/config.toml"
      CODE_AGENT_SANDBOX_AUTH_JSON_PATH: "/var/lib/unidesk/code-agent-sandbox/auth.json"
      CODE_AGENT_SANDBOX_MODE: "${CODE_AGENT_SANDBOX_MODE:-half-isolation}"
      CODE_AGENT_SANDBOX_TOKEN_PROVIDER: "${CODE_AGENT_SANDBOX_TOKEN_PROVIDER:-codex}"
      CODE_AGENT_SANDBOX_TOKEN_PROVIDER_SWITCH_ALLOWED: "${CODE_AGENT_SANDBOX_TOKEN_PROVIDER_SWITCH_ALLOWED:-true}"
      CODE_AGENT_SANDBOX_CONFIG_WRITABLE: "${CODE_AGENT_SANDBOX_CONFIG_WRITABLE:-true}"
      CODE_AGENT_SANDBOX_AUTH_WRITABLE: "${CODE_AGENT_SANDBOX_AUTH_WRITABLE:-true}"
      CODE_AGENT_SANDBOX_ENV_WRITABLE: "${CODE_AGENT_SANDBOX_ENV_WRITABLE:-true}"
      CODE_AGENT_SANDBOX_ADAPTERS: "${CODE_AGENT_SANDBOX_ADAPTERS:-codex,opencode,future-agent}"
      CODE_AGENT_SANDBOX_DEFAULT_ADAPTER: "${CODE_AGENT_SANDBOX_DEFAULT_ADAPTER:-codex}"
      CODE_AGENT_SANDBOX_MAX_PROMPT_CHARS: "${CODE_AGENT_SANDBOX_MAX_PROMPT_CHARS:-12000}"
      CODE_AGENT_SANDBOX_MAX_TRACE_ITEMS: "${CODE_AGENT_SANDBOX_MAX_TRACE_ITEMS:-200}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_CODE_AGENT_SANDBOX_DEPLOY_REF:-deploy.json#environments.prod.services.code-agent-sandbox}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_CODE_AGENT_SANDBOX_DEPLOY_SERVICE_ID:-code-agent-sandbox}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_CODE_AGENT_SANDBOX_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_CODE_AGENT_SANDBOX_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_CODE_AGENT_SANDBOX_DEPLOY_REQUESTED_COMMIT:-}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_code-agent-sandbox.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
      - ./.state/code-agent-sandbox:/var/lib/unidesk/code-agent-sandbox
    healthcheck:
      test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:4260/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  auth-broker:
    image: auth-broker
    profiles:
      - auth-broker
    build:
      context: .
      dockerfile: src/components/microservices/auth-broker/Dockerfile
    container_name: auth-broker-backend
    restart: "no"
    expose:
      - "4291"
    environment:
      HOST: "0.0.0.0"
      PORT: "4291"
      AUTH_BROKER_GITHUB_CONFIGURED: "${UNIDESK_AUTH_BROKER_GITHUB_CONFIGURED:-false}"
      AUTH_BROKER_GITHUB_CREDENTIAL_REF: "${UNIDESK_AUTH_BROKER_GITHUB_CREDENTIAL_REF:-github:unidesk-dev}"
      AUTH_BROKER_ALLOWED_REPOS: "${UNIDESK_AUTH_BROKER_ALLOWED_REPOS:-pikasTech/unidesk}"
      AUTH_BROKER_AUDIT_LOG: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_auth-broker.jsonl"
      UNIDESK_DEPLOY_REF: "${UNIDESK_AUTH_BROKER_DEPLOY_REF:-deploy.json#environments.prod.services.auth-broker}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_AUTH_BROKER_DEPLOY_SERVICE_ID:-auth-broker}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_AUTH_BROKER_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_AUTH_BROKER_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_AUTH_BROKER_DEPLOY_REQUESTED_COMMIT:-}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_auth-broker.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD", "auth-broker", "--healthcheck"]
      interval: 30s
      timeout: 3s
      retries: 1
    logging: *unidesk-log-rotation

  todo-note:
    image: todo-note
    build:
      context: /root/todo_note
      dockerfile: Dockerfile
    container_name: todo-note-backend
    labels:
      unidesk.ai/deploy-service-id: "${UNIDESK_TODO_NOTE_DEPLOY_SERVICE_ID:-todo-note}"
      unidesk.ai/deploy-ref: "${UNIDESK_TODO_NOTE_DEPLOY_REF:-deploy.json#environments.prod.services.todo-note}"
      unidesk.ai/deploy-repo: "${UNIDESK_TODO_NOTE_DEPLOY_REPO:-}"
      unidesk.ai/deploy-commit: "${UNIDESK_TODO_NOTE_DEPLOY_COMMIT:-}"
      unidesk.ai/deploy-requested-commit: "${UNIDESK_TODO_NOTE_DEPLOY_REQUESTED_COMMIT:-}"
    restart: unless-stopped
    depends_on:
      - database
    expose:
      - "4211"
    environment:
      HOST: "0.0.0.0"
      PORT: "4211"
      TODO_NOTE_BACKEND_ONLY: "1"
      DATABASE_URL: "postgres://${UNIDESK_DATABASE_USER}:${UNIDESK_DATABASE_PASSWORD}@database:5432/${UNIDESK_DATABASE_NAME}"
      PGAPPNAME: "unidesk-todo-note"
      TODO_NOTE_LOGS_DIR: "logs"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_todo-note.jsonl"
      TODO_NOTE_LOG_PATH: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_todo-note.jsonl"
      TODO_NOTE_REMINDER_CLAUDEQQ_ENABLED: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_ENABLED:-true}"
      TODO_NOTE_REMINDER_CLAUDEQQ_BASE_URL: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_BASE_URL:-http://backend-core:8080/api/microservices/claudeqq/proxy}"
      TODO_NOTE_REMINDER_CLAUDEQQ_TARGET_TYPE: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_TARGET_TYPE:-private}"
      TODO_NOTE_REMINDER_CLAUDEQQ_USER_ID: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_USER_ID:-645275593}"
      TODO_NOTE_REMINDER_CLAUDEQQ_GROUP_ID: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_GROUP_ID:-}"
      TODO_NOTE_REMINDER_LEAD_MINUTES: "${UNIDESK_TODO_NOTE_REMINDER_LEAD_MINUTES:-10}"
      TODO_NOTE_REMINDER_SCAN_INTERVAL_MS: "${UNIDESK_TODO_NOTE_REMINDER_SCAN_INTERVAL_MS:-30000}"
      TODO_NOTE_REMINDER_CLAUDEQQ_TIMEOUT_MS: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_TIMEOUT_MS:-15000}"
      TODO_NOTE_REMINDER_CLAUDEQQ_SEND_ATTEMPTS: "${UNIDESK_TODO_NOTE_REMINDER_CLAUDEQQ_SEND_ATTEMPTS:-3}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_TODO_NOTE_DEPLOY_REF:-deploy.json#environments.prod.services.todo-note}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_TODO_NOTE_DEPLOY_SERVICE_ID:-todo-note}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_TODO_NOTE_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_TODO_NOTE_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_TODO_NOTE_DEPLOY_REQUESTED_COMMIT:-}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:4211/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  oa-event-flow:
    image: oa-event-flow
    build:
      context: .
      dockerfile: src/components/microservices/oa-event-flow/Dockerfile
    container_name: oa-event-flow-backend
    restart: unless-stopped
    depends_on:
      - database
      - backend-core
    expose:
      - "4255"
    ports:
      - "${UNIDESK_OA_EVENT_FLOW_BIND_HOST}:${UNIDESK_OA_EVENT_FLOW_PORT}:4255"
    environment:
      HOST: "0.0.0.0"
      PORT: "4255"
      DATABASE_URL: "postgres://${UNIDESK_DATABASE_USER}:${UNIDESK_DATABASE_PASSWORD}@database:5432/${UNIDESK_DATABASE_NAME}"
      DATABASE_POOL_MAX: "${UNIDESK_OA_EVENT_FLOW_DATABASE_POOL_MAX:-2}"
      PIPELINE_OA_BRIDGE_BASE_URL: "http://backend-core:8080/api/microservices/pipeline/proxy"
      PIPELINE_OA_BRIDGE_INTERVAL_MS: "${UNIDESK_PIPELINE_OA_BRIDGE_INTERVAL_MS:-15000}"
      PIPELINE_OA_BRIDGE_RUN_LIMIT: "${UNIDESK_PIPELINE_OA_BRIDGE_RUN_LIMIT:-50}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_oa-event-flow.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_OA_EVENT_FLOW_DEPLOY_REF:-deploy.json#environments.prod.services.oa-event-flow}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_OA_EVENT_FLOW_DEPLOY_SERVICE_ID:-oa-event-flow}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_OA_EVENT_FLOW_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_OA_EVENT_FLOW_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_OA_EVENT_FLOW_DEPLOY_REQUESTED_COMMIT:-}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:4255/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  project-manager:
    image: project-manager
    build:
      context: .
      dockerfile: src/components/microservices/project-manager/Dockerfile
    container_name: project-manager-backend
    restart: unless-stopped
    depends_on:
      - database
    expose:
      - "4233"
    environment:
      HOST: "0.0.0.0"
      PORT: "4233"
      DATABASE_URL: "postgres://${UNIDESK_DATABASE_USER}:${UNIDESK_DATABASE_PASSWORD}@database:5432/${UNIDESK_DATABASE_NAME}"
      DATABASE_POOL_MAX: "${UNIDESK_PROJECT_MANAGER_DATABASE_POOL_MAX:-1}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_project-manager.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_PROJECT_MANAGER_DEPLOY_REF:-deploy.json#environments.prod.services.project-manager}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_PROJECT_MANAGER_DEPLOY_SERVICE_ID:-project-manager}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_PROJECT_MANAGER_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_PROJECT_MANAGER_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_PROJECT_MANAGER_DEPLOY_REQUESTED_COMMIT:-}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:4233/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  baidu-netdisk:
    image: baidu-netdisk
    build:
      context: .
      dockerfile: src/components/microservices/baidu-netdisk/Dockerfile
    container_name: baidu-netdisk-backend
    restart: unless-stopped
    depends_on:
      - database
    expose:
      - "4244"
    environment:
      HOST: "0.0.0.0"
      PORT: "4244"
      DATABASE_URL: "postgres://${UNIDESK_DATABASE_USER}:${UNIDESK_DATABASE_PASSWORD}@database:5432/${UNIDESK_DATABASE_NAME}"
      DATABASE_POOL_MAX: "${UNIDESK_BAIDU_NETDISK_DATABASE_POOL_MAX:-2}"
      BAIDU_NETDISK_CLIENT_ID: "${UNIDESK_BAIDU_NETDISK_CLIENT_ID:-}"
      BAIDU_NETDISK_CLIENT_SECRET: "${UNIDESK_BAIDU_NETDISK_CLIENT_SECRET:-}"
      BAIDU_NETDISK_TOKEN_KEY: "${UNIDESK_BAIDU_NETDISK_TOKEN_KEY:-}"
      BAIDU_NETDISK_APP_ROOT: "${UNIDESK_BAIDU_NETDISK_APP_ROOT:-/}"
      BAIDU_NETDISK_STAGING_DIR: "/data/staging"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_baidu-netdisk.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_BAIDU_NETDISK_DEPLOY_REF:-deploy.json#environments.prod.services.baidu-netdisk}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_BAIDU_NETDISK_DEPLOY_SERVICE_ID:-baidu-netdisk}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_BAIDU_NETDISK_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_BAIDU_NETDISK_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_BAIDU_NETDISK_DEPLOY_REQUESTED_COMMIT:-}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
      - ./.state/baidu-netdisk/staging:/data/staging
    healthcheck:
      test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:4244/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  frontend:
    build:
      context: .
      dockerfile: src/components/frontend/Dockerfile
    container_name: unidesk-frontend
    restart: unless-stopped
    depends_on:
      - backend-core
    ports:
      - "${UNIDESK_FRONTEND_PORT}:8080"
    environment:
      PORT: "8080"
      CORE_INTERNAL_URL: "http://backend-core:8080"
      FRONTEND_PUBLIC_URL: "http://${UNIDESK_PUBLIC_HOST}:${UNIDESK_FRONTEND_PORT}"
      PROVIDER_INGRESS_PUBLIC_URL: "ws://${UNIDESK_PUBLIC_HOST}:${UNIDESK_PROVIDER_INGRESS_PORT}/ws/provider"
      AUTH_USERNAME: "${UNIDESK_AUTH_USERNAME}"
      AUTH_PASSWORD: "${UNIDESK_AUTH_PASSWORD}"
      PROVIDER_TOKEN: "${UNIDESK_PROVIDER_TOKEN}"
      UNIDESK_SSH_CLIENT_TOKEN: "${UNIDESK_SSH_CLIENT_TOKEN:-}"
      UNIDESK_SSH_CLIENT_ROUTE_ALLOWLIST: "${UNIDESK_SSH_CLIENT_ROUTE_ALLOWLIST:-G14,G14:*,D601,D601:*}"
      SESSION_SECRET: "${UNIDESK_SESSION_SECRET}"
      SESSION_TTL_SECONDS: "${UNIDESK_SESSION_TTL_SECONDS}"
      UNIDESK_DEPLOY_REF: "${UNIDESK_FRONTEND_DEPLOY_REF:-deploy.json#environments.prod.services.frontend}"
      UNIDESK_DEPLOY_SERVICE_ID: "${UNIDESK_FRONTEND_DEPLOY_SERVICE_ID:-frontend}"
      UNIDESK_DEPLOY_REPO: "${UNIDESK_FRONTEND_DEPLOY_REPO:-}"
      UNIDESK_DEPLOY_COMMIT: "${UNIDESK_FRONTEND_DEPLOY_COMMIT:-}"
      UNIDESK_DEPLOY_REQUESTED_COMMIT: "${UNIDESK_FRONTEND_DEPLOY_REQUESTED_COMMIT:-}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_frontend.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
    volumes:
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    healthcheck:
      test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:8080/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 5s
      timeout: 3s
      retries: 20
    logging: *unidesk-log-rotation

  dev-frontend-proxy:
    build:
      context: .
      dockerfile: src/components/dev-frontend-proxy/Dockerfile
    container_name: unidesk-dev-frontend-proxy
    restart: unless-stopped
    depends_on:
      - backend-core
    ports:
      - "${UNIDESK_DEV_FRONTEND_PORT}:8080"
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/health"]
      interval: 10s
      timeout: 5s
      retries: 12
    logging: *unidesk-log-rotation

  provider-gateway:
    image: unidesk_provider-gateway
    build:
      context: .
      dockerfile: src/components/provider-gateway/Dockerfile
    container_name: unidesk-provider-gateway-main
    restart: always
    pid: "host"
    depends_on:
      - backend-core
    environment:
      PROVIDER_SERVER_URL: "ws://backend-core:8081/ws/provider"
      PROVIDER_TOKEN: "${UNIDESK_PROVIDER_TOKEN}"
      PROVIDER_ID: "${UNIDESK_PROVIDER_ID}"
      PROVIDER_NAME: "${UNIDESK_PROVIDER_NAME}"
      PROVIDER_LABELS_JSON: "${UNIDESK_PROVIDER_LABELS_JSON}"
      HEARTBEAT_INTERVAL_MS: "${UNIDESK_HEARTBEAT_INTERVAL_MS}"
      RECONNECT_BASE_MS: "${UNIDESK_RECONNECT_BASE_MS}"
      RECONNECT_MAX_MS: "${UNIDESK_RECONNECT_MAX_MS}"
      DOCKER_SOCKET_PATH: "/var/run/docker.sock"
      MONITOR_DISK_PATH: "${UNIDESK_MONITOR_DISK_PATH}"
      PROVIDER_UPGRADE_HOST_PROJECT_ROOT: "${UNIDESK_PROVIDER_UPGRADE_HOST_PROJECT_ROOT}"
      PROVIDER_UPGRADE_WORKSPACE_PATH: "${UNIDESK_PROVIDER_UPGRADE_WORKSPACE_PATH}"
      PROVIDER_UPGRADE_COMPOSE_FILE: "${UNIDESK_PROVIDER_UPGRADE_COMPOSE_FILE}"
      PROVIDER_UPGRADE_ENV_FILE: "${UNIDESK_PROVIDER_UPGRADE_ENV_FILE}"
      PROVIDER_UPGRADE_COMPOSE_PROJECT: "${UNIDESK_PROVIDER_UPGRADE_COMPOSE_PROJECT}"
      PROVIDER_UPGRADE_SERVICE: "${UNIDESK_PROVIDER_UPGRADE_SERVICE}"
      PROVIDER_UPGRADE_RUNNER_IMAGE: "${UNIDESK_PROVIDER_UPGRADE_RUNNER_IMAGE}"
      LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_DAY}/${UNIDESK_LOG_PREFIX}_provider-gateway.jsonl"
      UNIDESK_LOG_RETENTION_BYTES: "${UNIDESK_LOG_RETENTION_BYTES:-512MiB}"
      HOST_SSH_HOST: "${UNIDESK_HOST_SSH_HOST}"
      HOST_SSH_PORT: "${UNIDESK_HOST_SSH_PORT}"
      HOST_SSH_USER: "${UNIDESK_HOST_SSH_USER}"
      HOST_SSH_KEY: "/run/host-ssh/id_ed25519"
      HOST_REMOTE_CWD: "/root"
      HOST_LOGIN_SHELL: "/bin/bash"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ${UNIDESK_PROVIDER_UPGRADE_HOST_PROJECT_ROOT}:${UNIDESK_PROVIDER_UPGRADE_WORKSPACE_PATH}:ro
      - ${UNIDESK_HOST_SSH_KEY_DIR}:/run/host-ssh:ro
      - ${UNIDESK_LOG_DIR}:/var/log/unidesk
    extra_hosts:
      - "host.docker.internal:host-gateway"
    logging: *unidesk-log-rotation

volumes:
  unidesk_pgdata_10gb:
    name: unidesk_pgdata_10gb
