Run OpenCode and other AI coding agents in secure Docker containers.
Protect your SSH keys, API tokens, and system files while using AI tools that need filesystem access.
Last updated: February 25, 2026
- What's New
- Why Use This?
- Quick Start
- Configuration
- Directory Structure
- Security Model
- Quick Reference
- Troubleshooting
- Other Tools
- Contributing
- License
- Git Fetch-Only: Allow git fetch/pull but block push β perfect for AI agents that should read but not write
- Bundled Skills: RTK token optimizer skills auto-installed for OpenCode users
- SSH Config Fix: Resolved crash during git credential setup
# Fetch-only mode (no push allowed)
opencode --git-fetch
# Or select from interactive menu:
# 4) Fetch only - allow once (no push, this session)
# 5) Fetch only - always for this workspace (no push)
# Manage via CLI
npx @kokorolx/ai-sandbox-wrapper git fetch-only ~/projects/myrepo
npx @kokorolx/ai-sandbox-wrapper git full ~/projects/myrepo
npx @kokorolx/ai-sandbox-wrapper git status| Without Sandbox | With AI Sandbox |
|---|---|
| AI reads SSH keys, API tokens | β Only whitelisted folders visible |
| Full filesystem access | β Read-only except workspace |
| Host environment exposed | β API keys passed explicitly |
| Runs with your permissions | β Non-root, CAP_DROP=ALL |
Prerequisites: Docker Desktop (macOS/Windows) or Docker Engine (Linux)
# Install
npx @kokorolx/ai-sandbox-wrapper setup
# Reload shell
source ~/.zshrc
# Run OpenCode
opencodeDuring setup: select opencode, choose registry images (faster), whitelist your project directories.
nano ~/.ai-sandbox/envANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
npx @kokorolx/ai-sandbox-wrapper workspace add ~/projects/my-app
# Or: echo '/path/to/project' >> ~/.ai-sandbox/workspaces# New --expose flag (recommended)
opencode --expose 3000
opencode -e 3000,5555,5556
# Expose to network
PORT_BIND=all opencode --expose 3000
# Legacy (deprecated)
PORT=3000 opencodeWeb Mode Auto-Detection:
opencode web # Auto-exposes 4096
opencode web --port 8080 # Auto-exposes 8080
opencode --expose 3000 web # Exposes both 3000 and 4096Output:
π Detected web command. Auto-exposing port 4096.
π Port mappings: 4096
π Web UI available at http://localhost:4096
Control authentication for OpenCode web server:
# Set password directly (visible in process list)
ai-run opencode web --password mysecret
ai-run opencode web -p mysecret
# Read password from environment variable (more secure)
MY_PASS=secret ai-run opencode web --password-env MY_PASS
# Explicitly allow unsecured mode (suppresses warning)
ai-run opencode web --allow-unsecuredLogin credentials:
- Username:
opencode(default, override withOPENCODE_SERVER_USERNAMEenv var) - Password: your configured password
Precedence: --password > --password-env > OPENCODE_SERVER_PASSWORD env > interactive prompt
Without flags, interactive mode shows a menu; non-interactive mode shows a security warning.
Port Conflict Detection:
β ERROR: Port 3000 is already in use by node (PID: 12345)
# Join Docker networks (for databases, APIs, MetaMCP)
opencode -n mynetwork
opencode -n network1,network2Git credentials are not shared by default. When you run a tool, you'll be prompted:
π Git Access Control
1) Yes, allow once
2) Yes, always allow for this workspace
3) No, keep Git disabled (secure default)
4) Fetch only - allow once (no push, this session)
5) Fetch only - always for this workspace (no push)
Fetch-only mode allows git fetch, git pull, git clone but blocks git push. Uses git's pushInsteadOf config β no network restrictions needed.
# Force fetch-only via flag
opencode --git-fetch
# Manage via CLI
npx @kokorolx/ai-sandbox-wrapper git fetch-only ~/projects/myrepo
npx @kokorolx/ai-sandbox-wrapper git full ~/projects/myrepoWhen running nano-brain inside the sandbox, ai-run performs a targeted preflight and automatic retry for common native-module failures (for example tree-sitter binding issues).
It also suppresses known non-fatal tree-sitter symbol-graph warnings when the command succeeds, so normal query output stays clean. To see suppressed diagnostics, run with debug mode (AI_RUN_DEBUG=1).
This behavior applies to both:
- direct mode (
ai-run npx nano-brain ...) - interactive shell mode (
ai-run, then runnpx nano-brain ...inside the container shell)
# Auto-repair enabled by default
ai-run npx nano-brain status
# Disable per-command
ai-run npx nano-brain status --no-nano-brain-auto-repair
# Disable via environment variable
AI_RUN_DISABLE_NANO_BRAIN_AUTO_REPAIR=1 ai-run npx nano-brain status
# Show suppressed non-fatal warning details
AI_RUN_DEBUG=1 ai-run npx nano-brain query "hello"Clipboard access in containers requires a terminal that supports OSC52 protocol.
Supported terminals: iTerm2, Warp, Kitty, Alacritty, WezTerm, Windows Terminal, Ghostty
Not supported: GNOME Terminal, VS Code Terminal, Tilix, Terminator
Test if your terminal supports clipboard:
printf "\033]52;c;$(printf "test" | base64)\a"
# Press Cmd+V / Ctrl+V - if you see "test", it worksπ Full details: CLIPBOARD_SUPPORT.md
During setup, you can optionally install MCP servers for AI agent browser automation:
| Tool | Maintainer | Features | Size |
|---|---|---|---|
| Chrome DevTools MCP | Performance profiling, Core Web Vitals, detailed console/network inspection | ~400MB | |
| Playwright MCP | Microsoft | Multi-browser (Chromium), TypeScript code generation, vision mode | ~300MB |
After installation, configure your MCP client (e.g., OpenCode) to use them:
~/.config/opencode/opencode.json:
{
"mcp": {
"chrome-devtools": {
"type": "local",
"command": [
"chrome-devtools-mcp",
"--headless",
"--isolated",
"--executablePath", "/opt/chromium",
"--chromeArg=--no-sandbox",
"--chromeArg=--disable-setuid-sandbox"
]
},
"playwright": {
"type": "local",
"command": [
"npx", "@playwright/mcp@latest",
"--headless",
"--browser", "chromium",
"--no-sandbox"
]
}
}
}Note: The
--no-sandboxflags are required when running in Docker containers. This is safe because the container itself provides isolation.
OpenCode containers auto-install these skills on first run (existing skills are never overwritten):
| Skill | Description |
|---|---|
rtk |
Command reference for RTK token optimizer (60-90% token savings) |
rtk-setup |
Persistent RTK enforcement β updates AGENTS.md and propagates to subagents |
Skills are copied to ~/.config/opencode/skills/ and available immediately.
~/.ai-sandbox/
βββ config.json # Workspaces, git, networks
βββ env # API keys
βββ tools/ # Per-tool sandbox homes
β βββ opencode/home/
βββ shared/git/ # Shared git credentials
Native configs are bind-mounted:
~/.config/opencodeβ/home/agent/.config/opencode~/.local/share/opencodeβ/home/agent/.local/share/opencode
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β HOST SYSTEM β
β β SSH keys, API tokens, browser data β
β β Home directory, system files β
β β Other projects β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
Docker isolation
β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β AI SANDBOX CONTAINER β
β β
/workspace (whitelisted folders only) β
β β
Passed API keys (explicit) β
β β
Git config (opt-in per workspace) β
β β Everything else β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
# Run OpenCode
opencode # Direct mode
opencode --shell # Interactive shell
opencode web # Web UI mode
# Port exposure
opencode --expose 3000 # Expose port
opencode -e 3000,4000 # Multiple ports
# Network
opencode -n mynetwork # Join Docker network
# Git fetch-only
opencode --git-fetch # Fetch only (no push)
# Nano-brain
ai-run npx nano-brain status # With auto-repair
AI_RUN_DISABLE_NANO_BRAIN_AUTO_REPAIR=1 ai-run npx nano-brain status
# Management
npx @kokorolx/ai-sandbox-wrapper workspace list
npx @kokorolx/ai-sandbox-wrapper clean| Issue | Solution |
|---|---|
command not found: opencode |
Run source ~/.zshrc |
Outside whitelisted workspace |
echo "$(pwd)" >> ~/.ai-sandbox/workspaces |
| Port already in use | Stop the process or use different port |
| Docker not found | Install and start Docker Desktop |
| Clipboard not working | Use OSC52-compatible terminal. See CLIPBOARD_SUPPORT.md |
| nano-brain native binding/tree-sitter error | Fatal errors auto-repair and retry once by default; known non-fatal symbol-graph warnings are suppressed unless AI_RUN_DEBUG=1 |
This sandbox also supports Claude, Gemini, Aider, Kilo, Codex, Amp, Qwen, and more.
See TOOLS.md for the full list and tool-specific configuration.
See CONTRIBUTING.md.
MIT