diff --git a/openhands/usage/agent-canvas/backend-setup/docker.mdx b/openhands/usage/agent-canvas/backend-setup/docker.mdx index 201241d0..9d1dd127 100644 --- a/openhands/usage/agent-canvas/backend-setup/docker.mdx +++ b/openhands/usage/agent-canvas/backend-setup/docker.mdx @@ -1,6 +1,155 @@ --- title: Setup a Docker Backend -description: Run an OpenHands agent server in Docker and connect Agent Canvas to it. +description: Build a custom OpenHands Agent Server image and connect Agent Canvas to it. --- -Coming soon. +This guide walks through building a **custom Agent Server image** that layers extra tooling (for example, the JDK) on top of the official base image, running it locally with Docker, and registering it as a backend in Agent Canvas. + +Use this approach when the default backend's toolchain is missing something your agent needs, such as a specific language runtime, build tool, or CLI. + +## Prerequisites + +- Docker installed and running +- An LLM API key (Anthropic, OpenAI, etc.) +- Agent Canvas installed and running locally — see [Setup](/openhands/usage/agent-canvas/setup) + +## 1. Build a Custom Image + +The OpenHands Agent Server publishes a base image at `ghcr.io/openhands/agent-server`. Extend it with a small `Dockerfile` that installs whatever your agent needs. + +The example below adds the JDK and a few common utilities. Save it as `Dockerfile`: + +```dockerfile icon="docker" +FROM ghcr.io/openhands/agent-server:1-python + +USER root + +# Install Java (JDK) and common build/diagnostic utilities. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + default-jdk \ + maven \ + unzip \ + vim \ + less \ + && rm -rf /var/lib/apt/lists/* + +# Switch back to the unprivileged user that the base image runs as. +USER openhands +``` + + + The base image already ships with Python, Node.js, `git`, `jq`, `tmux`, build tools, and a VS Code Web + VNC stack. Only add what you actually need on top. + + + + For fully reproducible builds, pin to a more specific tag like `1.24.0-python` instead of `1-python`. + + +Build the image with a tag you can reference later: + +```bash +docker build -t agent-server-java:latest . +``` + + + For ARM hosts (Apple Silicon, Graviton), prefer the matching base tag (for example `latest-python` already supports multi-arch). If you need to force a platform, pass `--platform linux/amd64` to `docker build`. + + +## 2. Run the Custom Image + +Start the image, expose the agent server's HTTP port, and protect it with a session API key. The agent server reads `SESSION_API_KEY` from the environment and requires the same value on the `X-Session-API-Key` header for every request. + +Use the same name for the container as you'll use for the Agent Canvas backend — it makes it easy to tell which container backs which backend later. + +```bash +# Pick any sufficiently random value; you'll paste it into Agent Canvas later. +export SESSION_API_KEY="$(openssl rand -hex 32)" + +docker run -d \ + --name agent-server-java \ + -p 8001:8000 \ + -e SESSION_API_KEY="$SESSION_API_KEY" \ + agent-server-java:latest +``` + +Verify the server is reachable: + +```bash +curl -H "X-Session-API-Key: $SESSION_API_KEY" http://localhost:8001/health +``` + + + The agent server can execute arbitrary shell commands inside the container. Treat `SESSION_API_KEY` like a production credential and **do not expose port 8001 to the public internet** without a TLS-terminating reverse proxy in front of it. + + +To follow logs or stop the container: + +```bash +docker logs -f agent-server-java +docker stop agent-server-java +``` + +## 3. Add the Backend in Agent Canvas + +With the container running, point Agent Canvas at it: + +1. Open Agent Canvas. +2. Click the backend switcher in the top bar and choose **Manage Backends**. +3. Click **Add Backend** and fill in: + - **Name** — `agent-server-java` (matching the container name) + - **Host / Base URL** — `http://localhost:8001` + - **API Key** — the `SESSION_API_KEY` value from step 2 + - **Type** — `Local` +4. Save the backend and select it as the **active backend**. + +Agent Canvas will run a health check against the URL. Once it passes, the backend is ready to handle conversations using the tools you baked into the image. + + + See [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) for what changes when you switch the active backend (settings, LLM availability, MCP servers, automations). + + +## Running Multiple Custom Backends + +You can build as many custom images as you need and run each one as its own backend in Agent Canvas. A common pattern is one image per language or repo toolchain — for example a `agent-server-java` for JVM work, a `agent-server-rust` for Cargo projects, and a `agent-server-data` image with the Python data stack pre-installed. + +Give each container its own name, its own host port, and its own `SESSION_API_KEY`, then add a matching backend entry in Agent Canvas for each one: + +```bash +# JVM toolchain on port 8001 +docker run -d --name agent-server-java \ + -p 8001:8000 -e SESSION_API_KEY="$JAVA_KEY" \ + agent-server-java:latest + +# Rust toolchain on port 8002 +docker run -d --name agent-server-rust \ + -p 8002:8000 -e SESSION_API_KEY="$RUST_KEY" \ + agent-server-rust:latest + +# Python data stack on port 8003 +docker run -d --name agent-server-data \ + -p 8003:8000 -e SESSION_API_KEY="$DATA_KEY" \ + agent-server-data:latest +``` + +In **Manage Backends**, add one entry per container using the matching name, URL, and API key. You can then switch between them from the backend selector depending on what kind of task you're working on. + +## Updating the Image + +When you want to add more tooling or pick up a newer agent server release: + +```bash +docker pull ghcr.io/openhands/agent-server:1-python +docker build -t agent-server-java:latest . +docker stop agent-server-java && docker rm agent-server-java +# then re-run the `docker run` from step 2 +``` + +The existing backend entry in Agent Canvas keeps working as long as the host, port, and `SESSION_API_KEY` stay the same. + +## Related Guides + +- [Connect and Manage Backends](/openhands/usage/agent-canvas/backends) +- [Setup a Local Backend](/openhands/usage/agent-canvas/backend-setup/local) +- [Setup a VM Backend](/openhands/usage/agent-canvas/backend-setup/vm) +- [Agent Server Overview](/sdk/guides/agent-server/overview)