Claude Code Docker 容器化方案
基于双层镜像架构的快速构建方案
目录
方案概述
本项目通过 Docker 容器化 Claude Code CLI,提供一致、可移植的开发环境。
核心目标
- 快速构建 - 通过预构建基础镜像,重建时间从 5-10 分钟降至 10-30 秒
- 环境一致 - 任何机器上都是相同的工具版本和配置
- 安全隔离 - Claude Code 的操作被限制在容器内
- 开袋即用 - 预装所有依赖(Node.js、Bun、Chromium、Git 等)
双层镜像架构
┌─────────────────────────────────────┐
│ docker-claude:latest (应用镜像) │ ← 只包含 skills,构建快 (~10 秒)
│ - 复制 skills 目录 │
│ - 用户配置和环境变量 │
└─────────────────────────────────────┘
↑ 基于
┌─────────────────────────────────────┐
│ docker-claude-base:with-deps │ ← 预构建基础镜像,一次构建永久缓存
│ - Ubuntu 24.04 LTS │
│ - 系统包 (git, curl, chromium 等) │
│ - Node.js 24 LTS │
│ - Bun (latest) │
│ - Claude Code CLI (latest) │
│ - 非 root 用户 claude │
└─────────────────────────────────────┘镜像大小
| 镜像 | 大小 | 说明 |
|---|---|---|
docker-claude-base:with-deps |
~1.37 GB | 包含所有重依赖 |
docker-claude:latest |
~1.37 GB | 仅增加 skills 目录 |
构建时间对比
| 场景 | 传统构建 | 优化后 |
|---|---|---|
| 首次构建 | ~8-12 分钟 | ~8-12 分钟(相同) |
| 重建(缓存命中) | ~5-8 分钟 | ~10-30 秒 |
| 基础镜像变化 | ~8-12 分钟 | ~5-8 分钟(仅重建基础层) |
与官方沙箱对比
官方沙箱 (Sandbox)
Claude Code 内置的轻量级隔离环境,基于 macOS Sandbox 或 Linux seccomp/namespace。
架构图:
用户终端
↓
Claude Code CLI
↓
官方沙箱 (限制文件系统访问、网络等)
↓
宿主机工具 (git, npm, docker 等)Docker 容器方案
在 Docker 容器中运行完整的 Claude Code 环境。
架构图:
用户终端
↓
docker exec 进入容器
↓
容器内的 Claude Code CLI
↓
容器内工具链 (完全可控的环境)
↓
挂载的宿主机卷 (通过 -v 映射)详细对比表
| 维度 | 官方沙箱 | Docker 容器 |
|---|---|---|
| 隔离性 | ⭐⭐ 弱 - 仍是宿主机环境 | ⭐⭐⭐⭐⭐ 强 - 容器隔离 |
| 启动速度 | ⭐⭐⭐⭐⭐ 秒级 - 无需容器 | ⭐⭐⭐⭐ 秒级(容器已存在) |
| 环境一致性 | ⭐⭐ 依赖宿主机配置 | ⭐⭐⭐⭐⭐ 完全一致 |
| 安全性 | ⭐⭐⭐ 中等 - 沙箱限制 | ⭐⭐⭐⭐⭐ 高 - 容器隔离 |
| 配置复杂度 | ⭐⭐⭐⭐⭐ 简单 - 开箱即用 | ⭐⭐⭐ 中等 - 需 Docker 知识 |
| 可定制性 | ⭐⭐ 受限 - 依赖宿主机 | ⭐⭐⭐⭐⭐ 完全可控 |
| 磁盘占用 | ⭐⭐⭐⭐⭐ 小 - 无额外镜像 | ⭐⭐⭐ 较大 - ~1.37GB |
| 团队协作 | ⭐⭐ 配置可能不同 | ⭐⭐⭐⭐⭐ 镜像统一 |
| 工具预装 | ⭐⭐ 需自行安装 | ⭐⭐⭐⭐⭐ 全部预装 |
| 跨平台 | ⭐⭐⭐ 依赖系统支持 | ⭐⭐⭐⭐ 有 Docker 即可 |
优缺点总结
官方沙箱
优点:
- ✅ 启动快 - 无需启动容器,秒级响应
- ✅ 配置简单 - 无需 Docker 配置,开箱即用
- ✅ 原生性能 - 直接使用宿主机工具,无虚拟化开销
- ✅ 文件访问方便 - 可以直接访问项目文件,无需挂载卷
缺点:
- ❌ 隔离性弱 - 仍是宿主机环境,有安全风险
- ❌ 环境依赖宿主机 - 需要预先安装 Node.js、Bun、Git 等
- ❌ 权限受限 - 某些操作(如 Docker in Docker)无法执行
- ❌ 环境不一致 - 不同机器可能有不同配置
Docker 容器
优点:
- ✅ 强隔离性 - 容器内操作不影响宿主机
- ✅ 环境一致 - 任何机器上都是相同的工具版本
- ✅ 预装所有工具 - Node.js、Bun、Chromium、Git 等全部内置
- ✅ 可定制性强 - 可以安装任意工具,修改系统配置
- ✅ 快速上手 - 新人只需拉取镜像即可开始工作
- ✅ 配置持久化 - 通过卷挂载保存配置,容器可随意重建
缺点:
- ❌ 启动稍慢 - 需要启动容器(但已优化到秒级)
- ❌ 镜像较大 - 约 1.37GB(但缓存后构建很快)
- ❌ 需要 Docker - 宿主机必须安装 Docker
- ❌ 文件访问需挂载 - 需要通过
-v挂载卷访问宿主机文件 - ❌ 网络配置复杂 - 某些场景需要配置网络模式
使用指南
目录结构
docker-optimized/
├── Dockerfile.base # 预构建基础镜像(重依赖)
├── Dockerfile # 应用镜像(轻量,仅 skills)
├── docker-compose.yml # Docker Compose 配置
├── build.sh # 自动化构建脚本
├── .dockerignore # 构建排除文件
├── README.md # 快速开始指南
└── skills/ # Claude Code Skills 目录
├── claude-mem/
├── everything-claude-code/
└── superpowers/核心文件详解
1. Dockerfile.base(预构建基础镜像)
基础镜像包含所有重量级依赖,一次构建永久缓存:
# ============================================
# Pre-built Base Image for Claude Code Docker
# ============================================
# This image contains all heavy dependencies:
# - Ubuntu 24.04 base (LTS)
# - System packages (git, curl, chromium, etc.)
# - Node.js 24 LTS
# - Bun (latest)
# - Claude Code CLI (latest)
#
# Build this image once and tag it locally for fast rebuilds
# ============================================
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
# ============================================
# Install system dependencies
# ============================================
RUN apt-get update && apt-get install -y --no-install-recommends \
# Basic tools
git curl ca-certificates jq bc gpg unzip \
# Build tools
build-essential \
# Common utilities
vim nano wget htop tree \
# Chromium dependencies
libnss3 libatk-bridge2.0-0 libxss1 libgtk-3-0 \
libx11-xcb1 libdrm2 libgbm1 libasound2t64 \
libxcomposite1 libxdamage1 libxfixes3 \
libpango-1.0-0 libcairo2 libatk1.0-0 \
# Other dependencies
fonts-liberation libappindicator3-1 libu2f-udev \
xdg-utils libvulkan1 \
# Chromium browser
chromium-browser chromium-chromedriver \
# Cleanup
&& rm -rf /var/lib/apt/lists/*
# ============================================
# Install Node.js 24 LTS
# ============================================
RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# ============================================
# Install Bun (latest)
# ============================================
ENV BUN_INSTALL="/usr/local"
ENV PATH="/usr/local/bin:$PATH"
RUN curl -fsSL https://bun.sh/install | bash
# ============================================
# Install Claude Code CLI
# ============================================
RUN npm install -g @anthropic-ai/claude-code
# ============================================
# Set Chromium environment variables
# ============================================
ENV CHROME_BIN=/usr/bin/chromium-browser
ENV CHROMIUM_BIN=/usr/bin/chromium-browser
# ============================================
# Create non-root user
# ============================================
RUN useradd -m -s /bin/bash claude \
&& mkdir -p /home/claude/.claude /home/claude/.gstack \
&& chown -R claude:claude /home/claude \
&& chmod 1777 /tmp
# ============================================
# Set environment variables
# ============================================
ENV HOME=/home/claude
ENV USER=claude
ENV SHELL=/bin/bash
# Working directory
WORKDIR /workspace
CMD ["/bin/bash"]2. Dockerfile(应用镜像)
应用镜像基于基础镜像构建,仅复制 skills 目录:
# ============================================
# Stage 1: Builder - Prepare skills
# ============================================
FROM docker-claude-base:with-deps AS builder
WORKDIR /build
# Copy skill plugins from local context
COPY skills/ ./skills/
# ============================================
# Stage 2: Runtime - Copy skills and configure
# ============================================
FROM docker-claude-base:with-deps AS runtime
# Copy skills from builder stage
COPY --from=builder /build/skills /home/claude/.claude/skills/
# Set ownership
RUN chown -R claude:claude /home/claude/.claude/skills
# ============================================
# Environment variables (overridable at runtime)
# ============================================
# Claude / Anthropic
ENV ANTHROPIC_API_KEY=""
ENV ANTHROPIC_BASE_URL="https://api.anthropic.com"
# OpenAI compatible
ENV OPENAI_API_KEY=""
ENV OPENAI_BASE_URL="https://api.openai.com/v1"
# Alibaba DashScope
ENV DASHSCOPE_API_KEY=""
ENV DASHSCOPE_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
# DeepSeek
ENV DEEPSEEK_API_KEY=""
ENV DEEPSEEK_BASE_URL="https://api.deepseek.com/v1"
# Moonshot (Kimi)
ENV MOONSHOT_API_KEY=""
ENV MOONSHOT_BASE_URL="https://api.moonshot.cn/v1"
# Zhipu AI
ENV ZHIPU_API_KEY=""
ENV ZHIPU_BASE_URL="https://open.bigmodel.cn/api/paas/v4"
# SiliconFlow
ENV SILICONFLOW_API_KEY=""
ENV SILICONFLOW_BASE_URL="https://api.siliconflow.cn/v1"
# Default model
ENV DEFAULT_MODEL="claude-3-5-sonnet-20241022"
# Terminal
ENV TERM=xterm-256color
WORKDIR /workspace
USER claude
CMD ["/bin/bash"]3. docker-compose.yml
Docker Compose 配置文件,支持多服务商 API 密钥:
services:
claude:
build:
context: .
dockerfile: Dockerfile
target: runtime
container_name: claude-code
# Interactive mode
stdin_open: true
tty: true
# Volume mounts
volumes:
# Working directory
- ./data/workspace:/workspace
# Claude config persistence
- ./data/claude-config:/home/claude/.claude
# Gstack config persistence
- ./data/gstack-config:/home/claude/.gstack
# Optional: Mount host SSH keys
- ~/.ssh:/home/claude/.ssh:ro
# Optional: Mount host git config
- ~/.gitconfig:/home/claude/.gitconfig:ro
# Working directory
working_dir: /workspace
# Environment variables (loaded from .env file)
environment:
# Claude / Anthropic
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL:-https://api.anthropic.com}
# OpenAI compatible
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
- OPENAI_BASE_URL=${OPENAI_BASE_URL:-https://api.openai.com/v1}
# Alibaba DashScope
- DASHSCOPE_API_KEY=${DASHSCOPE_API_KEY:-}
- DASHSCOPE_BASE_URL=${DASHSCOPE_BASE_URL:-https://dashscope.aliyuncs.com/compatible-mode/v1}
# DeepSeek
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}
- DEEPSEEK_BASE_URL=${DEEPSEEK_BASE_URL:-https://api.deepseek.com/v1}
# Moonshot (Kimi)
- MOONSHOT_API_KEY=${MOONSHOT_API_KEY:-}
- MOONSHOT_BASE_URL=${MOONSHOT_BASE_URL:-https://api.moonshot.cn/v1}
# Zhipu AI
- ZHIPU_API_KEY=${ZHIPU_API_KEY:-}
- ZHIPU_BASE_URL=${ZHIPU_BASE_URL:-https://open.bigmodel.cn/api/paas/v4}
# SiliconFlow
- SILICONFLOW_API_KEY=${SILICONFLOW_API_KEY:-}
- SILICONFLOW_BASE_URL=${SILICONFLOW_BASE_URL:-https://api.siliconflow.cn/v1}
# Default model
- DEFAULT_MODEL=${DEFAULT_MODEL:-claude-3-5-sonnet-20241022}
# Terminal
- TERM=${TERM:-xterm-256color}
# Network mode (host mode for easy access to local services)
network_mode: host
# Startup command
command: /bin/bash4. build.sh(自动化构建脚本)
自动化构建脚本,支持智能缓存检测:
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
BASE_IMAGE="docker-claude-base:with-deps"
APP_IMAGE="docker-claude:latest"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Functions
print_header() {
echo -e "\n${BLUE}========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}========================================${NC}\n"
}
print_success() {
echo -e "${GREEN}✓ $1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠ $1${NC}"
}
print_error() {
echo -e "${RED}✗ $1${NC}"
}
# Check if base image exists locally
check_base_image() {
if docker image inspect "$BASE_IMAGE" &> /dev/null; then
return 0
else
return 1
fi
}
# Build the base image
build_base_image() {
print_header "Step 1: Building Base Image"
echo "Base image: $BASE_IMAGE"
echo "This image contains:"
echo " - Ubuntu 24.04"
echo " - System packages (git, curl, chromium, etc.)"
echo " - Node.js 24 LTS"
echo " - Bun 1.3.11"
echo " - Claude Code CLI"
echo ""
echo "This takes ~5-10 minutes on first build, then cached."
echo ""
docker build -t "$BASE_IMAGE" -f Dockerfile.base .
print_success "Base image built: $BASE_IMAGE"
# Show image size
local size=$(docker image inspect "$BASE_IMAGE" --format='{{.Size}}' | awk '{printf "%.2f GB\n", $1/1024/1024/1024}')
echo " Image size: $size"
}
# Build the application image
build_app_image() {
print_header "Step 2: Building Application Image"
echo "Application image: $APP_IMAGE"
echo "This image layers skills on top of the base image."
echo ""
docker build -t "$APP_IMAGE" --build-arg BUILDKIT_INLINE_CACHE=1 .
print_success "Application image built: $APP_IMAGE"
# Show image size
local size=$(docker image inspect "$APP_IMAGE" --format='{{.Size}}' | awk '{printf "%.2f GB\n", $1/1024/1024/1026}')
echo " Image size: $size"
}
# Show build statistics
show_stats() {
print_header "Build Statistics"
echo "Local images:"
docker images | grep -E "(docker-claude-base|docker-claude:)" || true
echo ""
}
# Main execution
main() {
cd "$SCRIPT_DIR"
print_header "Docker Claude Code - Build Script"
echo "Directory: $SCRIPT_DIR"
echo ""
# Check for skills directory
if [ ! -d "../skills" ]; then
print_error "skills/ directory not found in parent directory"
echo "Please ensure skills/ exists at: $SCRIPT_DIR/../skills/"
exit 1
fi
# Copy skills to local context
print_header "Preparing Build Context"
echo "Copying skills from parent directory..."
if [ -d "./skills" ]; then
rm -rf "./skills"
fi
cp -r "../skills" "./skills"
print_success "Skills copied to ./skills/"
# Check if base image exists
if check_base_image; then
print_success "Base image found: $BASE_IMAGE"
echo "Skipping base image build, using cached version."
else
print_warning "Base image not found, building now..."
build_base_image
fi
# Build application image
build_app_image
# Show statistics
show_stats
print_header "Build Complete!"
echo "To start the container:"
echo " docker-compose up -d"
echo ""
echo "To attach to the container:"
echo " docker exec -it claude-code /bin/bash"
echo ""
echo "To rebuild (base image cached):"
echo " ./build.sh"
echo ""
}
# Run main function
main "$@"5. .dockerignore
构建时排除的文件:
# Git
.git
.gitignore
# Claude config
.claude
CLAUDE.md
# Documentation
*.md
docs/
# Environment files
.env
.env.*
!.env.example
# Build artifacts
docker-optimized/
*.log
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Test and coverage
coverage/
*.test
*.spec
# Temporary files
tmp/
temp/
*.tmp6. .env.example(环境变量示例)
API 密钥配置模板(已脱敏):
# ============================================
# Claude Code Container Environment Variables
# Copy to .env and fill in your API Keys
# ============================================
# ============================================
# Anthropic Claude (Native Claude Code support)
# Get: https://console.anthropic.com
# ============================================
ANTHROPIC_API_KEY=sk-ant-xxx
ANTHROPIC_BASE_URL=https://api.anthropic.com
# ============================================
# OpenAI Compatible (Fallback)
# Get: https://platform.openai.com/api-keys
# ============================================
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai.com/v1
# ============================================
# Domestic Cloud Provider API Keys (Fill as needed)
# ============================================
# Alibaba Cloud DashScope (Qwen series)
# Get: https://dashscope.aliyun.com/api-key
DASHSCOPE_API_KEY=sk-xxx
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
# DeepSeek
# Get: https://platform.deepseek.com/api_keys
DEEPSEEK_API_KEY=sk-xxx
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
# Moonshot (Kimi)
# Get: https://platform.moonshot.cn/console/api-keys
MOONSHOT_API_KEY=sk-xxx
MOONSHOT_BASE_URL=https://api.moonshot.cn/v1
# Zhipu AI (GLM series)
# Get: https://open.bigmodel.cn/usercenter/apikeys
ZHIPU_API_KEY=xxx.xxx
ZHIPU_BASE_URL=https://open.bigmodel.cn/api/paas/v4
# SiliconFlow
# Get: https://cloud.siliconflow.cn/account/ak
SILICONFLOW_API_KEY=sk-xxx
SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1
# ============================================
# Default Model Configuration
# ============================================
DEFAULT_MODEL=claude-3-5-sonnet-20241022
# ============================================
# Terminal Configuration
# ============================================
TERM=xterm-256color快速开始
# 1. 进入目录
cd docker-optimized
# 2. 首次构建(基础镜像 + 应用镜像)
./build.sh
# 3. 启动容器
docker-compose up -d
# 4. 附加到容器
docker exec -it claude-code /bin/bash日常重建(缓存命中)
# 基础镜像已缓存,重建只需 10-30 秒
./build.sh
# 或直接使用 docker-compose
docker-compose build环境变量配置
通过 .env 文件配置 API 密钥:
# 复制示例配置
cp ../.env.example .env
# 编辑配置(替换为你的 API 密钥)
vim .env
# 启动时自动加载
docker-compose up -d数据持久化
volumes:
- ./data/workspace:/workspace # 工作目录
- ./data/claude-config:/home/claude/.claude # Claude 配置
- ./data/gstack-config:/home/claude/.gstack # Gstack 配置所有数据持久化到 ./data/ 目录,容器删除后数据不丢失。
推荐场景
选择 官方沙箱 如果:
- ✅ 个人使用,快速测试
- ✅ 宿主机环境已经配置完善
- ✅ 不需要特殊工具或系统权限
- ✅ 不想依赖 Docker
选择 Docker 容器 如果:
- ✅ 团队协作,需要统一环境
- ✅ 需要特定版本的工具(如 Node.js 24、Bun 最新版)
- ✅ 关心安全性和隔离性
- ✅ 经常在不同机器间切换
- ✅ 需要访问 Chromium 等复杂依赖(如 E2E 测试)
- ✅ 想要"开箱即用"的体验
故障排除
构建失败
# 清理构建缓存
docker builder prune -f
# 重新构建
./build.sh基础镜像损坏
# 删除并重建基础镜像
docker rmi docker-claude-base:with-deps
docker build -t docker-claude-base:with-deps -f Dockerfile.base .容器无法启动
# 查看容器日志
docker logs claude-code
# 删除容器重新创建
docker rm -f claude-code
docker-compose up -d结论
对于需要环境一致性、安全性和团队协作的场景,Docker 容器方案是更好的选择。虽然需要额外的 Docker 配置和镜像存储空间,但通过双层镜像架构和优化后的构建流程,已经将重建时间从 5-10 分钟降至 10-30 秒,提供了优秀的开发体验。
官方沙箱更适合临时测试或快速原型开发,但对于生产环境或团队使用,Docker 容器方案的优势更加明显。
参考资料:ANALYSIS.md