This skill should be used when creating Docker containers for Claude Code sandboxing, configuring isolated development environments, setting up Docker volumes and persistence, configuring port forwarding for sandboxed applications, or troubleshooting Docker container issues in sandbox contexts. Provides Docker configuration knowledge specifically for running Claude Code in contained environments.
From sandboxnpx claudepluginhub aaronbassett/agent-foundry --plugin sandboxThis skill uses the workspace's default tool permissions.
examples/Dockerfile.templateexamples/docker-compose.ymlreferences/optimization.mdreferences/troubleshooting.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides agent creation for Claude Code plugins with file templates, frontmatter specs (name, description, model), triggering examples, system prompts, and best practices.
Configure Docker containers to run Claude Code in isolated, safe environments that prevent AI agents from modifying the host system.
This skill provides Docker configuration knowledge specifically for creating sandboxed development environments. Focus on the minimum Docker setup needed for Claude Code isolation while maintaining full development capabilities, not general Docker expertise.
Sandboxes use Docker to create complete isolation between Claude Code and the host system:
Default recommendation: Ubuntu 24.04 LTS
FROM ubuntu:24.04
Why Ubuntu 24.04:
Alternative images:
debian:bookworm - Minimal, smaller image sizeubuntu:25.04 - Latest features, shorter supportFor faster sandbox creation with common tools pre-installed, build a custom base image:
When to use custom base images:
How to create:
# my-sandbox-base.dockerfile
FROM ubuntu:24.04
# Install common tools
RUN apt-get update && apt-get install -y \
curl wget git build-essential \
ripgrep fd-find jq python3 python3-pip \
&& rm -rf /var/lib/apt/lists/*
# Install Rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
# Install Node.js via nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
Build and tag:
docker build -f my-sandbox-base.dockerfile -t my-sandbox-base:latest .
Use in Sandbox.toml:
[sandbox]
base_image = "my-sandbox-base:latest"
Mount the workspace and persistence directories:
docker run \
-v $(pwd)/workspace:/workspace \
-v $(pwd)/.docker-cache/cargo:/root/.cargo \
-v $(pwd)/.docker-cache/npm:/root/.npm \
-v $(pwd)/.docker-cache/pip:/root/.cache/pip \
-v $(pwd)/.docker-cache/claude:/root/.claude \
sandbox-container
Critical mounts:
/workspace - Project source code (editable from host)/root/.cargo - Rust package cache/root/.npm - Node.js package cache/root/.cache/pip - Python package cache/root/.claude - Claude Code config and cacheBenefits:
Forward ports for web development:
docker run -p 3000-3999:3000-3999 sandbox-container
Port range rationale:
Custom ports: Detect from package.json scripts or user specification:
# Specific ports only
docker run -p 3000:3000 -p 8080:8080 sandbox-container
Pass through essential environment variables:
docker run \
--env-file .env \
-e GITHUB_TOKEN="${GITHUB_TOKEN}" \
sandbox-container
Always pass through:
GITHUB_TOKEN - For gh CLI operations.envNever pass through:
FROM ubuntu:24.04
# Set non-interactive frontend for apt
ENV DEBIAN_FRONTEND=noninteractive
# Install base packages
RUN apt-get update && apt-get install -y \
curl wget git build-essential \
ca-certificates gnupg \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /workspace
# Install languages (Rust, Python, Node.js)
# ... language-specific setup ...
# Install CLI tools
# ... tool installation ...
# Install Claude Code
RUN curl -fsSL https://claude.ai/install.sh | bash
# Configure shell
# ... shell setup ...
CMD ["/bin/bash"]
Order Dockerfile commands by change frequency:
Good ordering:
# Rarely changes - cached well
FROM ubuntu:24.04
RUN apt-get update && apt-get install -y curl git
# Occasionally changes - medium cache hit rate
RUN install_rust_stable
# Frequently changes - volume mounted, not in image
# (Don't COPY source code into image)
Why this matters:
Multi-stage builds are typically NOT needed for sandbox containers because:
Skip multi-stage builds for sandboxes.
#!/bin/bash
# up.sh
docker build -t sandbox-${PROJECT_NAME} .
docker run -d \
--name sandbox-${PROJECT_NAME} \
-v $(pwd)/workspace:/workspace \
-v $(pwd)/.docker-cache/cargo:/root/.cargo \
-v $(pwd)/.docker-cache/npm:/root/.npm \
-v $(pwd)/.docker-cache/pip:/root/.cache/pip \
-v $(pwd)/.docker-cache/claude:/root/.claude \
-p 3000-3999:3000-3999 \
--env-file .env \
sandbox-${PROJECT_NAME}
echo "Sandbox is starting..."
# Wait and check if the container is running
sleep 2
if docker ps | grep -q "sandbox-${PROJECT_NAME}"; then
echo "✅ Sandbox is running!"
echo "Access it with: ./sandbox/shell.sh"
else
echo "❌ Failed to start sandbox."
echo "Check logs: docker logs sandbox-${PROJECT_NAME}"
exit 1
fi
#!/bin/bash
# shell.sh
docker exec -it sandbox-${PROJECT_NAME} /bin/zsh
#!/bin/bash
# run.sh
docker exec sandbox-${PROJECT_NAME} "$@"
#!/bin/bash
# stop.sh
docker stop sandbox-${PROJECT_NAME}
docker rm sandbox-${PROJECT_NAME}
Add visual indicators that you're in a container:
# In .zshrc
if [ -f /.dockerenv ]; then
export IN_CONTAINER=true
# Starship will show container indicator
fi
Starship config recognizes this:
[container]
disabled = false
symbol = "🐳 "
style = "bold red"
Use .dockerignore to exclude unnecessary files:
# .dockerignore
.git
node_modules/
.docker-cache/
*.log
.env.local
Benefits:
Add health checks for long-running services:
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/ || exit 1
Use sparingly - only for services that need it.
Container runs as root by default. Files created in workspace will be root-owned.
Solution 1: Match host UID/GID
ARG USER_ID=1000
ARG GROUP_ID=1000
RUN groupadd -g ${GROUP_ID} developer && \
useradd -u ${USER_ID} -g developer developer
USER developer
Solution 2: Fix permissions on stop
# In stop.sh
docker exec sandbox-${PROJECT_NAME} chown -R $(id -u):$(id -g) /workspace
docker stop sandbox-${PROJECT_NAME}
Choose Solution 2 for simplicity.
Containers are network-isolated by default. Only exposed ports are accessible.
Don't expose:
Never build secrets into the image:
# ❌ BAD
RUN git clone https://user:password@github.com/repo.git
# ✅ GOOD
RUN git clone https://github.com/repo.git
# (Requires GITHUB_TOKEN in environment)
Use .env files and --env-file flag instead.
For detailed troubleshooting and optimization:
references/troubleshooting.md - Common Docker issues and solutionsreferences/optimization.md - Performance and DevX improvementsComplete working examples:
examples/Dockerfile.template - Full Dockerfile template with all featuresexamples/docker-compose.yml - Alternative using Docker ComposeWith language-environment-config:
With sandbox-config-management:
Default base image: ubuntu:24.04
Required volume mounts:
/workspace - Source code/root/.cargo - Rust cache/root/.npm - Node cache/root/.cache/pip - Python cache/root/.claude - Claude Code configCommon port range: -p 3000-3999:3000-3999
Environment: --env-file .env + -e GITHUB_TOKEN
Order Dockerfile: Base → Languages → Tools → Config
Skip multi-stage builds for dev containers