A comprehensive Docker-based development environment pre-configured with multiple language runtimes, network diagnostics, and debugging tools. Designed for use with Claude Code.
- Node.js (v24 LTS Krypton) + npm
- Bun (latest ~1.3.x)
- Go (1.25.x)
- Rust (stable) + cargo, rustfmt, clippy, rust-analyzer
- Zig (0.15.2) + zls 0.15.1 language server
- Python 3 + pip, venv
- ping, traceroute, mtr
- nmap, tcpdump, netcat
- dig, nslookup, host, whois
- iperf3, net-tools, iproute2
- Git + git-lfs
- Docker CLI + docker-compose
- PostgreSQL client (psql)
- ImageMagick (convert)
- Build tools: cmake, ninja, make, gcc, g++
- strace, ltrace, gdb, valgrind
- htop, btop, lsof
- ripgrep (rg), fd-find (fd), bat
- jq, yq (JSON/YAML processing)
- vim, nano, tmux, screen
- curl, wget
- cargo-watch, cargo-edit, cargo-audit
- tokei (code statistics)
- hyperfine (benchmarking)
- Pre-installed and ready to use
./build.sh
# or: docker build -t claude-sandbox .Or let the script build it automatically on first run.
# Run in current directory (auto-mounted to /workspace)
./claude-sandbox.sh
# Run with a specific project directory
./claude-sandbox.sh -m ~/my-project:/workspace
# Run with an initial prompt
./claude-sandbox.sh -p "Review the codebase and suggest improvements"
# Mount additional directories
./claude-sandbox.sh -m ~/data:/dataOnce inside the container:
# Start Claude Code
claude
# Or run a specific command
claude "explain this codebase"./claude-sandbox.sh [OPTIONS] [-- COMMAND]
Options:
-w, --workdir PATH Set working directory inside container (default: /workspace)
-m, --mount SRC:DST Mount a host directory (can be used multiple times)
If DST is omitted, mounts to the same path inside the container
-M, --overlay SRC:DST Mount read-only with ephemeral writes (overlayfs)
Writes are temporary and never persist to host
-p, --prompt PROMPT Initial prompt to pass to Claude Code
-d, --detach Run container in background
--insecure Expose host Docker socket and PID namespace (less isolated)
--no-creds Don't mount Claude credentials
-n, --name NAME Set container name
-v, --verbose Show the full docker command being executed
-h, --help Show help message
# Interactive Claude Code in current directory
./claude-sandbox.sh
# Run a specific command
./claude-sandbox.sh -- cargo build --release
# Start Claude Code directly with a prompt
./claude-sandbox.sh -p "explain this codebase"# Mount project and shared data
./claude-sandbox.sh \
-m ~/project:/workspace \
-m ~/shared-libs:/libs# Mount a directory read-only with temporary writes (lost when container stops)
./claude-sandbox.sh -M ~/sensitive-project:/workspace
# Combine regular and overlay mounts
./claude-sandbox.sh -m ~/data:/data -M ~/config:/config# Run npm install and build
./claude-sandbox.sh -- bash -c "npm install && npm run build"
# Run Rust tests
./claude-sandbox.sh -- cargo test
# Run Zig build
./claude-sandbox.sh -- zig buildThe sandbox runs an isolated Docker daemon by default:
./claude-sandbox.sh
# Inside the container - containers run INSIDE the sandbox
docker run -p 8080:80 nginx
curl localhost:8080 # Works! Port is accessible within sandboxThis provides:
- Full isolation from host Docker environment
- Containers accessible via localhost
- No host PID namespace exposure
Insecure mode - exposes host Docker socket:
./claude-sandbox.sh --insecure
# Inside the container - containers run on HOST
docker ps # Shows host containers
# Ports NOT accessible via localhost inside sandboxUse --insecure only when you specifically need host Docker access.
The script automatically mounts Claude configuration from your home directory
using bindfs to remap ownership to the container's claude user:
| Host Path | Container Path | Notes |
|---|---|---|
~/.claude/ |
/home/claude/.claude/ |
Config (.config.json), credentials, agents, skills, commands, plugins |
~/.claude.json |
/home/claude/.claude.json |
Legacy config (fallback if ~/.claude/.config.json doesn't exist) |
~/.config/claude/ |
/home/claude/.config/claude/ |
Additional config |
~/.anthropic/ |
/home/claude/.anthropic/ |
Alternative config location |
If ANTHROPIC_API_KEY is set on the host, it's passed through to the container.
If you haven't logged in to Claude Code yet:
# On your host machine (not in container)
claude login
# Then run the sandbox
./claude-sandbox.sh -m .:/workspace./claude-sandbox.sh --no-credsEdit the Dockerfile and rebuild:
# Add your tools
RUN apt-get update && apt-get install -y \
your-tool \
another-toolThen rebuild:
docker build -t claude-sandbox .The container is ephemeral by default. To persist state:
# Create a named volume for cargo cache
docker volume create cargo-cache
# Run with volume mounted
docker run -it --rm \
-v cargo-cache:/home/claude/.cargo/registry \
-v $(pwd):/workspace \
claude-sandboxMount your dotfiles:
./claude-sandbox.sh \
-m ~/.bashrc:/home/claude/.bashrc:ro \
-m ~/.vimrc:/home/claude/.vimrc:ro# Inside the container
# Check connectivity
ping -c 4 google.com
# Trace route
traceroute github.com
mtr --report google.com
# Port scanning (authorized targets only)
nmap -p 80,443 example.com
# DNS lookup
dig github.com
nslookup api.anthropic.com
# Network connections
netstat -tulpn
ss -tulpn
# Bandwidth testing
iperf3 -c iperf.he.netIf you get permission errors with Docker commands:
# The script tries to add the correct group automatically
# If it fails, you may need to run with --privileged (not recommended)
# Or fix docker socket permissions on the host
sudo chmod 666 /var/run/docker.sock# Exit the container and login on host
exit
claude login
# Re-run the sandbox
./claude-sandbox.sh -m .:/workspace# Try building with no cache
docker build --no-cache -t claude-sandbox .
# Or pull fresh base image
docker pull ubuntu:24.04
docker build -t claude-sandbox .The first run builds the image which takes several minutes. Subsequent runs start instantly.
-
Isolated by Default: The sandbox runs an isolated Docker daemon (dind) by default. Host Docker socket and PID namespace are NOT exposed unless you use
--insecure. -
Insecure Mode: Using
--insecureexposes the host Docker socket and PID namespace. Only use this when you specifically need host Docker access. -
Credentials: Claude credentials are mounted with bindfs for permission handling. The container can read and write to credential files.
-
Network: The container has full network access. Use
--network noneto disable if needed. The sandbox automatically detects host IPs and sets up routing so containers can reach services on the host (e.g., MCP servers, local APIs). If your host runs a firewall, you may need to allow traffic from Docker bridge interfaces (docker0,br-*,veth*) to the relevant host ports. -
Privileged Mode: The container runs in privileged mode (required for dind). This grants elevated capabilities inside the container.
MIT