“There are many coding agent dockerizations, but this one is mine.”
Dockerfiles, launcher scripts, and a pre-populated ~/.pi configuration for running the Pi coding agent in Docker.
The repository is intentionally opinionated: it keeps Pi sessions and configuration outside your project checkout, mounts the detected project root into the container, and ships helper extensions, prompt templates, skills, and CLI tooling that are useful for day-to-day coding-agent work.
git clone https://github.com/stefan2904/dockerized-pi.git
cd dockerized-pi
# Optional: add provider tokens and bot identity
cp .env.template .env
$EDITOR .env
# Build the Docker image (defaults to the latest Pi release)
./build.sh
# Run Pi against the current directory/repository
./pi.shYou can also authenticate providers inside Pi with /login instead of putting API keys in .env.
- Docker
- Git
- A POSIX shell (the scripts are Bash/sh)
- Optional for
./pi.sh --update:curlandjqon the host
The image is built with the host UID/GID so files created by the agent remain owned by your local user.
./build.sh # build pi-coding-agent:latest
./build.sh 0.74.0 # build a specific @earendil-works/pi-coding-agent version
./build.sh --installed-versionThe default build uses Dockerfile.release and installs Pi from npm. Dockerfile.git is kept as an alternate source-build Dockerfile for development/testing.
The release image includes:
- Node.js on Debian Trixie slim
- zsh with grml defaults
- git, GitHub CLI (
gh), GitLab CLI (glab), Sentry CLI - curl, wget, jq, ripgrep, tree, file
- sudo/gosu with a configurable
piuser password - tmux and QEMU utilities used by Pi features
- Python via
uvplusautopep8,pytest, andmitmproxy - Networking/debugging CLIs:
xh,grpcurl,websocat
Use ./pi.sh [options] [pi arguments...] from any directory. The launcher discovers the project root by walking up from $PWD until it finds .git, .project, or .projectile, then mounts that root at /workspace.
./pi.sh # interactive Pi in the current project
./pi.sh --continue # continue the latest session
./pi.sh --ro # read-only workspace mount
./pi.sh -p "summarize this repo" # pass normal Pi CLI args through
./pi.sh --commit # run the /commit prompt template
./pi.sh --sessions # list saved sessions
./pi.sh --entrypoint entrypoint-zsh.sh # run with an alternate container entrypoint
./pi.sh --update # update Pi and configured packagesLauncher options:
| Option | Description |
|---|---|
--install | Install/update shell aliases: pi, pic, picommit. |
--update | Build the latest Pi release and run pi update. |
--sessions | Show recent session files under pi/agent/sessions. |
--ro, --readonly | Mount the workspace read-only and expose only read/search/list tools. |
--commit | Invoke the checked-in /commit prompt, optionally using PI_FAST_PROVIDER=/=PI_FAST_MODEL. |
--entrypoint PATH, --entrypoint=PATH | Bind-mount an alternate container entrypoint. Relative paths and @PATH are resolved from this repository. |
If a project contains a .pi_ro file, the launcher forces read-only mode for that project.
Pi package-management commands (install, remove, update, list, config) are passed through without adding tool/session arguments.
./pi.sh --installThis writes aliases to the first existing file among ~/.zshrc.local, ~/.zshrc, and ~/.bashrc:
pi→ run the agent in the current directorypic→ continue the last session (pi --continue)picommit→ runpi --commit
Copy .env.template to .env and set only what you need. The file is passed to Docker with --env-file and is ignored by git.
| Variable | Purpose |
|---|---|
BOT_GH_TOKEN | GitHub token used to authenticate gh inside the container. |
BOT_GIT_NAME | Git author name configured inside the container. |
BOT_GIT_EMAIL | Git author email configured inside the container. |
BOT_SENTRY_TOKEN | Sentry CLI auth token. |
PI_FAST_PROVIDER | Provider used by ./pi.sh --commit when PI_FAST_MODEL is set. |
PI_FAST_MODEL | Model used by ./pi.sh --commit. |
PI_SUDO_PASSWORD | Password for sudo as the pi user. If empty, a random password is printed at startup. |
PI_CACHE_RETENTION | Pi prompt-cache retention setting, for example 7d. |
ANTHROPIC_API_KEY | Anthropic API key. |
OPENAI_API_KEY | OpenAI API key. |
GEMINI_API_KEY | Google Gemini API key. |
MISTRAL_API_KEY | Mistral API key. |
HF_TOKEN | Hugging Face token. |
OPENROUTER_API_KEY | OpenRouter API key. |
Additional provider-specific variables can be added to .env as needed. For example, the bundled Kilo Code provider extension expects KILO_API_KEY if you use kilo-code models.
.
├── build.sh # docker build helper
├── pi.sh # launcher/alias installer/update helper
├── Dockerfile.release # npm-release based image
├── Dockerfile.git # source-build image variant
├── entrypoint.sh # container setup, auth, sudo, then exec pi
├── .env.template # optional host/container environment
├── examples.org # example projects created with this setup
└── pi/ # mounted as /home/pi/.pi in the container
└── agent/
├── settings.json # Pi settings and packages
├── models.json # local/custom providers (Ollama, LM Studio, ...)
├── modes.json # named model/provider modes
├── extensions/ # custom commands/tools/providers
├── prompts/ # prompt templates such as /commit
└── skills/ # bundled skills
Runtime state is stored below pi/agent and ignored where appropriate:
pi/agent/auth.jsonfor OAuth/provider loginspi/agent/sessions/for session historypi/agent/git/for installed git packages.cache/checkoutsand.cache/gondolinfor reusable caches
Do not commit secrets or generated runtime state.
/commit— stage and commit changes with a conventional commit message.
/files-changed— list files read/written/edited in the active session branch and open selections in VS Code./quota— consolidated quota view for logged-in providers such as GitHub Copilot, Google Antigravity/Gemini CLI, and OpenAI Codex.- Legacy per-provider quota extensions are included for Antigravity and GitHub Copilot, but are disabled in favor of
/quotaby the current settings. /kilo-refresh-models— refresh the Kilo Code model catalog./kilo-list-free-models— list currently free Kilo Code models.- Project status footer — shows host project root, host name, and read-only mode state.
get_files_changed— report files touched in the active session branch.get_gemini_cli_quota— fetch Gemini CLI quota/model availability.get_openai_codex_quota— probe OpenAI Codex quota headers and plan details.- Legacy disabled quota extensions also provide
get_antigravity_quotaandget_copilot_quotaif re-enabled.
pi/agent/models.jsondefines local OpenAI-compatible providers for Ollama and LM Studio athost.docker.internal.- The Kilo Code extension dynamically registers the
kilo-codeprovider from Kilo’s gateway. pi/agent/modes.jsoncontains named model modes for quick switching.
git-autopep8— format only changed Python lines withautopep8.
The container starts as root, configures the pi user, then drops privileges with gosu. If PI_SUDO_PASSWORD is unset, a random password is generated and printed:
========================================== sudo password for pi: a1b2c3d4e5f67890 ==========================================
Set PI_SUDO_PASSWORD in .env for a stable password.
- The launcher mounts the detected project root as
/workspaceand starts Pi in the matching relative subdirectory. - Read-only mode changes both the Docker mount and the active tool list.
- Provider logins performed with
/loginpersist inpi/agent/auth.jsonon the host and are ignored by git. - Local Ollama/LM Studio endpoints are addressed from inside Docker via
host.docker.internal.