Skip to main content
The Docker sandbox runs the agent server inside a Docker container. This is the default and recommended option for most users.
In some self-hosted deployments, the sandbox provider is controlled via the legacy RUNTIME environment variable. Docker is the default.

Why Docker?

  • Isolation: reduces risk when the agent runs commands.
  • Reproducibility: consistent environment across machines.

Mounting your code into the sandbox

If you want OpenHands to work directly on a local repository, mount it into the sandbox. If you start OpenHands via:
your current directory will be mounted into the sandbox workspace.

Using SANDBOX_VOLUMES

You can also configure mounts via the SANDBOX_VOLUMES environment variable (format: host_path:container_path[:mode]):
Anything mounted read-write into /workspace can be modified by the agent.

Self-hosting Behind a Reverse Proxy

When you self-host OpenHands behind a reverse proxy (nginx, Traefik, etc.), each Docker sandbox exposes its agent-server (and VS Code / worker) ports on a randomly assigned host port. The frontend reaches the sandbox by plugging that random port into the container_url_pattern, which defaults to http://localhost:{port}. Two things break for a typical reverse-proxy setup:
  1. The hostname is localhost, not your public domain.
  2. The port is random, so you cannot add a static proxy route for it.
OH_WEB_URL does not control these sandbox URLs. On the OpenHands host it only adds the origin to the sandbox’s CORS allow-list — it is not forwarded into the sandbox container’s environment, so it has no effect on the host/port the browser uses to reach a sandbox.

Pin sandbox ports with host networking

Set AGENT_SERVER_USE_HOST_NETWORK=true to run agent-server containers in Docker host-network mode. Instead of random host ports, each container’s ports are reachable directly on fixed host ports:
This lets you add a single static reverse-proxy route for each fixed port.
Host-network mode binds every sandbox to the same fixed host ports. Only one sandbox can run at a time; concurrent conversations will collide on those ports. OpenHands logs a warning if host networking is enabled with max_num_sandboxes > 1.

Fix the sandbox URL hostname

To point sandbox URLs at your public domain (keeping the per-sandbox port), set the container_url_pattern to your hostname with the {port} placeholder:
This replaces localhost with your domain, but the port is still random per sandbox. Traefik cannot natively route an arbitrary dynamic port; a regex-based proxy (e.g. nginx) is needed to forward each port to the right sandbox.

Summary

Custom sandbox images

To customize the container image (extra tools, system deps, etc.), see Custom Sandbox Guide.