Skip to content

Agents > Self-hosting

Managed: Docker backend

Open in ChatGPT ↗
Ask ChatGPT about this page
Open in Claude ↗
Ask Claude about this page
Copied!

Run the Oz managed worker daemon with the Docker backend to execute cloud agent tasks in isolated containers on your infrastructure.

Run the oz-agent-worker daemon with the Docker backend — the default managed path. Each agent task runs in an isolated Docker container spawned from the worker, with full orchestration by Oz (Slack, Linear, schedules, API, oz agent run-cloud).

  • You want the simplest managed setup and have Docker available on the worker host.
  • You want per-task isolation without running a Kubernetes cluster.
  • You’re not already deploying workloads into Kubernetes.

  • Enterprise plan with self-hosting enabledContact sales if self-hosting is not yet enabled for your team.
  • A machine to run the worker — A VM, server, or local machine running Linux (recommended for production). For testing, macOS and Windows hosts running Docker Desktop work.
  • Docker installed — The worker uses Docker to spawn task containers. The Docker daemon must run Linux containers (Windows containers are not supported). Verify with docker info.
  • An agent API key — Create one in the Oz web app so the worker can authenticate to Oz. You can bind the key to any cloud agent — that choice doesn’t restrict which agents can run on the worker. See API Keys for the full creation flow.

If Docker is not already installed, follow the official Docker installation guide for your platform. Verify Docker is running:

Terminal window
docker info

Expected outcome: docker info prints daemon details without errors.


Export your agent API key so the worker can authenticate to Oz:

Terminal window
export WARP_API_KEY="your_agent_api_key"

The oz-agent-worker is open source. See the oz-agent-worker repository for source code, issues, and contribution guidelines.

There are three ways to install and run the worker with the Docker backend. Docker is recommended for production; go install and building from source are primarily useful for contributors and one-off testing.

The worker can be configured entirely via CLI flags, or via a YAML config file for more complex setups.

The worker needs access to the Docker daemon to spawn task containers. Mount the host’s Docker socket into the worker container:

Terminal window
docker run -v /var/run/docker.sock:/var/run/docker.sock \
-e WARP_API_KEY="$WARP_API_KEY" \
warpdotdev/oz-agent-worker --worker-id "my-worker"

Expected outcome: The worker connects to Oz and logs that it’s listening for tasks.

Terminal window
go install github.com/warpdotdev/oz-agent-worker@latest
oz-agent-worker --api-key "$WARP_API_KEY" --worker-id "my-worker"
Terminal window
git clone https://github.com/warpdotdev/oz-agent-worker.git
cd oz-agent-worker
go build -o oz-agent-worker
./oz-agent-worker --api-key "$WARP_API_KEY" --worker-id "my-worker"

Once started, the worker connects to Oz, waits for tasks routed to its --worker-id, runs each task in an isolated Docker container, and reports status and results back. The worker automatically reconnects if the connection drops.

You can run multiple workers with the same --worker-id for redundancy — Oz distributes tasks across connected workers.


The worker can take configuration either via CLI flags or via a YAML config file. CLI flags take precedence over config file values.

Common CLI flags:

Terminal window
docker run -v /var/run/docker.sock:/var/run/docker.sock \
-e WARP_API_KEY="$WARP_API_KEY" \
warpdotdev/oz-agent-worker \
--worker-id "prod-runner-1" \
--log-level debug \
--max-concurrent-tasks 4 \
--idle-on-complete 10m \
-v /opt/shared-cache:/cache:ro \
-e NPM_TOKEN=your_token \
-e GITHUB_TOKEN

Equivalent config file (config.yaml):

worker_id: "prod-runner-1"
log_level: "debug"
max_concurrent_tasks: 4
idle_on_complete: "10m"
backend:
docker:
volumes:
- "/opt/shared-cache:/cache:ro"
environment:
- name: NPM_TOKEN
value: "your_token"
- name: GITHUB_TOKEN # inherits from host environment

Pass it with --config-file config.yaml. See the self-hosted worker reference for the full flag and config schema.


The worker uses the standard Docker client discovery mechanism to find the Docker daemon:

  1. DOCKER_HOST environment variable (e.g., unix:///var/run/docker.sock, tcp://localhost:2375).
  2. Default socket (/var/run/docker.sock on Linux, ~/.docker/run/docker.sock for rootless Docker).
  3. Docker context via DOCKER_CONTEXT environment variable.
  4. Config file (~/.docker/config.json) for context settings.

Additional Docker environment variables the worker respects:

  • DOCKER_API_VERSION — Specify Docker API version.
  • DOCKER_CERT_PATH — Path to TLS certificates.
  • DOCKER_TLS_VERIFY — Enable TLS verification.

Example: Connecting to a remote Docker daemon

Terminal window
export DOCKER_HOST="tcp://remote-host:2376"
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH="/path/to/certs"
oz-agent-worker --api-key "$WARP_API_KEY" --worker-id "my-worker"

The worker automatically uses credentials from your Docker config (~/.docker/config.json) when pulling task images. If your environments use images from a private registry, authenticate the worker’s host first:

Terminal window
docker login your-registry.example.com

When running the worker via Docker, mount the Docker config into the container:

Terminal window
docker run \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.docker/config.json:/root/.docker/config.json:ro \
-e WARP_API_KEY="$WARP_API_KEY" \
warpdotdev/oz-agent-worker --worker-id "my-worker"

Once your Docker worker is connected, route tasks to it with --host "<your-worker-id>". Routing is the same across all managed backends — see Routing runs to self-hosted workers for CLI, scheduled, integration, API, and web UI examples.