Opinionated, containerized AI coding harness environments for Fedora.
This project is my personal take on running AI coding harnesses inside a container. One repo produces five images and five launchers, sharing the same base environment:
| Launcher | Harness | Image |
|---|---|---|
ccbox |
Claude Code | quay.io/guimou/ccbox |
ocbox |
OpenCode | quay.io/guimou/ocbox |
qcbox |
Qwen Code | quay.io/guimou/qcbox |
cxbox |
Codex CLI | quay.io/guimou/cxbox |
ompbox |
Oh My Pi | quay.io/guimou/ompbox |
All five provide:
- Isolation - Only the current project directory is mounted; each project gets its own history and session data
- Multi-session - Run multiple sessions simultaneously in the same project
- Consistency - Same Fedora-based environment everywhere, with common dev tools pre-installed
- Multi-platform - Supports both x86_64/amd64 and ARM64 (Apple Silicon)
- Rootless Podman - Runs without root privileges using user namespaces
- SELinux support - Works out of the box on Fedora with proper volume labeling
- Optional firewall - Restrict outbound network to an allowlist (Linux only)
- Podman installed and configured for rootless operation
- Fedora Linux (or compatible distribution) or macOS with Podman Desktop
Download the shared engine (box-common.sh) plus the launcher(s) you want into the same folder:
mkdir -p ~/.local/bin
curl -fsSL https://raw.githubusercontent.com/guimou/ccbox/main/lib/box-common.sh -o ~/.local/bin/box-common.sh
curl -fsSL https://raw.githubusercontent.com/guimou/ccbox/main/ccbox -o ~/.local/bin/ccbox
chmod +x ~/.local/bin/ccbox
# Repeat the last two lines for ocbox / qcbox / cxbox if desired
curl -fsSL https://raw.githubusercontent.com/guimou/ccbox/main/ocbox -o ~/.local/bin/ocbox
chmod +x ~/.local/bin/ocbox
# and
curl -fsSL https://raw.githubusercontent.com/guimou/ccbox/main/qcbox -o ~/.local/bin/qcbox
chmod +x ~/.local/bin/qcbox
# and
curl -fsSL https://raw.githubusercontent.com/guimou/ccbox/main/cxbox -o ~/.local/bin/cxbox
chmod +x ~/.local/bin/cxbox
# and
curl -fsSL https://raw.githubusercontent.com/guimou/ccbox/main/ompbox -o ~/.local/bin/ompbox
chmod +x ~/.local/bin/ompboxWith this install the image tag defaults to latest; use --claude-version (or --opencode-version / --qwen-version / --codex-version / --omp-version) to pin one.
Cloning gives you the version pin files and lets you build images locally (--build). Symlink the launchers you use (symlinks are resolved back to the repo):
git clone https://github.com/guimou/ccbox.git
ln -sf "$(pwd)/ccbox/ccbox" ~/.local/bin/ccbox
ln -sf "$(pwd)/ccbox/ocbox" ~/.local/bin/ocbox
ln -sf "$(pwd)/ccbox/qcbox" ~/.local/bin/qcbox
ln -sf "$(pwd)/ccbox/cxbox" ~/.local/bin/cxbox
ln -sf "$(pwd)/ccbox/ompbox" ~/.local/bin/ompboxEither way, make sure ~/.local/bin is in your PATH. Run ccbox --install for OS and shell-specific instructions.
cd your-project
ccbox # Run Claude Code in the current directory
ocbox # Run OpenCode
qcbox # Run Qwen Code
cxbox # Run Codex CLI
ompbox # Run Oh My PiThe container image is pulled automatically on first run. A few common flags:
ccbox --with-firewall # Restrict outbound network (Linux only)
ccbox --build # Build the image locally (development, Apple Silicon)
ccbox --build-base # Also rebuild the shared base image locally
ccbox --local # Use the locally-built image
ccbox -- --version # Pass arguments to the harness CLI
ccbox --help # All optionsAPI keys and provider settings are forwarded from host environment variables (e.g. ANTHROPIC_API_KEY, Vertex AI, Bedrock) — see the usage guide for exactly what is passed per launcher.
Breaking change: host credential store files are no longer mounted by default. Pass:
--with-gcloudto mount~/.config/gcloud(e.g. for Vertex AI),--with-gitconfigto mount~/.gitconfig,--with-credentialsto mount the harness credential store file —~/.claude/.credentials.json(ccbox),~/.local/share/opencode/auth.json(ocbox),~/.qwen/oauth_creds.json(qcbox),~/.codex/auth.json(cxbox),~/.omp/.envand~/.omp/agent/.env(ompbox, read-only dotenv API keys).
Note this does not cover the always-mounted main config (~/.claude/settings.json, ~/.config/opencode/opencode.json, ~/.qwen/settings.json, ~/.codex/config.toml, ~/.omp/agent/config.yml): any key stored in those is passed regardless of --with-credentials. GitHub token injection (GH_TOKEN) is unaffected. OAuth logins done with /login inside an ompbox container stay per project (see docs/usage.md).
The same launchers run inside a long-lived pod, with the pod playing the role of your workstation: rsh in, cd ~/repos/<repo>, run ccbox. The harness starts through Apptainer from a SIF converted from the same image, with the same per-project isolation. See docs/kubernetes.md.
| Document | Contents |
|---|---|
| docs/usage.md | All flags, provider configuration, GitHub auth, version pinning, firewall, clipboard, agent teams, platform notes, included tools |
| docs/architecture.md | How images, launchers, mounts, and per-project isolation work; what data lives where for each harness |
| docs/development.md | Building locally, adding packages/domains, CI/CD and release process |
| docs/kubernetes.md | Running the launchers in a long-lived pod on Kubernetes/OpenShift (Apptainer runtime, RWX volume, SCC, egress policy) |
See CONTRIBUTING.md for contribution guidelines.