Run Claude Code inside a sandboxed Linux container on macOS — full isolation, ephemeral by default, credentials bridged automatically (so uses your Claude Code plan).
Claude Code runs in an ephemeral, isolated container — a strong fit for YOLO permission modes like --dangerously-skip-permissions: risky actions are sandboxed, and local changes disappear unless you explicitly persist them via git.
Apple Container provides Apple Silicon-native Linux containers with lightweight-VM isolation. Superior to the Seatbelt sandbox that Claude Code uses by default.
- macOS with Apple Silicon
- Apple's
containerCLI - Claude Code authenticated on host (
claude login) - GitHub CLI authenticated on host (
gh auth login) — optional, for git push/PR workflows
./launch.sh --rebuild # Build image (first time)
./launch.sh # Run Claude Code in container
./launch.sh -C /path/to/project # Specific project
./launch.sh --rebuild --lang golang # Go imageSymlink scripts to run from any directory:
ln -sf ~/Projekty/Container/launch.sh ~/.local/bin/launch
ln -sf ~/Projekty/Container/cleanup.sh ~/.local/bin/cleanupBoth scripts resolve symlink chains, so SCRIPT_DIR always points to the real Container directory.
Place defaults in ~/.config/container/ — project-local configs take priority:
mkdir -p ~/.config/container
cp container-build.toml ~/.config/container/
cp container-run.example.toml ~/.config/container/container-run.toml| Document | What's inside |
|---|---|
| RUNNING.md | Building images, running containers, workspace modes, cleanup |
| CONFIGURATION.md | Build config, runtime config, MCP servers, permissions |
| TROUBLESHOOTING.md | Common errors and fixes |
| Container Lifecycle | How containers, images, and builder cache interact |
| MCP in Containers | MCP server architecture and setup details |
| File | Purpose |
|---|---|
Dockerfile |
Multi-target image: base + Python or Go |
entrypoint.sh |
Container startup: config, credentials, workspace, MCP registration |
launch.sh |
Main runner: builds image, extracts credentials, launches container |
cleanup.sh |
Container/image/builder lifecycle management |
container-build.toml |
Build-time versions and feature flags |
container-run.toml |
Per-project runtime: resources, Claude mode, MCP, workspace excludes |
container-run.example.toml |
Annotated example with all options |
templates/CONTAINER.*.md.tmpl |
Language-specific CONTAINER.md templates |
Multi-target Dockerfile with shared base and language-specific stages:
- Base = Debian bookworm-slim (arm64) + Claude Code, git, gh, jq, ripgrep, fd, fzf, uv, openssh-client. Non-root
sandboxuser. - Python (
claudecode-python) = Python 3.14 via uv - Go (
claudecode-golang) = Go 1.26 + gopls, goimports, golangci-lint, gotestsum, govulncheck, delve
| Image | Build command |
|---|---|
claudecode-python |
./launch.sh --rebuild |
claudecode-golang |
./launch.sh --rebuild --lang golang |
Containers can connect to MCP servers via HTTP transport — no binaries baked into images:
- Remote HTTP servers — configured in
[mcp]section, tokens from macOS Keychain - Host-side Postgres — reached via Apple Container gateway (
192.168.64.1)
See CONFIGURATION.md and MCP in Containers for setup.
Blocked by an upstream bug in the
claude-agent-acpstatic binary (linux-arm64) — crashes with a JavaScript TDZ error (Cannot access 'z4' before initialization) duringsession/prompt. The Homebrew (Node.js) build works fine; only the static Bun SEA binary is affected.zed-claude-acp.shis ready — waiting for a fix.