> ## Documentation Index
> Fetch the complete documentation index at: https://allhandsai-jmj-model-router-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker Sandbox

> The recommended sandbox provider for running OpenHands locally.

The **Docker sandbox** runs the agent server inside a Docker container. This is
the default and recommended option for most users.

<Note>
  In some self-hosted deployments, the sandbox provider is controlled via the
  legacy <code>RUNTIME</code> environment variable. Docker is the default.
</Note>

## 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.

### Recommended: CLI launcher

If you start OpenHands via:

```bash theme={null}
openhands serve --mount-cwd
```

your current directory will be mounted into the sandbox workspace.

### Using SANDBOX\_VOLUMES

You can also configure mounts via the <code>SANDBOX\_VOLUMES</code> environment
variable (format: <code>host\_path:container\_path\[:mode]</code>):

```bash theme={null}
export SANDBOX_VOLUMES=$PWD:/workspace:rw
```

<Note>
  Anything mounted read-write into <code>/workspace</code> can be modified by the
  agent.
</Note>

## 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.

<Note>
  <code>OH\_WEB\_URL</code> 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.
</Note>

### 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:

| Container port | Service        |
| -------------- | -------------- |
| `8000`         | Agent server   |
| `8001`         | VS Code server |
| `8011`         | Worker 1       |
| `8012`         | Worker 2       |

```bash theme={null}
export AGENT_SERVER_USE_HOST_NETWORK=true
```

This lets you add a single static reverse-proxy route for each fixed port.

<Warning>
  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
  <code>max\_num\_sandboxes > 1</code>.
</Warning>

### 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:

```bash theme={null}
# OH_-prefixed form (recommended for V1):
export OH_SANDBOX_CONTAINER_URL_PATTERN="https://my-domain:{port}"
# Legacy form (also accepted):
export SANDBOX_CONTAINER_URL_PATTERN="https://my-domain:{port}"
```

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

| Goal                                        | Variable                                                             | Effect                                                                                              |
| ------------------------------------------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Fixed, static ports (one sandbox at a time) | `AGENT_SERVER_USE_HOST_NETWORK=true`                                 | Containers use host networking; ports `8000`/`8001`/`8011`/`8012` are exposed directly on the host. |
| Public hostname for sandbox URLs            | `OH_SANDBOX_CONTAINER_URL_PATTERN` / `SANDBOX_CONTAINER_URL_PATTERN` | Replaces `localhost` with your domain in the URLs the browser uses. Port stays random per sandbox.  |

## Custom sandbox images

To customize the container image (extra tools, system deps, etc.), see
[Custom Sandbox Guide](/openhands/usage/advanced/custom-sandbox-guide).
