Skip to content
badjwarePublic

About

a harness container

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

pibox

A containerized, sandboxed environment for running AI coding agents.

Pibox wraps a coding agent inside an Arch Linux-based Docker image so the agent executes against your working directory without having unrestricted access to your host system. The container mirrors your host user (UID/GID/name) so files created inside the container keep consistent ownership on the host.

Three harnesses are supported:

Harness Agent Image
pi (default) pi ghcr.io/badjware/pibox:pi
claude Claude Code ghcr.io/badjware/pibox:claude
pi-web PI WEB, a web UI for pi ghcr.io/badjware/pibox:pi-web

Features

  • Sandboxed execution: the agent runs inside a container with an ephemeral filesystem.
  • Host-user mirroring: files written from inside the container are owned by your host user.
  • Persistent config: ~/.pi is always bind-mounted, and ~/.claude is bind-mounted for the claude harness, so settings and sessions survive between runs.
  • Optional rootless Docker-in-Docker: opt in with --unsafe-enable-docker when the agent needs to run containers itself.
  • Pre-built images: distributed via GitHub Container Registry.

Requirements

  • Docker

YMMV on WSL.

Quick start

git clone https://github.com/badjware/pibox.git
cd pibox
./launch.sh

You can invoke launch.sh from any directory. The directory you run it from becomes the working directory bind-mounted into the container.

Set aliases in your shell for convenience:

alias pibox='/path/to/pibox/launch.sh'
alias claudebox='/path/to/pibox/launch.sh --harness claude'

Usage

./launch.sh [options] [-- <agent args>]

Flags

Flag Short Description
--help -h Show usage help and exit.
--harness pi|claude|pi-web -H Choose the agent to run. Defaults to pi.
--build Build the image locally from the Dockerfiles instead of using the published image.
--pull Update the image prior to launching.
--unsafe-enable-docker Start a rootless Docker daemon in DinD mode inside the container so the agent can run containers.
--unsafe-enable-aws Mount ~/.aws into the container.
--unsafe-enable-kube Mount ~/.kube into the container.
--unsafe-host-wayland Mount the Wayland socket into the container and forward Wayland environment variables.
--unsafe-host-tmux Mount the tmux socket into the container and forward the tmux environment variable.
--unsafe-host-net Share the host network namespace.
--ephemeral, --tmp -e Start in a temporary working directory instead of the current one.
--workdir <dir> -w Use <dir> as the working directory instead of the current one. Incompatible with --ephemeral.
--read-only, --ro -r Mount all volumes as read-only inside the container.
--volume <spec> -v Bind-mount an extra volume (repeatable, same syntax as docker run -v).
--extra-package <name> -P Install an extra pacman or AUR package at container startup. Repeatable and non-persistent.
--port <spec> -p Publish a container port. Repeatable, using Docker -p syntax such as 9119:9119. Replaces the default pi-web port mapping.

Any arguments after -- are passed through to the agent inside the container.

Examples

Launch pi (default):

./launch.sh

Launch Claude Code:

./launch.sh --harness claude

Launch PI WEB and open http://127.0.0.1:8504:

./launch.sh --harness pi-web

By default, pi-web is published on 127.0.0.1:8504 only. Any --port replaces that mapping. pi-web listens on port 8504 inside the container, so target it explicitly, for example --port 0.0.0.0:9000:8504. Set PIBOX_PI_WEB_PORT to change the default host port. With --unsafe-host-net, pi-web binds 127.0.0.1:${PIBOX_PI_WEB_PORT:-8504} directly on the host. PI WEB assumes trusted users; only expose it on a trusted network.

Pass arguments through to the agent (everything after -- is forwarded):

./launch.sh -- -p "summarize the README"

Install extra packages at startup (repo or AUR):

./launch.sh -P tree -P openscad-git

Packages known to pacman are installed from the official repositories. Anything else is treated as an AUR package: it is cloned, its dependencies are installed, and it is built from source at container startup. AUR builds are not recursive, so an AUR package whose own dependencies are AUR-only will fail to build. This covers packages whose dependencies all live in the official repositories.

Force-refresh the image from GHCR:

./launch.sh --pull

Forward Wayland for GUI apps:

./launch.sh --unsafe-host-wayland

Shell completion

A zsh completion is provided at completions/_pibox. To enable it, add the completions/ directory to your $fpath before compinit in ~/.zshrc:

fpath=(/path/to/pibox/completions $fpath)
autoload -U compinit && compinit

What's inside the image

The container ships with a set of tools suited to a coding agent:

  • git, vim (as $EDITOR), tmux
  • node, python (Python 3), go, gcc, make
  • fd, rg, jq, yq, bc, zip, unzip, diffutils, curl
  • docker + docker compose
  • kubectl, aws (aws-cli)
  • chromium, wl-clipboard, patchright (Playwright), trafilatura

Tools deliberately not installed: sudo, ssh, scp, wget.

Default bind mounts

These paths are always bind-mounted.

Host Container Mode
current working directory same absolute path rw
~/.pi ~/.pi rw
~/.pi/agent/extensions ~/.pi/agent/extensions ro
~/.claude (claude only) ~/.claude ro
~/.claude/project (claude only) ~/.claude/project rw
~/.claude.json (claude only) ~/.claude.json rw
~/.pi-web (pi-web only) ~/.pi-web rw
~/.config/pi-web (pi-web only) ~/.config/pi-web rw
~/.gitconfig ~/.gitconfig ro
pibox-cache volume ~/.cache rw
/etc/fonts /etc/fonts ro
/usr/share/fonts /usr/share/fonts ro
/var/cache/fontconfig /var/cache/fontconfig ro
host CA bundle /etc/ssl/host-ca-bundle.pem ro

About

a harness container

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages