services: ocg-manager: build: context: . args: NPM_REGISTRY: ${NPM_REGISTRY:-https://registry.npmjs.org} CARGO_REGISTRY: ${CARGO_REGISTRY:-sparse+https://index.crates.io/} image: ${OCG_IMAGE:-ghcr.io/klarkxy/opencode-go-mgr:latest} restart: unless-stopped environment: - OCG_ADMIN_USERNAME - OCG_ADMIN_PASSWORD - OCG_MANAGER_ENCRYPTION_KEY - OCG_CLIENT_ROOT_URL - HTTP_PROXY - HTTPS_PROXY - ALL_PROXY - NO_PROXY - OCG_BROWSER_WORKER_URL=${OCG_BROWSER_WORKER_URL:-http://browser:9080} - OCG_BROWSER_CONTROL_TOKEN_FILE=/run/ocg-browser/control-token - OCG_BROWSER_PROFILES_DIR=/browser-profiles # Docker CPA is always the optional sibling service, never an arbitrary # remote endpoint. The Dashboard treats this value as read-only. - OCG_CPA_BASE_URL=${OCG_CPA_BASE_URL:-http://cpa:8317} ports: - "127.0.0.1:${OCG_PORT:-9042}:9042" volumes: - ocg-data:/data - ocg-browser-profiles:/browser-profiles - ocg-browser-runtime:/run/ocg-browser:ro read_only: true tmpfs: - /tmp cap_drop: - ALL security_opt: - no-new-privileges:true networks: - default - browser-private - cpa-private # Optional local CPA sibling. Start it with: # Copy-Item cpa-config.example.yaml cpa-config.yaml # docker compose --profile cpa up -d # The inference listener stays private; only OAuth callback ports bind to # host loopback so CPA itself owns browser/device authorization. cpa: profiles: ["cpa"] image: eceasy/cli-proxy-api:v7.2.145 restart: unless-stopped environment: - MANAGEMENT_PASSWORD=${CPA_MANAGEMENT_PASSWORD:-} expose: - "8317" ports: - "127.0.0.1:1455:1455" - "127.0.0.1:54545:54545" - "127.0.0.1:51121:51121" volumes: - cpa-auth:/root/.cli-proxy-api - ./cpa-config.yaml:/CLIProxyAPI/config.yaml:ro networks: - cpa-private # Optional remote browser. Start the published images with: # docker compose --profile browser up -d # For a local source build, also set OCG_BROWSER_IMAGE=ocg-manager-browser:local # and include --build. Reserve at least 2 CPU, 2 GiB RAM, and 1 GiB shared memory. browser: profiles: ["browser"] build: context: . dockerfile: Dockerfile.browser args: CARGO_REGISTRY: ${CARGO_REGISTRY:-sparse+https://index.crates.io/} image: ${OCG_BROWSER_IMAGE:-ghcr.io/klarkxy/opencode-go-mgr-browser:latest} restart: unless-stopped environment: - OCG_BROWSER_CONTROL_ADDR=0.0.0.0:9080 - OCG_BROWSER_CONTROL_TOKEN_FILE=/run/ocg-browser/control-token - OCG_BROWSER_PROFILE_ROOT=/profiles - OCG_BROWSER_VNC_WS_URL=ws://browser:6080/websockify expose: - "9080" - "6080" volumes: - ocg-browser-profiles:/profiles - ocg-browser-runtime:/run/ocg-browser read_only: true tmpfs: - /tmp:rw,nosuid,nodev,size=256m,uid=10001,gid=10001,mode=1777 - /home/ocg:rw,nosuid,nodev,size=128m,uid=10001,gid=10001,mode=0700 shm_size: 1gb cap_drop: - ALL security_opt: - seccomp=unconfined stop_grace_period: 30s networks: - browser-private volumes: ocg-data: # Browser profiles contain long-lived cookies and are sensitive backup data. ocg-browser-profiles: ocg-browser-runtime: # CPA OAuth auth files. Back up separately; OCG never reads their contents. cpa-auth: networks: # Project-scoped bridge: browser control/VNC stay unpublished while Chromium # retains outbound HTTPS access for Google and OpenCode. browser-private: {} # Project-scoped bridge for Open Console Gateway and the optional CPA sibling. cpa-private: {}