Configuration¶
opencode-manager is configured by a single global file:
A working default is written on install, so ocm runs out of the box. This page
documents every option.
Full example¶
workspaceRoot: /home/user/.local/share/opencode-manager
runtime: docker
useLocalOpenCodeAuth: false
hostNetwork: false
runtimeArgs:
- --dns
- 1.1.1.1
logLevel: warning
baseImage:
name: docker.io/mroger78/ocm-base:latest
packages:
- htop
- unzip
commands:
- update-ca-certificates
moduleDirs:
- /home/user/.config/opencode-manager/modules
workspacePostCreateCommands:
- git clone git@github.com:me/project.git .
- npm install
workspacePreDeleteCommands:
- git push
Options¶
workspaceRoot¶
Directory under which every workspace is stored. Each workspace gets its own
subdirectory containing workspace.yaml and home/.
runtime¶
Container runtime. Must be either docker or podman. Set it to match what you
have installed.
useLocalOpenCodeAuth¶
When true, the host file ~/.local/share/opencode/auth.json is mounted
read-write into the same path in every workspace container, so workspaces
share your host OpenCode login. Default false keeps auth isolated from the host
— in keeping with the security principle.
hostNetwork¶
When true, each workspace container shares the host's network namespace
(docker/podman --network host) instead of getting an isolated one. Default
false.
Enable it when the agent (or its tools) needs to reach services listening on the
host's loopback — a local model server, a database, a dev server, etc. With an
isolated network those 127.0.0.1 services are unreachable from inside the
container.
Inside every container an OpenCode server runs on the loopback interface. With
isolated networking they could all share one port, but under host networking they
share the host's loopback, so a fixed port would collide. To avoid that, each
workspace is assigned a unique loopback port (range 4096–4999), recorded as
openCodePort in its workspace.yaml and reused across restarts. Existing
workspaces created before this option are assigned a port automatically on their
next start. The assignment happens regardless of hostNetwork, so toggling the
option never requires a migration.
Toggling hostNetwork (or otherwise changing a workspace's network namespace or
assigned port) takes effect the next time the workspace starts: the manager
recreates a container whose live network mode or OCM_OPENCODE_PORT no longer
matches, so it can never keep serving on the stale fallback port (4096) and
collide with another workspace under host networking. Recreation preserves the
workspace (the home is bind-mounted and modules reinstall idempotently).
Note: host networking is opt-in because it weakens isolation — the container can reach (and bind) anything on the host's network interfaces. It also has limited support on Docker Desktop (macOS/Windows); on Linux with docker/podman it works as expected.
runtimeArgs¶
Optional list of extra flags passed verbatim to the docker/podman create
command used to create each workspace container. They are inserted in the options
section, just before the image name, so they can extend (or override) anything the
manager sets itself. This is an escape hatch for runtime options the manager does
not model natively — no code change required. For example:
Each entry is one argument token, exactly as you would type it on the command
line: a flag and its value are separate list items (- --dns then
- 1.1.1.1), or combined with = in a single item (- --add-host=db:10.0.0.5).
The list is applied to every workspace; an empty entry is rejected.
Note: values are passed through untouched and are not validated by the manager — a flag your runtime rejects will surface as a container-create error.
logLevel¶
How much is written to the log file. One of debug, info, warning
(default), or error.
Logging¶
Logs are appended to a file, not printed to the terminal, so they never interfere with the TUI:
moduleDirs¶
List of directories scanned for modules. The built-in modules are installed into the first one on package install; add your own module directories here to extend the catalogue.
workspacePostCreateCommands¶
Optional list of shell commands run inside the workspace container the first
time the workspace is started, after its modules are installed. Each command runs
as the workspace user, in the project directory (/home/debian/workspace), with
the workspace's ~/.env sourced — so module-provided environment variables are
available, exactly as the agent sees them. They are a one-shot per workspace
setup hook: clone the project repo, install dependencies, prime a cache, etc.
A completion marker is stored in the workspace directory after the first run, so the commands never re-run on later starts (attach, shell, module edits…). A command that exits non-zero is logged and skipped — it never blocks the workspace from starting, and the workspace is still marked as set up.
workspacePreDeleteCommands¶
Optional list of shell commands run inside the workspace container just before
a workspace is deleted, while it still exists. Same execution environment as
workspacePostCreateCommands (workspace user, project directory, ~/.env
sourced). Use them for teardown — push pending commits, archive work, deregister
from a service:
If the container is stopped it is started first; if no container exists the hook is skipped. A failing command is logged and never blocks the deletion — a broken command can't make a workspace undeletable. As with all destructive actions, the deletion confirmation still applies; these commands run only once you confirm.
Base image¶
The baseImage block controls the container image workspaces are built from.
baseImage:
name: docker.io/mroger78/ocm-base:latest
packages:
- htop
- unzip
commands:
- update-ca-certificates
baseImage.name¶
The base image to use. Defaults to the published, prebuilt
docker.io/mroger78/ocm-base:latest, which already contains the full tooling
(npx, uvx, git, ripgrep, jq, opencode, tokscale, and the manager
scripts). With this default and no extras, ocm simply pulls that image
instead of building one, so the first start is fast.
baseImage.packages / baseImage.commands¶
Project-wide extras layered on top of the base.
- Adding
packagesorcommandsbuilds a thin local overlay on top of the prebuilt base — only the extras are applied. commandsrun during the image build immediately after the packages are installed (e.g.update-ca-certificates).
Pointing baseImage.name at a different distro instead (e.g.
debian:stable-slim) falls back to building the complete base recipe locally
from that image.
Always included¶
Generated workspace images always include npx, uvx, git, ripgrep, and
jq, regardless of configuration. Use packages/commands only for additional
tools.
How images are reused¶
A managed base image is tagged from a stable hash of the baseImage definition
and reused until that definition changes; changing any field produces a new
managed base image. The published image and the local-build fallback share the
same recipe (under internal/runtime/buildcontext/), so they never drift.
When the TUI starts it ensures the base image is available, showing
Creating the base image... while it is pulled or built.
Related¶
- Concepts → Shared OpenCode config — the read-only OpenCode templates shared into every workspace.
- Troubleshooting — when the base image won't build or the runtime can't be found.