PilotDeck Docker
July 9, 2026 · View on GitHub
简体中文版本:README_DOCKER.zh.md
PilotDeck runs as two cooperating Node.js processes in the container:
- Gateway: agent runtime on
PILOTDECK_GATEWAY_PORT(default18789) - UI Server: web frontend + REST/WebSocket adapter on
SERVER_PORT(default3001)
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 v20+
- Docker Compose v2+
Make sure the Docker daemon is running before starting PilotDeck. On macOS/Windows, start Docker Desktop first and wait until the engine is ready:
docker info
The first build pulls base images such as node:22-bookworm and node:22-bookworm-slim from Docker Hub. If pulling images is slow or fails with context deadline exceeded, configure a Docker registry mirror or Docker Desktop proxy, then retry docker compose up -d --build. On Docker Desktop, registry mirrors can be configured in Settings → Docker Engine. On Linux, add mirrors to /etc/docker/daemon.json, then restart Docker.
The container installs dependencies with Node.js 22 and the committed pnpm-lock.yaml inside the image, so it does not use the host Node.js runtime or host CPU architecture for native Node modules. The legacy sqlite/sqlite3 packages are not required by PilotDeck and are not part of the source install path.
As a one-off workaround, you can pre-pull the required Node images from a reachable mirror and tag them with the names used by the Dockerfile:
docker pull mirror.gcr.io/library/node:22-bookworm
docker pull mirror.gcr.io/library/node:22-bookworm-slim
docker tag mirror.gcr.io/library/node:22-bookworm node:22-bookworm
docker tag mirror.gcr.io/library/node:22-bookworm-slim node:22-bookworm-slim
The Docker build also downloads Debian and npm packages inside the image, so slow package registries may still require a stable network proxy.
Option A: Configure via environment variables
Set the model provider variables in docker-compose.yml or an .env file:
PILOTDECK_MODEL=openai/gpt-4.1
PILOTDECK_API_KEY=sk-your-api-key
PILOTDECK_API_URL=https://api.openai.com/v1
Then start:
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:
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:
volumes:
- pilotdeck-home:/root/.pilotdeck
- ${PILOTDECK_CONFIG:-${HOME}/.pilotdeck/pilotdeck.yaml}:/root/.pilotdeck/pilotdeck.yaml:ro
Start the service:
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:
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
docker build -t pilotdeck:latest .
Run with environment variables
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
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
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
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
Browser (localhost:3001) ──► UI Server (port 3001) ──► Gateway (port 18789)
Both processes are managed by concurrently inside the Docker container.
Development
npm install
npm run dev
This starts the Gateway and UI dev server with hot reload.