# PilotDeck Docker PilotDeck runs as two cooperating Node.js processes in the container: - **Gateway**: agent runtime on `PILOTDECK_GATEWAY_PORT` (default `18789`) - **UI Server**: web frontend + REST/WebSocket adapter on `SERVER_PORT` (default `3001`) The Docker Compose setup persists the full `PILOT_HOME` directory, including generated config, auth DB, permissions, sessions/projects, memory, skills/plugins, and router stats. ## Quick Start with Docker Compose ### Prerequisites - [Docker](https://docs.docker.com/get-docker/) v20+ - [Docker Compose](https://docs.docker.com/compose/) v2+ ### Option A: Configure via environment variables Set the model provider variables in `docker-compose.yml` or an `.env` file: ```env PILOTDECK_MODEL=openai/gpt-4.1 PILOTDECK_API_KEY=sk-your-api-key PILOTDECK_API_URL=https://api.openai.com/v1 ``` Then start: ```bash docker compose up -d --build ``` If `/root/.pilotdeck/pilotdeck.yaml` does not exist in the `pilotdeck-home` volume, the entrypoint generates it from the `PILOTDECK_*` environment variables on first start. ### Option B: Configure via YAML file Create the host config file first: ```bash mkdir -p ~/.pilotdeck cat > ~/.pilotdeck/pilotdeck.yaml <<'YAML' schemaVersion: 1 agent: model: openai/gpt-4.1 model: providers: openai: protocol: openai url: https://api.openai.com/v1 apiKey: sk-your-api-key models: gpt-4.1: {} YAML ``` Then uncomment the config bind mount in `docker-compose.yml`: ```yaml volumes: - pilotdeck-home:/root/.pilotdeck - ${PILOTDECK_CONFIG:-${HOME}/.pilotdeck/pilotdeck.yaml}:/root/.pilotdeck/pilotdeck.yaml:ro ``` Start the service: ```bash docker compose up -d --build ``` The UI is available at **http://localhost:3001**. ## Workspace Mounts Agents run inside the container. To let them access a host project, mount it into `/workspace` by uncommenting the workspace bind mount: ```yaml volumes: - pilotdeck-home:/root/.pilotdeck - ${PILOTDECK_WORKSPACE:-${PWD}}:/workspace ``` You can set `PILOTDECK_WORKSPACE=/path/to/project` before running `docker compose up`. ## Manual Docker Build & Run ### Build the image ```bash docker build -t pilotdeck:latest . ``` ### Run with environment variables ```bash docker run -d --name pilotdeck \ -p 3001:3001 \ -v pilotdeck-home:/root/.pilotdeck \ -e PILOTDECK_MODEL=openai/gpt-4.1 \ -e PILOTDECK_API_KEY=sk-your-api-key \ -e PILOTDECK_API_URL=https://api.openai.com/v1 \ pilotdeck:latest ``` ### Run with a config file ```bash docker run -d --name pilotdeck \ -p 3001:3001 \ -v pilotdeck-home:/root/.pilotdeck \ -v ~/.pilotdeck/pilotdeck.yaml:/root/.pilotdeck/pilotdeck.yaml:ro \ pilotdeck:latest ``` ### Run with a workspace mount ```bash docker run -d --name pilotdeck \ -p 3001:3001 \ -v pilotdeck-home:/root/.pilotdeck \ -v "$PWD":/workspace \ -e PILOTDECK_MODEL=openai/gpt-4.1 \ -e PILOTDECK_API_KEY=sk-your-api-key \ -e PILOTDECK_API_URL=https://api.openai.com/v1 \ pilotdeck:latest ``` ### Run with a proxy ```bash docker run -d --name pilotdeck \ -p 3001:3001 \ -v pilotdeck-home:/root/.pilotdeck \ -e PILOTDECK_MODEL=openai/gpt-4.1 \ -e PILOTDECK_API_KEY=sk-your-api-key \ -e PILOTDECK_API_URL=https://api.openai.com/v1 \ -e PILOTDECK_PROXY=http://host.docker.internal:7890 \ pilotdeck:latest ``` ## Environment Variables | Variable | Description | Default | |---|---|---| | `PILOT_HOME` | PilotDeck state directory inside the container | `/root/.pilotdeck` | | `PILOTDECK_MODEL` | Main model identifier, formatted as `provider/model` | `openrouter/deepseek/deepseek-v4-flash` | | `PILOTDECK_LIGHT_MODEL` | Lightweight routing/judge model identifier | `openrouter/qwen/qwen3-8b` | | `PILOTDECK_API_KEY` | API key for the main model provider | `PLACEHOLDER_RUN_ONBOARDING_TO_REPLACE` | | `PILOTDECK_API_URL` | Base URL for the main model provider API | `https://openrouter.ai/api/v1` | | `PILOTDECK_LIGHT_API_KEY` | API key for a different light-model provider | Falls back to `PILOTDECK_API_KEY` | | `PILOTDECK_LIGHT_API_URL` | Base URL for a different light-model provider | Falls back to `PILOTDECK_API_URL` | | `PILOTDECK_PROXY` | HTTP/HTTPS proxy URL | — | | `SERVER_PORT` | UI server port | `3001` | | `PILOTDECK_GATEWAY_PORT` | Gateway port used by the UI bridge | `18789` | ## Architecture ```text Browser (localhost:3001) ──► UI Server (port 3001) ──► Gateway (port 18789) ``` Both processes are managed by `concurrently` inside the Docker container. ## Development ```bash npm install npm run dev ``` This starts the Gateway and UI dev server with hot reload.