Getting started
Install the requirements and start the dashboard.
Requirements
-
Linux or macOS
-
Docker (on macOS: Docker Desktop, OrbStack, Colima or similar), and the devcontainer CLI:
npm i -g @devcontainers/cli -
Node.js 22.13 or newer
-
opencode v2 installed in each project's devcontainer. Add project sets this up for you. Otherwise install it with
npm i -g @opencode/cli@2(for example inpostCreateCommand) or with the v2 installer:curl -fsSL https://opencode.ai/v2/install | bashopencode.ai/installinstalls v1. opendevhub looks for the binary onPATH, in~/.opencode/bin,~/.local/binand~/.bun/bin, and in thePATHthat bash or zsh set up from their startup files. -
LLM provider credentials available inside the container, via
containerEnv,remoteEnvor mounts. Git and ssh are set up for you: see Git and ssh.
Start the dashboard
npx opendevhub
npx opendevhub --port 8080 --no-openOn first start, open Settings → General and add the folders that hold your git repos (for example ~/code). They are saved in config.json and scanned on every start. The dashboard port is remembered too.
opendevhub prints the dashboard's link, http://localhost:7777/?token=…, and opens it. The token gives your browser access; other processes, agents in containers among them, can't use the dashboard without it. You need the link once per browser. Later, opendevhub open prints and opens it again. See Dashboard access and config approvals.
Containers keep running when opendevhub exits. The next time it starts, it reconnects to them.
How opendevhub reaches containers
On Linux with a native Docker engine, opendevhub connects to each container's IP directly.
When that IP is not reachable from the host (macOS, where containers live in a VM; rootless Docker; Docker Desktop on Linux), it starts one opendevhub-gateway container (node:22-alpine). The gateway publishes a single port on 127.0.0.1 and relays to the project containers, joining their Docker networks as needed. The project log says which route a project uses. The gateway is left running when opendevhub exits and is replaced when opendevhub needs a newer one.
Environment variables
| Variable | Effect |
|---|---|
OPENDEVHUB_ROUTE | auto (default) probes each container IP; direct or gateway forces a route. On macOS, auto only goes direct when something already answers on the container IP, so OrbStack users who want to skip the gateway can set direct. |
OPENDEVHUB_GATEWAY_IMAGE | Image for the gateway container (default node:22-alpine; it needs node on PATH). |
OPENDEVHUB_PUSH | Where Publish runs git: host or container. Default: the host when the checkout works there, else the container. |
OPENDEVHUB_RELATIVE_WORKTREES | Set to 0 to always create worktrees with absolute links. |
Sessions survive rebuilds
Every container opendevhub creates (the project's and each worktree's own) gets a Docker volume, opendevhub-opencode-<environment>, mounted at /opendevhub/opencode. Before it starts opencode serve, opendevhub links opencode's data folder (${XDG_DATA_HOME:-~/.local/share}/opencode: sessions, messages, provider logins) and state folder (${XDG_STATE_HOME:-~/.local/state}/opencode) to it, so Rebuild and a changed devcontainer config keep your conversations.
- A fresh volume belongs to root; opendevhub gives it to the container user once (
docker exec -u root … chown). - Data a container already has moves onto an empty volume. When the volume already holds data, it wins and the container's copy is kept next to it as
opencode.before-opendevhub.<time>. - If your devcontainer already mounts one of these folders (or a folder above it, like a home volume), opendevhub leaves it alone.
- Removing a worktree's own container removes its volume. The project's volume stays until you remove it:
docker volume rm opendevhub-opencode-<project id>(with the container stopped) starts opencode from scratch. - Containers created before this feature have no volume: their sessions are lost on the next rebuild, which adds it.