Openhands
OpenHands Agent Canvas: an AI software engineer in your browser
OpenHands on Cubeship
OpenHands is an open-source AI software engineer. Its web app, Agent Canvas, runs coding agents that read and write code, run commands and browse, and automations that run them on a schedule or from a webhook. It uses any model provider you give it a key for.
This template installs it on a Cubeship instance, with the web app on a domain and everything it keeps in two volumes.
What it creates
- openhands — Agent Canvas
1.18.0, built on the instance from theDockerfilein this repository: the web app, the agent server and the automation backend in one container, answering on the domain you choose. Settings, secrets, conversations and automations are kept in a volume at/home/openhands/.openhands, and the code the agent works on in one at/projects.
It needs Cubeship 0.7.0 or newer, and an admin to install it: the app is built on the instance, and only admins build.
Why it is built
The published image, ghcr.io/openhands/agent-canvas, writes its API key into
the page it serves, so the browser is signed in without asking. That is meant
for a machine only you can reach; on a domain it would sign in anyone who opens
it. The Dockerfile here is that image with one flag changed, the one
OpenHands' own --public mode changes: the page asks for the key instead. The
build fails rather than ship the old behaviour if a new image stops matching.
What you are asked
| Input | What to give |
|---|---|
| Where OpenHands answers | A domain you control, pointed at your instance. |
| The API key you sign in with | Nothing — the instance generates it and shows it once. Keep a copy. |
No model provider key is asked for. Add one in the app instead: it is stored, encrypted, in the volume.
After installing
- Open the domain. It sends you to
/canvas, which asks for the API key: paste the generated one. - Under Settings, choose a model provider and enter its key.
- Start a conversation. The agent works in
/projects; clone a repository there, or add a GitHub token under Settings and let it clone one.
It is on the internet
The API key is all that stands between the domain and an agent that runs any command in its container, with the model keys and tokens you gave it. OpenHands documents a firewall or an IP allow-list in front of it as well; Cubeship cannot restrict a domain by address, so keep the key long and to yourself.
The browser keeps the key in the page's storage. The built-in editor, at
/vscode on the same domain, can read that storage, which OpenHands tracks as
#16492.
To reach this instance from an Agent Canvas on your own machine, add it under Manage backends with the domain as its host and the API key.
What the agent can reach
The agent runs its commands inside the container, as the unprivileged
openhands user: the two volumes, the internet, and other apps on the instance
at their internal addresses. It has no Docker socket and no privileged mode, so
it cannot start containers, and OpenHands' Docker sandbox, which would give
each conversation a container of its own, does not work here.
The volumes
The app runs as one copy on the machine its volumes are on, and a deploy stops it for a few seconds, ending any conversation in progress. Back both up from the app's settings. The key that encrypts stored secrets is generated on first start and kept in the first volume, so a backup of it restores them.
Telemetry
Agent Canvas sends anonymous usage events to OpenHands unless told otherwise.
Set AGENT_CANVAS_DISABLE_TELEMETRY=1 on the app and redeploy to turn off the
web app's.
Updating
Change the tag in the Dockerfile, release this repository, and point ref at
the new release.
Resources
The app is limited to 2 CPUs and 4 GiB of memory. The agent builds and tests
code in the same container, so raise limits in template.yaml for large
projects.
What this creates
openhands
https://github.com/cubeshipd/cubeship-openhands-template
/home/openhands/.openhands
Volume of openhands
/projects
Volume of openhands
# yaml-language-server: $schema=https://cubeship.dev/schema/template/v1.json
version: 1
# The first release that gives a volume to the user its image runs as;
# OpenHands runs as openhands and cannot write to a volume owned by root.
minCubeship: "0.7.0"
project: openhands
inputs:
- key: domain
type: domain
label: Where OpenHands answers
- key: apiKey
type: secret
label: The API key you sign in with
generate: 48
apps:
- key: canvas
name: openhands
# The published image writes its API key into the page it serves, so
# anyone who opens the domain is signed in. The Dockerfile in this
# repository is that image asking for the key instead.
repo: https://github.com/cubeshipd/cubeship-openhands-template
ref: v1.0.0
build: dockerfile
port: 8000
# The agent server's own check, and the one route that asks for no key.
health: /health
domains:
- host: ${input.domain}
volumes:
- path: /home/openhands/.openhands
- path: /projects
limits: { cpu: 2, memory: 4Gi }
env:
LOCAL_BACKEND_API_KEY: ${input.apiKey}