joakimp 973c2efd5c Expand README + tweak DOCKER_HUB.md for users not cloning the repo
README rewrite:
- Two quick-start paths: 'no git clone' (curl docker-compose.yml +
  .env.example) and 'with git clone' for hackers/forkers
- New 'Authentication' section with subsections per provider
  (Anthropic, OpenAI, Gemini, AWS Bedrock static, AWS Bedrock SSO).
  AWS SSO path documents the ~/.aws bind-mount.
- Persistent state expanded: 5-row volume table + optional volumes
  table. Annotated what survives what.
- Configuration reference: full .env table.
- Versioning, building from source (with build args table),
  troubleshooting FAQ, related projects, license.
- 11 kB total — comprehensive but readable.

DOCKER_HUB.md tweaks:
- Quick-start now has a 'no git clone' path (curl two files), pointing
  users at the gitea README for the full setup guide. The git-clone
  path was overkill for the 90% case (just want to docker run).
- Explicit link to gitea README at the end of the quick-start block.
2026-05-15 17:58:06 +02:00
2026-05-14 19:57:17 +02:00
2026-05-14 19:57:17 +02:00
2026-05-14 19:57:17 +02:00
2026-05-14 19:57:17 +02:00

pi-devbox

A Docker container with pi coding-agent pre-installed, built on the opencode-devbox base image. Persistent state, full dev toolchain, MemPalace memory, and provider-agnostic LLM auth — in one docker compose run.

Hub: joakimp/pi-devbox · multi-arch (amd64 + arm64) Source: gitea.jordbo.se/joakimp/pi-devbox


What's inside

Inherited from opencode-devbox:base-latest:

  • Debian trixie (current stable)
  • Node.js (LTS), uv (Python), rustup (Rust on-demand)
  • AWS CLI v2 (with Bedrock support)
  • MemPalace + MCP server — persistent agent memory across sessions; queryable via mempalace_* tools inside pi
  • Gitea MCP server
  • Dev tools: neovim (LazyVim), tmux, bat, eza, fzf, zoxide, ripgrep, jq, git-lfs, make
  • Shell: bash with history tuning, prefix-search, fzf/zoxide integration

Added by pi-devbox:

  • pi (@earendil-works/pi-coding-agent) — baked at /usr/bin/pi, version pinned at build time
  • pi-toolkit — mosh/tmux-friendly keybindings (Shift+Enter, Ctrl+J, Alt+J newline), AWS env loader, settings template
  • pi-extensions — 7 extensions: ext-toggle, mcp-loader, todo, ssh-controlmaster, notify, git-checkpoint, confirm-destructive
  • mempalace bridge — auto-symlinked MCP extension so pi reads/writes the same palace as opencode

The entrypoint deploys all of these on first container start. Idempotent and preserves user edits.


Quick start (no git clone)

If you just want to run pi-devbox and don't plan to modify the source, grab the two template files and go:

mkdir -p ~/pi-devbox && cd ~/pi-devbox

# Pull the docker-compose.yml and .env template
curl -O https://gitea.jordbo.se/joakimp/pi-devbox/raw/branch/main/docker-compose.yml
curl -fsSL https://gitea.jordbo.se/joakimp/pi-devbox/raw/branch/main/.env.example -o .env

# Edit .env — at minimum set WORKSPACE_PATH, an LLM API key, and your git identity
$EDITOR .env

# Pull and run pi
docker compose run --rm devbox pi

docker compose run --rm devbox (no command) drops you into bash; you can then run pi, aws sso login, etc. manually.

To attach a second terminal to the same container (e.g. shell while pi is running):

docker compose exec -u developer devbox bash

Quick start (with git clone)

If you want to follow upstream changes, run a customized fork, or rebuild the image yourself:

git clone https://gitea.jordbo.se/joakimp/pi-devbox
cd pi-devbox
cp .env.example .env
$EDITOR .env
docker compose run --rm devbox pi

Authentication

pi reads provider credentials from environment variables, which the container picks up from .env automatically.

Anthropic (Claude)

ANTHROPIC_API_KEY=sk-ant-...

Generate a key at https://console.anthropic.com/settings/keys.

OpenAI

OPENAI_API_KEY=sk-...

Google Gemini

GEMINI_API_KEY=...

AWS Bedrock (e.g. Claude on Bedrock)

Two paths — pick one:

A) Static credentials (simplest, lower-trust environments only):

AWS_REGION=eu-west-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...

B) AWS SSO (recommended for corporate AWS, requires mounting ~/.aws):

AWS_REGION=eu-west-1
AWS_PROFILE=your-profile

Then in your docker-compose.yml, uncomment the ~/.aws bind-mount:

volumes:
  - ~/.aws:/home/developer/.aws

Inside the container, run aws sso login once per session. The token cache lives on the bind-mount, so subsequent pi invocations pick it up automatically. The pi-toolkit's pi-env.zsh (deployed to ~/.config/pi/) auto-sources AWS_PROFILE/AWS_REGION whenever a shell starts.

First-run pi configuration

On first start, pi reads ~/.pi/agent/settings.json (auto-bootstrapped from the pi-toolkit template). Edit it inside the container to pick a default provider/model:

docker compose exec -u developer devbox bash
$EDITOR ~/.pi/agent/settings.json

The file is rewritten by pi at runtime (e.g. lastChangelogVersion), so it lives on the devbox-pi-config named volume — your edits persist across container recreation.

For pi's full configuration model (provider list, model overrides, MCP integration, themes, extensions): https://github.com/earendil-works/pi#configuration.


