Skip to main content
Use per-conversation Docker mode when you want Agent Canvas and the outer Agent Server to remain trusted host processes while each conversation runs in a separate, hardened Docker container. This mode differs from running the entire Agent Canvas distribution in Docker. Here, only conversations run in containers; Agent Canvas and the outer Agent Server stay on the host.

Prerequisites

  • Docker installed and running on the Agent Server host
  • Permission for the user running agent-canvas to invoke Docker
  • An Agent Server image compatible with the installed Agent Server version

Start Agent Canvas

Set the conversation runtime and image before starting Agent Canvas:
You can combine these variables with other launcher options. For example, to use another port:
The launcher forwards the variables to the local Agent Server. No separate frontend configuration is required.

Choose the Runtime per Conversation

By default the server runs every conversation the same way. To let each conversation choose between running on the host and running in its own container, set OH_CONVERSATION_RUNTIME_SELECTABLE=1:
The runtime selector on Home then offers Docker next to Local (and Worktree when a folder is open), and Settings → Runtime lets you pick the default runtime. Conversations that do not ask for a runtime use OH_CONVERSATION_RUNTIME.
As with OH_CONVERSATION_RUNTIME=docker, the launcher then listens on all network interfaces (0.0.0.0) so conversation containers can reach services on the host, and it no longer embeds the session API key in the page. Set OH_BIND_HOST to choose another address.
A start request can also set the container’s memory and CPU limits (container.memory and container.cpus); Settings → Runtime sends them when you set them there. Limits left unset use OH_CONVERSATION_CONTAINER_MEMORY and OH_CONVERSATION_CONTAINER_CPUS.
Client-supplied container.memory and container.cpus replace the server’s OH_CONVERSATION_CONTAINER_MEMORY and OH_CONVERSATION_CONTAINER_CPUS; they are not capped by them. Anyone who can start a conversation on the server can ask for a larger container. Do not rely on these variables as an upper bound on a server that other people can reach.

How Isolation Works

For each conversation, the outer Agent Server starts a dedicated Docker container running a full Agent Server. The container starts lazily when the conversation first needs it.
  • The inner server runs with OH_CONVERSATION_RUNTIME=local, so it runs the agent loop and its own tools inside the container.
  • Each container has its own generated OH_SECRET_KEY, its own session API key, and its own persistence.
  • The outer Agent Server proxies and mediates conversation requests to the container, and resolves agent and profile settings before forwarding them.
The container is hardened as follows:
  • Runs as the host user’s UID and GID rather than root.
  • Drops all Linux capabilities (--cap-drop ALL) and sets no-new-privileges.
  • Publishes its API only on 127.0.0.1, authenticated with the per-conversation session API key.
  • Maps host.docker.internal to the host gateway.
  • Is limited by the memory, CPU, and PID settings in the configuration reference.

Workspace and Persistence

Each container bind-mounts three host directories: Because these are bind mounts, workspace files and conversation history persist after the container is removed. Conversations that share a host workspace share the same files.
The /workspace mount gives tools in the container read and write access to that host directory. Point conversations at a dedicated workspace if you do not want the agent to modify existing project files.
Containers are stopped when a conversation has been idle for the idle timeout (OH_CONVERSATION_IDLE_TTL_SECONDS, 20 minutes by default). The conversation is not lost; its container is started again on next use. Stale containers from a previous Agent Server run are removed when the server starts.

Verify Isolation

Create a new conversation and ask the agent to run:
The command should report /workspace as PWD, and a HOME of /var/openhands/.openhands rather than your host home directory. On the host, inspect the active conversation container:
The mounts output should list three bind mounts, with destinations /var/openhands/conversations/<id>, /var/openhands/.openhands, and /workspace. To check the other settings:

Configuration Reference