f51e9f52a1
Optional integration of pi-coding-agent alongside opencode in the same
container. Both harnesses share the mempalace install and palace path —
wing/diary entries are mutually visible.
Build:
--build-arg INSTALL_PI=true # opt-in
--build-arg PI_VERSION=0.73.1 # pin a version (default: latest)
--build-arg INSTALL_OPENCODE=false # build pi-only image
Dockerfile:
• New INSTALL_PI block: npm install -g @mariozechner/pi-coding-agent
+ git-clones pi-toolkit and pi-extensions to /opt/.
• Existing opencode install gated behind new INSTALL_OPENCODE arg
(default true; existing builds unaffected).
• mkdir adds ~/.pi/agent/extensions for the named volume mount root.
• CMD changed from ['opencode'] to ['bash', '-l']. compose run --rm
devbox now drops to a login shell so users pick the harness; pass
'opencode' or 'pi' explicitly to launch directly. compose exec
workflows are unaffected (bypass entrypoint+CMD).
entrypoint.sh:
• Adds ~/.pi to volume ownership loop.
entrypoint-user.sh:
• New 'pi: deploy toolkit + extensions + mempalace bridge' block runs
pi-toolkit/install.sh, pi-extensions/install.sh, settings.json
template bootstrap, then symlinks the mempalace.ts bridge directly.
Order: toolkit before extensions before bridge. mempalace-toolkit's
full install.sh is intentionally NOT called (its install_skill
would race with skillset auto-deploy --prune-stale).
docker-compose.yml:
• New devbox-pi-config named volume mounted at /home/developer/.pi.
Persists user toggles (/ext-disabled extensions) and settings.json
edits across container recreate. Mirrors devbox-opencode-config
pattern from v1.14.33.
scripts/smoke-test.sh:
• New --variant with-pi (threshold 2700 MB) and --variant omos-with-pi
(3400 MB).
• Pi assertions gated on `command -v pi`: version, /opt/pi-toolkit
clone HEAD, /opt/pi-extensions clone HEAD, deployed keybindings
symlink, ≥4 extension symlinks, mempalace.ts bridge symlink,
settings.json bootstrap.
• Pi state assertions use docker exec from the host (not 'run'),
since the container has no docker CLI.
• opencode core test now gated on INSTALL_OPENCODE presence.
scripts/generate-dockerhub-md.py:
• SECTION_RULES adds 'pi (alternative/complementary harness)': drop.
Section stays in README; dropped from DOCKER_HUB.md to keep under
the 25 kB Docker Hub limit.
Docs:
• README adds full 'pi (alternative/complementary harness)' section.
• AGENTS.md codifies pi install contract, deploy ordering, named
volume rationale, and CMD change.
• CHANGELOG.md gets an Unreleased entry.
• .env.example documents new build args.
• docker-compose.yml example args block updated.
Verification (local builds on arm64):
• Default (INSTALL_PI=false): 1871 MB, all assertions pass — no
regression.
• INSTALL_PI=true: 2110 MB (within 2700 threshold), 37 assertions
pass including pi version, all 7 extensions deployed (6 from
pi-extensions + mempalace.ts bridge), settings.json bootstrap.
Not yet:
• CI workflow updates to add -with-pi tag variants. Deferred until
local path stabilizes through user testing.
• pi-devbox separate repo for fully stripped pi-only image. Phase 2.
140 lines
5.7 KiB
YAML
140 lines
5.7 KiB
YAML
# opencode-devbox docker-compose
|
|
#
|
|
# Usage:
|
|
# cp .env.example .env # configure your provider and keys
|
|
# docker compose up -d
|
|
# docker compose exec -u developer devbox opencode
|
|
#
|
|
# Or for interactive one-shot:
|
|
# docker compose run --rm devbox
|
|
|
|
# Pin the project name so named volumes survive directory renames.
|
|
# Without this, Docker Compose derives the project name from the
|
|
# directory basename — renaming the dir orphans all existing volumes.
|
|
name: opencode-devbox
|
|
|
|
services:
|
|
devbox:
|
|
image: joakimp/opencode-devbox:latest
|
|
# For multi-agent orchestration, use the omos variant instead:
|
|
# image: joakimp/opencode-devbox:latest-omos
|
|
#
|
|
# To build from source instead of pulling from Docker Hub, uncomment:
|
|
# build:
|
|
# context: .
|
|
# args:
|
|
# INSTALL_GO: "false"
|
|
# INSTALL_OMOS: "false"
|
|
# INSTALL_PI: "false"
|
|
# # PI_VERSION: "latest"
|
|
# # INSTALL_OPENCODE: "true"
|
|
container_name: opencode-devbox
|
|
stdin_open: true
|
|
tty: true
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
- TERM=xterm-256color
|
|
- GITHUB_PERSONAL_ACCESS_TOKEN=${GITHUB_PERSONAL_ACCESS_TOKEN:-}
|
|
- GITEA_ACCESS_TOKEN=${GITEA_ACCESS_TOKEN:-}
|
|
- GITEA_HOST=${GITEA_HOST:-}
|
|
volumes:
|
|
# Host workspace — mount your project here
|
|
- ${WORKSPACE_PATH:-.}:/workspace
|
|
|
|
# SSH keys (read-only) — for git push/pull
|
|
- ${SSH_KEY_PATH:-~/.ssh}:/home/developer/.ssh:ro
|
|
|
|
# Optional: mount skillset repo for automatic skill/instruction deployment.
|
|
# The entrypoint runs deploy-skills.sh --bootstrap on start, creating
|
|
# relative symlinks that resolve inside the container regardless of
|
|
# where the repo lives on the host. Set SKILLSET_PATH in .env.
|
|
# - ${SKILLSET_PATH}:/home/developer/skillset
|
|
|
|
# Persist opencode config (opencode.jsonc, oh-my-opencode-slim.json,
|
|
# instructions, etc.) across container recreations. Auto-generated on
|
|
# first start from env vars by generate-config.py and the skillset
|
|
# deploy script. Using a named volume (not a host bind mount) keeps
|
|
# the container's skill/instruction symlinks independent from the host,
|
|
# allowing both native and containerized opencode on the same machine.
|
|
- devbox-opencode-config:/home/developer/.config/opencode
|
|
- devbox-pi-config:/home/developer/.pi
|
|
|
|
# NOTE: Do NOT bind-mount ~/.agents/skills/ from the host. The
|
|
# container manages its own skills directory independently — the
|
|
# entrypoint deploys skills from the skillset repo on each start.
|
|
# Sharing it with the host causes symlink conflicts (relative paths
|
|
# differ between host and container filesystem namespaces).
|
|
|
|
# Optional: mount neovim config from host (plugins auto-install on first start)
|
|
# - ~/.config/nvim:/home/developer/.config/nvim:ro
|
|
|
|
# Optional: persist opencode data (auth, memory, etc.)
|
|
- devbox-data:/home/developer/.local/share/opencode
|
|
|
|
# Optional: persist opencode TUI settings (theme, toggles, etc.)
|
|
- devbox-state:/home/developer/.local/state/opencode
|
|
|
|
# Persist bash history across container recreations.
|
|
# Without this, ~/.bash_history is lost on 'docker compose up --force-recreate'.
|
|
- devbox-shell-history:/home/developer/.cache/bash
|
|
|
|
# Persist zoxide directory history ('z <fragment>' to jump).
|
|
- devbox-zoxide:/home/developer/.local/share/zoxide
|
|
|
|
# Optional: override baked shell defaults with your host's rc files.
|
|
# The image ships sensible defaults (history tuning, prefix-search on
|
|
# Up/Down arrows, fzf/zoxide integration). Uncomment to use your own:
|
|
#
|
|
# NOTE: Single-file bind-mounts break when editors use atomic save
|
|
# (vim, VS Code, sed -i write a temp file then rename() over the
|
|
# original, creating a new inode the container never sees). This is a
|
|
# kernel limitation, not Docker-specific. If host edits stop appearing
|
|
# in the container, mount the parent directory instead — see the
|
|
# "Shell defaults" section in README.md.
|
|
# - ~/.bash_aliases:/home/developer/.bash_aliases:ro
|
|
# - ~/.inputrc:/home/developer/.inputrc:ro
|
|
|
|
# Optional: persist uv data (Python installs, tool installs)
|
|
# Without this, 'uv python install' must be re-run after container removal.
|
|
- devbox-uv:/home/developer/.local/share/uv
|
|
|
|
# Optional: persist Rust toolchains and cargo data
|
|
# Without this, 'rustup-init' must be re-run after container removal.
|
|
# - devbox-rustup:/home/developer/.rustup
|
|
# - devbox-cargo:/home/developer/.cargo
|
|
|
|
# Optional: persist VS Code server and extensions across container recreations
|
|
# - devbox-vscode:/home/developer/.vscode-server
|
|
|
|
# Persist neovim plugin/Mason data (avoids re-downloading on every recreate)
|
|
- devbox-nvim-data:/home/developer/.local/share/nvim
|
|
|
|
# Optional: persist MemPalace data (conversation memory, knowledge graph,
|
|
# embeddings). Without this, palace data is lost on container recreation.
|
|
# - devbox-palace:/home/developer/.mempalace
|
|
|
|
# Optional: persist ChromaDB embedding model cache (~79 MB, downloaded on
|
|
# first mempalace search). Without this, the model re-downloads on every
|
|
# container recreation. Separate from palace data — model cache is
|
|
# disposable, palace data is precious.
|
|
# - devbox-chroma-cache:/home/developer/.cache/chroma
|
|
|
|
# Optional: AWS credentials/SSO config (not read-only — SSO writes token cache)
|
|
# - ~/.aws:/home/developer/.aws
|
|
|
|
volumes:
|
|
devbox-opencode-config:
|
|
devbox-pi-config:
|
|
devbox-data:
|
|
devbox-state:
|
|
devbox-shell-history:
|
|
devbox-zoxide:
|
|
devbox-nvim-data:
|
|
devbox-uv:
|
|
# devbox-palace:
|
|
# devbox-chroma-cache:
|
|
# devbox-rustup:
|
|
# devbox-cargo:
|
|
# devbox-vscode:
|