Sign inSign up

netinventors/openrig

By netinventors

•Updated 4 days ago

Image
1

798

netinventors/openrig repository overview

⁠netinventors/openrig

Debian based image to run OpenRig⁠ and the AI coding agents it drives inside a container, so the agents can only touch the project directory that is mounted into it.

Note: This image is built to be started through a wrapper script and a Docker Compose setup, which mount the project and the state directories, keep the projects apart and load the environment. The wrapper script and the Compose setup are not published at the moment. The image works without them, but you have to set up the same mounts and options yourself (see Running without the wrapper⁠).

⁠Tags

netinventors/openrig:<openrig version>-node<node version>-<debian version>, e.g. netinventors/openrig:0.6.7-node24-trixie

Every build is also tagged latest. Images are rebuilt regularly, also without version bumps, to pick up Debian and Node.js security fixes.

⁠What is included

ToolCommandSource
Node.jsnode, npmofficial node:<version>-<debian>-slim image
OpenRigrig, openrig-tui@openrig/cli⁠
Claude Codeclaude@anthropic-ai/claude-code⁠
Codexcodex@openai/codex⁠
Pipi@earendil-works/pi-coding-agent⁠
Oh My Piomp (with bun)@oh-my-pi/pi-coding-agent⁠
Cursor CLIcursor-agent, agentcursor.com/cli⁠
Grok CLIgrok@xai-official/grok⁠
herdrherdrherdrdev/herdr⁠, the tiled view for rig terminal open

Plus tmux, git, ripgrep, jq, curl, less, unzip, openssh-client, procps and tini.

Why Debian and not Alpine: OpenRig needs the native better-sqlite3 module and Claude Code needs extra workarounds on musl. Both work out of the box on glibc.

Everything runs as the node user (uid/gid 1000). The tools are installed into /home/node/.npm-global, /home/node/.bun and /home/node/.local, not as root (except the static herdr binary in /usr/local/bin). Auto updates of Claude Code are disabled; updates come with a new image.

⁠Startup

Entrypoint: tini → /usr/local/bin/entrypoint.sh. Default command: tmux new-session -A -s rig. On every start the entrypoint

  • runs rig setup (idempotent, output in ~/.openrig/setup.log),
  • starts a headless herdr server for rig terminal open (log in ~/.openrig/herdr.log),
  • starts the OpenRig daemon in the background (bound to 0.0.0.0 when OPENRIG_AUTH_BEARER_TOKEN is set) and brings the kernel rig back, because its tmux sessions do not survive the container (log in ~/.openrig/start.log).

The daemon needs the tmux server of the default command. If you replace the command, start tmux yourself or skip the daemon with OPENRIG_SKIP_START=1.

⁠Environment variables

VariablePurpose
ANTHROPIC_API_KEY, OPENAI_API_KEYuse API keys instead of logging in
OPENRIG_AUTH_BEARER_TOKENbearer token for the daemon. Required to bind it to 0.0.0.0, which is needed to reach its UI/API from the host. Also handed to rig tui as OPENRIG_TERMINAL_BEARER_TOKEN
OPENRIG_SKIP_SETUP=1skip rig setup on start
OPENRIG_SKIP_HERDR=1do not start the headless herdr server
OPENRIG_SKIP_START=1do not start the daemon and the kernel

⁠Volumes

The image declares no volumes. The wrapper setup bind mounts these directories from the host. They must exist and be writable by uid 1000:

Container pathContentScope
the project's host paththe project the agents work onper project
/home/node/.openrigOpenRig: rigs, kernel, missions, tasks, logsper project
/home/node/.claudeClaude Code login, settings, history (CLAUDE_CONFIG_DIR)shared
/home/node/.codexCodex login and sessionsshared
/home/node/.pi, /home/node/.ompPi / Oh My Pishared
/home/node/.cursor, /home/node/.config/cursorCursor CLI and its loginshared
/home/node/.grokGrok CLIshared

Mount the project at the same path as on the host, not at a fixed path like /workspace. The agents key their conversation history and memory by the working directory, so with a fixed path every project would see the history, memory and tasks of the previous one. For the same reason use a separate /home/node/.openrig directory per project. The login directories can be shared.

Never mount your real ~/.claude, ~/.codex etc. from the host: the agents could write hooks that your host tools execute, and read your host credentials.

⁠Port

7433: OpenRig daemon UI/API. Publish it on the host's loopback only (127.0.0.1:7433:7433).

⁠Running without the wrapper

Roughly what the wrapper does, for a project in the current directory:

state=~/.local/share/openrig
project="$(basename "$PWD")-$(printf '%s' "$PWD" | sha256sum | cut -c1-8)"
mkdir -p "$state"/{claude,codex,pi,omp,cursor,cursor-config,grok} "$state/workspaces/$project/openrig"

docker run --rm -it \
  --hostname openrig \
  --cap-drop ALL \
  --security-opt no-new-privileges:true \
  -p 127.0.0.1:7433:7433 \
  -v "$PWD:$PWD" -w "$PWD" \
  -v "$state/workspaces/$project/openrig:/home/node/.openrig" \
  -v "$state/claude:/home/node/.claude" \
  -v "$state/codex:/home/node/.codex" \
  -v "$state/pi:/home/node/.pi" \
  -v "$state/omp:/home/node/.omp" \
  -v "$state/cursor:/home/node/.cursor" \
  -v "$state/cursor-config:/home/node/.config/cursor" \
  -v "$state/grok:/home/node/.grok" \
  -e OPENRIG_AUTH_BEARER_TOKEN="$(openssl rand -hex 32)" \
  netinventors/openrig:latest

On first start log in once inside the container; the logins are kept in the state directories:

claude               # or: claude auth login
codex login
cursor-agent login   # optional
grok login           # optional
rig setup            # should report no failures now
rig start            # later starts do this automatically

To see the kernel's seats as tiles, place them in herdr and attach a herdr client from a host terminal (not from inside the container's tmux, both use the ctrl+b prefix):

# inside the container
rig terminal open saved:kernel --provider herdr
# on the host
docker exec -it <container> herdr   # ctrl+b q detaches

--provider herdr is required: without it rig tries to open a desktop terminal window, which the container does not have, and fails with unauthorized.

⁠Containment

  • only the project directory is mounted from the host
  • the agents' configs and logins are separate from the host's own
  • run with --cap-drop ALL and no-new-privileges; non-root user
  • no Docker socket, so service backed rigs (e.g. secrets-manager) do not work. Never mount /var/run/docker.sock: it gives the agents root on the host
  • the network is not restricted

Tag summary

Content type

Image

Digest

sha256:727f676e0…

Size

1.1 GB

Last updated

4 days ago

docker pull netinventors/openrig