Persistent state

Persistent state is what makes the difference between "use this once" and "make it my long-term coding environment". Everything important survives docker compose down and image upgrades; only docker compose down -v wipes the volumes.

Volume Mount point What survives Notes
devbox-pi-config /home/developer/.pi/ pi settings.json, extension toggles, sessions, user-installed pi packages NPM_CONFIG_PREFIX set inside the container so pi install npm:… and npm install -g lands here automatically
devbox-shell-history /home/developer/.cache/bash bash history Across container recreate
devbox-zoxide /home/developer/.local/share/zoxide zoxide directory jump history The z/zi shortcuts remember where you've been
devbox-nvim-data /home/developer/.local/share/nvim neovim plugin & Mason package state LazyVim plugins persist
devbox-uv /home/developer/.local/share/uv uv-managed Python installs and tool cache uv tool install results live here

Optional persistent volumes

These are commented out in docker-compose.yml by default. Uncomment them if you want the corresponding state to persist:

Volume Mount point What survives
devbox-palace /home/developer/.mempalace MemPalace data — drawers, knowledge graph, embeddings. Treat as primary storage if you rely on agent memory.
devbox-chroma-cache /home/developer/.cache/chroma ChromaDB embedding model cache (~80 MB; disposable, re-downloads in seconds)

Workspace bind mount

/workspace is bind-mounted from WORKSPACE_PATH on the host (default ~/projects). Source code never lives inside the container — your editor on the host and pi inside the container see the same files.

SSH keys (read-only)

~/.ssh is mounted read-only at /home/developer/.ssh for git push/pull. The container does not write to it.


Configuration reference

All config flows through .env. The full list (with annotations) is in .env.example. Here's the most relevant subset:

Variable Default Purpose
WORKSPACE_PATH ~/projects Host path mounted as /workspace
SSH_KEY_PATH ~/.ssh Host path for SSH keys (read-only)
GIT_USER_NAME (empty) Sets git config --global user.name inside container
GIT_USER_EMAIL (empty) Sets git config --global user.email inside container
ANTHROPIC_API_KEY (unset) Anthropic provider auth
OPENAI_API_KEY (unset) OpenAI provider auth
GEMINI_API_KEY (unset) Google Gemini auth
AWS_PROFILE / AWS_REGION (unset) AWS Bedrock SSO flow
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (unset) AWS Bedrock static creds
GITEA_ACCESS_TOKEN / GITEA_HOST (unset) Gitea MCP server (optional)
GITHUB_PERSONAL_ACCESS_TOKEN (unset) GitHub MCP server / git ops over HTTPS
LANG / LANGUAGE / LC_ALL en_US.UTF-8 Locale override

Versioning

Tags follow the pi npm package version: v0.74.0, v0.75.0, … latest always points at the most recent successful release.

Container-level rebuilds on the same pi version (security updates, base bumps, fixes) get a letter suffix: v0.74.0b, v0.74.0c, …

When the upstream pi npm package cuts a new version, this image is rebuilt and re-tagged to match.


Building from source

If you want to pin a specific pi version, change the base image, or hack on the Dockerfile:

git clone https://gitea.jordbo.se/joakimp/pi-devbox
cd pi-devbox

# Edit Dockerfile or override via build args:
docker compose build \
  --build-arg PI_VERSION=0.73.0 \
  --build-arg BASE_IMAGE=joakimp/opencode-devbox:base-latest

docker compose up -d

Build args supported:

Arg Default Effect
BASE_IMAGE joakimp/opencode-devbox:base-latest Parent image — set to joakimp/opencode-devbox:base-<sha> for reproducible builds
PI_VERSION latest npm version of @earendil-works/pi-coding-agent
PI_TOOLKIT_REF main Git ref for pi-toolkit
PI_EXTENSIONS_REF main Git ref for pi-extensions

Troubleshooting

pi --version works but pi exits immediately. First-run config probably hasn't been done. docker compose exec -u developer devbox bash, edit ~/.pi/agent/settings.json, ensure a provider is set and the matching API key is exported.

AWS SSO token expired. aws sso login from inside the container. The token cache is on the ~/.aws bind-mount, so it persists; expiration is the issue.

Anthropic 401 / OpenAI 401. Check the .env value made it in: docker compose exec devbox env | grep ANTHROPIC (etc).

pi prompts for an extension/MCP server you don't recognize. Either toggle it off via /ext inside pi, or rename the file: mv ~/.pi/agent/extensions/<name>.ts{,.off}.

Container won't start, error about /workspace. WORKSPACE_PATH in .env doesn't exist on the host. Create the directory or fix the path.

Pi-toolkit symlinks lost after docker compose down -v. That's expected — -v wipes named volumes. Don't do it unless you mean it. Container recreation without -v (the default) preserves all state.


  • opencode-devbox — the base image. Use this if you want both opencode and pi (it has a latest-with-pi variant) or just opencode.
  • pi-toolkit — keybindings, env loader, settings template. Cloned into /opt/pi-toolkit at image build time and install.sh runs on container start.
  • pi-extensions — extension source. Same install pattern.
  • mempalace-toolkit — MemPalace bring-up. The mempalace.ts extension symlinked into ~/.pi/agent/extensions/ comes from here.
  • pi (upstream) — the coding-agent itself.

License

MIT (this image and its source). Pi and the bundled tools each carry their own licenses.

S
Description
pi coding-agent container built on opencode-devbox base
Readme 248 KiB
Languages
Shell 76.3%
Dockerfile 23.7%