services: database: image: postgres:16-alpine container_name: unidesk-database restart: unless-stopped expose: - "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" - "logging_collector=on" - "-c" - "log_directory=/var/log/unidesk" - "-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 - ${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 backend-core: build: context: . dockerfile: src/components/backend-core/Dockerfile container_name: unidesk-backend-core restart: unless-stopped depends_on: - database 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}" 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}" MICROSERVICES_JSON: "${UNIDESK_MICROSERVICES_JSON:-[]}" LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_PREFIX}_backend-core.jsonl" 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 todo-note: build: context: /root/todo_note dockerfile: Dockerfile container_name: todo-note-backend 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}" TODO_NOTE_LOGS_DIR: "logs" LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_PREFIX}_todo-note.jsonl" TODO_NOTE_LOG_PATH: "/var/log/unidesk/${UNIDESK_LOG_PREFIX}_todo-note.jsonl" 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 codex-queue: build: context: . dockerfile: src/components/microservices/codex-queue/Dockerfile container_name: codex-queue-backend restart: unless-stopped depends_on: - backend-core expose: - "4222" environment: HOST: "0.0.0.0" PORT: "4222" CODEX_QUEUE_STATE_PATH: "/var/lib/unidesk/codex-queue/state.json" CODEX_QUEUE_WORKDIR: "/root/unidesk" CODEX_QUEUE_CODEX_HOME: "/var/lib/unidesk/codex-queue/codex-home" CODEX_QUEUE_SOURCE_CODEX_CONFIG: "/root/.codex/config.toml" CODEX_QUEUE_DEFAULT_MODEL: "gpt-5.4-mini" CODEX_QUEUE_MODELS: "gpt-5.4-mini,gpt-5.4,gpt-5.5" CODEX_QUEUE_SANDBOX: "danger-full-access" CODEX_QUEUE_APPROVAL_POLICY: "never" CODEX_QUEUE_MAX_ATTEMPTS: "3" OPENAI_API_KEY: "${OPENAI_API_KEY:-}" CRS_OAI_KEY: "${CRS_OAI_KEY:-}" MINIMAX_API_KEY: "${UNIDESK_CODEX_QUEUE_MINIMAX_API_KEY:-}" MINIMAX_API_BASE: "${UNIDESK_CODEX_QUEUE_MINIMAX_API_BASE:-https://api.minimaxi.com/v1}" MINIMAX_MODEL: "${UNIDESK_CODEX_QUEUE_MINIMAX_MODEL:-MiniMax-M2.7}" MINIMAX_JUDGE_TIMEOUT_MS: "${UNIDESK_CODEX_QUEUE_MINIMAX_JUDGE_TIMEOUT_MS:-60000}" MINIMAX_JUDGE_REPAIR_ATTEMPTS: "${UNIDESK_CODEX_QUEUE_MINIMAX_JUDGE_REPAIR_ATTEMPTS:-2}" LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_PREFIX}_codex-queue.jsonl" volumes: - /var/run/docker.sock:/var/run/docker.sock - .:/root/unidesk - .:/workspace - /root/.codex/config.toml:/root/.codex/config.toml:ro - ${UNIDESK_LOG_DIR}:/var/log/unidesk - ./.state/codex-queue:/var/lib/unidesk/codex-queue extra_hosts: - "host.docker.internal:host-gateway" healthcheck: test: ["CMD-SHELL", "curl -fsS --max-time 2 http://127.0.0.1:4222/health >/dev/null"] interval: 5s timeout: 3s retries: 20 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}" SESSION_SECRET: "${UNIDESK_SESSION_SECRET}" SESSION_TTL_SECONDS: "${UNIDESK_SESSION_TTL_SECONDS}" LOG_FILE: "/var/log/unidesk/${UNIDESK_LOG_PREFIX}_frontend.jsonl" 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 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_PREFIX}_provider-gateway.jsonl" 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" volumes: unidesk_pgdata_10gb: name: unidesk_pgdata_10gb