自主型AI 编码代理 功能强大。它们可以浏览您的文件系统、执行 shell 命令、提交更改并修改文件,且无需您亲自敲下一行代码。但强大的能力也带来一个现实问题:一旦出错会怎样?万一代理修改了本不该动的配置文件,或安装了与您系统冲突的软件包,该怎么办?
大多数注重生产环境的开发者最终选择 Docker。我自己也在一次特定的会话后不断回到这个答案——当时 Claude Code 很“贴心”地清理了我项目的 .env 文件,因为它看起来“未被使用”。(其实它并非未用。)
容器在代理与宿主机之间提供了清晰的边界,而这种边界让无人值守的代理运行从焦虑变得踏实。
在本教程中,我将带您在 Docker 中运行 Claude Code:从构建最小基线镜像,到使用Docker Compose 编排多服务应用。完成后,您将拥有一套可复用且安全的工作流,可应用于任何项目。
如果您对最新的 Anthropic 模型感兴趣,推荐阅读我们的 Claude Opus 4.6 和 Claude Sonnet 4.6 指南。
Claude Code 如何与 Docker 集成
要理解为什么 Docker 与 Claude Code 天然契合,先简单弄清各自做什么会很有帮助。
Claude Code 是 Anthropic 推出的命令行代理式编码工具,于 2025 年 5 月正式发布。它驻留在您的终端,读取代码库,并通过自然语言提示执行任务(重构、编写测试、管理 git 工作流)。我们的Claude Code 2.1 全面教程 涵盖所需的一切。
Docker 是一个用于打包和运行应用的平台,它通过轻量、隔离的容器共享宿主 OS 内核,但保持严格的进程与文件系统边界。如果您对 Docker 完全陌生,建议先在免费的 Play with Docker 平台上试验。
Claude Code 需要一个可运行的环境,Docker 则提供了可复现、一次性的环境。二者结合威力强大,但要用好它们,您需要了解执行模型、安全默认值,以及最适合您场景的部署方式。
容器架构与执行流程
先从请求层面看一次容器化的 Claude Code 会话是如何工作的。
您在宿主终端发出一个提示(prompt)。
Docker 启动预装 Claude Code CLI 的容器,并将您的工作区以卷(volume)挂载。
Claude Code 从该挂载读取文件,理解代码库,在容器隔离的进程空间内执行命令,并将输出写回挂载卷。
会话结束后,容器的临时文件系统(挂载之外的所有内容)会被丢弃。
关键在于区分临时状态与持久状态。写入容器但不在挂载卷中的任何内容,清理时都会被删除。您的工作区位于宿主并被挂载进容器,因此会持久化。
这意味着临时依赖、构建产物和工具安装都会消失,但您的项目文件会如同 Claude 留下时那样保持不变。对我来说,这种分离让人安心:在理解这一点之前,我总是紧张地盯着代理会话。现在,我下达任务就去泡咖啡。
安全模型与安全默认
在理解执行流程后,值得明确说明 Docker 的隔离实际能保护什么、不能保护什么。
文件系统隔离是主要的安全收益。Claude Code 只能读写您明确挂载的路径。如果您没有将它们挂载进容器,您的SSH 密钥 、~/.aws 凭证、宿主环境变量以及系统配置文件对代理都是不可见的,除非您主动暴露它们。不过,这种保护前提是您谨慎配置挂载。
一条关键规则:切勿将宿主的 Docker 套接字(/var/run/docker.sock)挂载 到 Claude Code 容器中。如果代理能与宿主的 Docker 守护进程通信,它就可能启动特权容器、完全逃离沙箱,并获得对您机器的 root 级访问。
这是一个众所周知且没有正当理由的提权路径。我在一些社区 Dockerfile 中看到过这种做法,目的是让代理“管理容器”。每次看到我都想给作者发一条措辞强烈的消息。
选择合适的部署路径
抛开安全默认不谈,在写任何代码之前,您还需做一个决定:哪种部署模型适合您的用例?主要有三种选项,彼此并非可互换。
部署方式
最适合
关键取舍
Docker 沙箱(单容器)
隔离的、一次性代理任务
无服务间网络通信
Docker Compose
开发期多服务应用
配置更多,攻击面更广
Devcontainers
团队级标准化环境
需要 VS Code 或兼容 IDE
对于大多数任务(针对单个仓库运行代理、调试脚本、重构模块),纯 Docker 沙箱是最安全的默认选择。
当 Claude Code 需要与正在运行的数据库、API 或前端服务交互时,Docker Compose 就有意义了。
Devcontainers 适用于团队范围的标准化环境,并预装 IDE 扩展。值得注意的是,Anthropic 官方参考 devcontainer 内置防火墙,将出站连接限制在可信白名单内,也正因这种隔离,才能安全地以完全无人值守方式运行带有 --dangerously-skip-permissions 的 Claude Code。
本教程将同时介绍单容器沙箱和 Compose 设置。
为 Claude Code 准备 Docker 容器
既然架构和部署选项已明确,我们就先确保环境配置妥当再写代码。我见过太多人跳过这一步,而这也是此类教程半途失败的最常见原因。
系统与软件要求
在第一次运行 docker build 前,您需要具备以下条件:
Docker Desktop(macOS 或 Windows)或 Docker Engine(Linux),且守护进程处于运行状态。macOS 与 Windows 需在 BIOS/固件中启用虚拟化。Linux 上请将您的用户加入 docker 组(sudo usermod -aG docker $USER),或在每条 Docker 命令前加 sudo。
宿主机安装 Node.js v18 或更高版本,因为 Claude Code CLI 是一个 npm 包。用 node --version 确认。
一把 Anthropic API 密钥,您可在 Claude Console 生成。
继续之前,先快速做一次健全性检查,确认 Docker 本身工作正常:
docker run --rm hello-world技术支持
如果看到 Hello from Docker!,说明守护进程响应正常,可以继续。
认证与环境变量
确认守护进程健康后,下一个关键是凭证。将 Anthropic API 密钥作为运行时环境变量注入,比在容器内交互式登录安全得多。
我就是吃了这方面的亏:交互式登录可能把凭证写进容器层或 shell 历史文件里,长久保留在磁盘上,等您忘了它们还在。
正确的做法是在运行时用 -e 传入密钥:
docker run --rm -e ANTHROPIC_API_KEY = "$ANTHROPIC_API_KEY " my-claude-image技术支持
注意这里从宿主 shell 引用了 $ANTHROPIC_API_KEY。密钥既不会写进 Dockerfile,也不会被提交到版本控制,更不会出现在任何镜像层中。您只需在 shell 配置(~/.zshrc 或 ~/.bashrc)里设置一次,之后它就会在每次容器运行时自动传入。
工作区初始化
认证搞定后,最后一步是创建干净的工作区。我总会为每次代理会话单独建一个目录,而不是直接指向现有项目,这能避免代理“走神”到您并不打算让它修改的临近代码中。
mkdir ~/claude-docker-tutorial
cd ~/claude-docker-tutorial
echo "# My Project" > README.md
echo "def hello(): return 'world'" > app.py技术支持
保持此目录干净。不要把真实的 .env 或任何凭证拷进去。工作区应只包含您希望代理处理的代码,别的都不要。准备就绪后,我们开始构建。
在 Docker 中运行 Claude Code
环境与概念都已就绪,现在开始构建。本节将带您依次完成:先是最小单容器镜像,然后是一个可用的沙箱会话,最后是完整的多服务 Compose 栈。各步骤相互递进,建议按顺序进行,而非直接跳到后面。
1. 构建基线容器镜像
本节一切都建立在我们先前讨论的安全原则之上。下面这个最小 Dockerfile 将这些原则付诸实践:在精简的 Node.js 基础镜像上安装 Claude Code CLI。
FROM node:20-slim
RUN useradd -m -u 1001 claude
RUN npm install -g @anthropic-ai/claude-code
WORKDIR /workspace
USER claude
ENTRYPOINT ["claude" ]技术支持
这里有几点设计取舍值得说明。我使用 node:20-slim 而非 node:20-alpine,因为 Alpine 采用 musl libc,偶尔会与原生 npm 包产生兼容性问题。
我在第一次用 Alpine 时就踩了这个坑:Claude Code CLI 能装上,但首次运行就以一个莫名其妙的链接器错误崩溃,我花了一个小时才追溯到 musl。
slim 变体基于 Debian:轻量、可靠,不会有这些幺蛾子。此外,我创建了专用的 claude 用户并在入口前切换到它,这样代理进程就不会以 root 权限运行,即便在容器内也能限制其能力范围。
用如下命令构建镜像:
docker build -t claude-code:latest . 技术支持
首次构建时,Docker 会拉取基础镜像并安装 CLI。之后只要 Dockerfile 未变,您会在每层旁看到“CACHED”,一旦基线构建完成,重建几乎是瞬时的。
2. 启动隔离的沙箱会话
镜像就位后,开始第一次真正的会话。
只读操作
对于列出或总结文件等只读任务,基础命令足够:
docker run --rm \
-e ANTHROPIC_API_KEY = "$ANTHROPIC_API_KEY " \
-v $( pwd ) :/workspace \
claude-code:latest \
"List the files in this workspace and describe what each one does." 技术支持
-v $(pwd):/workspace 将当前目录挂载进容器,因此该命令可在任一项目目录中运行。--rm 会在容器退出后自动删除它。
写入操作
写入操作需要另外两个参数。
-u $(id -u):$(id -g) 会把宿主用户的 UID 和 GID 传入容器,赋予 claude 进程写入您挂载文件的权限。没有它,您会遇到只读文件系统错误,因为容器内的 claude 用户与宿主文件所有权不匹配。
--dangerously-skip-permissions 会跳过 Claude Code 的交互式审批提示,而在容器内非交互运行时这是必要的。正是 Docker 的边界让这一行为是安全的。
docker run --rm \
-e ANTHROPIC_API_KEY = "$ANTHROPIC_API_KEY " \
-v $( pwd ) :/workspace \
-u $( id -u ) : $( id -g ) \
claude-code:latest \
--dangerously-skip-permissions \
"Add a docstring to the hello function in app.py." 技术支持
Claude Code 在 Docker 中的写入操作
随后检查本地文件:cat app.py。如果您看到了文档字符串,说明卷挂载已双向生效,可以升级到多服务设置。
3. 编排多服务应用
单容器沙箱适合独立任务,但真实开发往往涉及多服务同时运行。这正是 Docker Compose 大显身手之处。
下面的配置将 Claude Code 代理与一个 Web 服务和 PostgreSQL 数据库联通,是很多后端项目的典型组合:
services :
claude :
build : .
environment :
- ANTHROPIC_API_KEY=${ ANTHROPIC_API_KEY}
volumes :
- ./workspace: /workspace
depends_on :
db :
condition : service_healthy
networks :
- app- network
web :
image : python: 3.12- slim
working_dir : /app
volumes :
- ./workspace: /app
command : python - m http.server 8080
ports :
- "8080:8080"
networks :
- app- network
db :
image : postgres: 16- alpine
environment :
POSTGRES_DB : appdb
POSTGRES_USER : user
POSTGRES_PASSWORD : password
healthcheck :
test : [ "CMD-SHELL" , "pg_isready -U user -d appdb" ]
interval : 5s
timeout : 3s
retries : 5
networks :
- app- network
networks :
app-network :
driver : bridge技术支持
注意这里省略了 version,因为在现代 Docker Compose 中它已过时,包含它反而会触发警告。
还有两点值得指出:
首先,claude 服务挂载的是 .:/workspace(当前目录),不是子目录。若使用 ./workspace,就需要单独的子文件夹存在,否则代理会看到空工作区。
其次,需要显式传入 DATABASE_URL,这样代理才知道如何连接 Postgres。没有它,Claude 没有连接串,会向您索要。
user: "${UID}:${GID}" 这行与我们在独立 docker run 命令中用到的宿主 UID/GID 覆盖相同,确保文件写入正常。在运行前先导出二者:
export UID = $( id -u ) GID = $( id -g ) 技术支持
claude 服务没有持久性的 command,因此不同于 web 与 db,它并不打算常驻运行。先启动支撑服务,再通过 docker compose run 按需调用 Claude:
docker compose up -d web db
docker compose run --rm \
claude \
--dangerously-skip-permissions \
"Check the database connection and summarize the schema in README.md." 技术支持
使用 Docker Compose 的 Claude Code
先用 docker compose up -d web db 启动支撑服务,再用 docker compose logs -f 观察日志。留意带有 condition: service_healthy 的 depends_on。
我在早期一个项目中没加健康检查,结果花了 20 分钟追查数据库连接错误,最后才发现 Claude 先于 Postgres 就绪而启动。健康检查几乎没成本,却能省去这种麻烦。
4. 管理会话清理
会话完成后,清理与初始设置同样重要。孤立容器会占用内存并干扰后续运行。以我的经验,这一步往往被开发者忽视,直到出现异常行为。
以下是最常用的命令,以及各自的使用场景:
命令
作用
使用时机
docker compose down
停止并移除栈中的所有容器
每次 Compose 会话结束后
docker container prune
移除所有已停止的容器
如果独立运行时忘了加 --rm
docker compose down -v
移除容器、网络和命名卷
完全重置,清空数据库状态
docker ps
列出正在运行的容器
确认没有残留活动
需要注意的是 docker compose down 的 -v 标志。它会删除命名卷,意味着在 Postgres 中累积的任何数据库数据都会丢失。只有在我确实需要从零开始时才会使用它。其他情况下,仅 docker compose down 就足够了。
Claude Code 与 Docker 的集成与故障排查
在核心工作流稳定运行后,接下来看看如何扩展它,以及在出问题时如何调试。
集成本地模型与扩展
Claude Code 支持通过 ANTHROPIC_BASE_URL 将推理重定向到任意与 Anthropic 兼容的本地端点。内置于 Docker Desktop 的 Docker Model Runner 正好暴露了这样的 API,使集成天然契合 Docker 生态。
拉取模型并将 Claude Code 指向本地端点:
docker model pull ai/smollm2
ANTHROPIC_BASE_URL = http://localhost:12434 claude --model ai/smollm2 "List the files of the repository." 技术支持
这和前面介绍的沙箱容器方法不同。此处,Claude Code 在您的宿主机上运行,推理通过 Docker Model Runner 留在本地,因此不会有 API 调用离开您的机器。
除了本地模型,您还可以通过 MCP(模型上下文协议)服务器 扩展 Claude Code 的能力。如果您还不熟悉,参阅我们的MCP 指南 是很好的起点。
Docker 的 MCP Toolkit 提供 200 多个预构建、容器化的 MCP 服务器,涵盖 GitHub、Jira、Supabase 等,让 Claude Code 在不暴露原始 API 凭证的前提下,获得对这些工具的受控访问。
二者结合,让您既能控制推理发生在何处,也能控制代理可访问哪些外部服务。
优化构建性能
随着 Dockerfile 体量增长,构建时间可能成为瓶颈。多阶段构建通过将安装与运行时镜像分离来解决这个问题:
FROM node:20-slim AS builder
RUN npm install -g @anthropic-ai/claude-code
FROM node:20-slim
COPY --from = builder /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from = builder /usr/local/bin/claude /usr/local/bin/claude
RUN useradd -m -u 1001 claude
USER claude
WORKDIR /workspace
ENTRYPOINT ["claude" ]技术支持
层的顺序与结构同样重要,而我在这方面走了不少弯路。
较少变化的指令(如安装系统包)应放在靠上位置;变化频繁的指令(如复制源文件)应放在靠下位置。这样可最大化缓存命中率,把 30 秒的重建压缩到近乎瞬时。
调试常见的集成故障
即便结构良好,也难免出错。以下是我最常遇到问题的可重复调试循环:先描述症状,再给出要运行的命令。
出站网络被阻断: Claude Code 无法访问 Anthropic API。运行 docker run --rm alpine wget -qO- https://api.anthropic.com 验证出站访问。如果失败,检查 docker network inspect bridge 的代理设置。
卷挂载不正确: Claude Code 报告找不到文件。运行 docker run --rm -v $(pwd):/workspace alpine ls /workspace。若列表为空,说明路径错误。先确认目录确实存在。
构建缓存陈旧: 您更新了 Dockerfile,但行为没变化。用 docker build --no-cache -t claude-code:latest . 强制全量重建。
Compose 中的服务间连接失败: 某服务无法访问另一服务。服务之间通过服务名(db、web)通信,而不是 localhost。运行 docker compose exec web ping db 测试可达性。如失败,说明服务不在同一网络。
结语
在 Docker 中运行 Claude Code 带来真正的价值:您可以让自主代理自由工作,同时明确它能接触到的范围被严格限制。
本教程介绍了如何构建最小的非 root 容器镜像、管理工作区卷、用 Docker Compose 编排多服务应用,以及诊断最常见的集成故障。
这套设置我花了一个下午才打磨到位,但它完全改变了我使用代理辅助开发的方式。我现在会委派完整任务,而不是盯着每一步,Docker 的边界让这一切成为可能。
接下来,有两条方向值得探索:
首先,考察适合您团队的 devcontainer 模板。GitHub 上的 Claude Code 参考 devcontainer 内置预配置的防火墙,将出站连接限制在可信域名。其次,试验 Docker MCP Toolkit,为 Claude Code 提供对您现有工具(GitHub、数据库、项目管理系统等)的结构化访问。
最后,记得定期更新基础镜像。Docker 镜像会随时间累积漏洞,执行一次 docker pull node:20-slim 并重建只需几分钟。
如果您对开发 AI 应用感兴 趣,强烈建议报名我们的 AI Engineering with LangChain 技能路径。课程均为 AI 原生,您将获得一位陪伴式导师,根据您的实际水平帮助您以自己的节奏达成目标。
自主型AI 编码代理功能强大。它们可以浏览您的文件系统、执行 shell 命令、提交更改并修改文件,且无需您亲自敲下一行代码。但强大的能力也带来一个现实问题:一旦出错会怎样?万一代理修改了本不该动的配置文件,或安装了与您系统冲突的软件包,该怎么办?
大多数注重生产环境的开发者最终选择 Docker。我自己也在一次特定的会话后不断回到这个答案——当时 Claude Code 很“贴心”地清理了我项目的
.env文件,因为它看起来“未被使用”。(其实它并非未用。)容器在代理与宿主机之间提供了清晰的边界,而这种边界让无人值守的代理运行从焦虑变得踏实。
在本教程中,我将带您在 Docker 中运行 Claude Code:从构建最小基线镜像,到使用Docker Compose编排多服务应用。完成后,您将拥有一套可复用且安全的工作流,可应用于任何项目。
如果您对最新的 Anthropic 模型感兴趣,推荐阅读我们的 Claude Opus 4.6 和 Claude Sonnet 4.6 指南。
Claude Code 如何与 Docker 集成
要理解为什么 Docker 与 Claude Code 天然契合,先简单弄清各自做什么会很有帮助。
Claude Code 是 Anthropic 推出的命令行代理式编码工具,于 2025 年 5 月正式发布。它驻留在您的终端,读取代码库,并通过自然语言提示执行任务(重构、编写测试、管理 git 工作流)。我们的Claude Code 2.1 全面教程涵盖所需的一切。
Docker 是一个用于打包和运行应用的平台,它通过轻量、隔离的容器共享宿主 OS 内核,但保持严格的进程与文件系统边界。如果您对 Docker 完全陌生,建议先在免费的 Play with Docker 平台上试验。
Claude Code 需要一个可运行的环境,Docker 则提供了可复现、一次性的环境。二者结合威力强大,但要用好它们,您需要了解执行模型、安全默认值,以及最适合您场景的部署方式。
容器架构与执行流程
先从请求层面看一次容器化的 Claude Code 会话是如何工作的。
关键在于区分临时状态与持久状态。写入容器但不在挂载卷中的任何内容,清理时都会被删除。您的工作区位于宿主并被挂载进容器,因此会持久化。
这意味着临时依赖、构建产物和工具安装都会消失,但您的项目文件会如同 Claude 留下时那样保持不变。对我来说,这种分离让人安心:在理解这一点之前,我总是紧张地盯着代理会话。现在,我下达任务就去泡咖啡。
安全模型与安全默认
在理解执行流程后,值得明确说明 Docker 的隔离实际能保护什么、不能保护什么。
文件系统隔离是主要的安全收益。Claude Code 只能读写您明确挂载的路径。如果您没有将它们挂载进容器,您的SSH 密钥、
~/.aws凭证、宿主环境变量以及系统配置文件对代理都是不可见的,除非您主动暴露它们。不过,这种保护前提是您谨慎配置挂载。一条关键规则:切勿将宿主的 Docker 套接字(
/var/run/docker.sock)挂载到 Claude Code 容器中。如果代理能与宿主的 Docker 守护进程通信,它就可能启动特权容器、完全逃离沙箱,并获得对您机器的 root 级访问。这是一个众所周知且没有正当理由的提权路径。我在一些社区 Dockerfile 中看到过这种做法,目的是让代理“管理容器”。每次看到我都想给作者发一条措辞强烈的消息。
选择合适的部署路径
抛开安全默认不谈,在写任何代码之前,您还需做一个决定:哪种部署模型适合您的用例?主要有三种选项,彼此并非可互换。
部署方式
最适合
关键取舍
Docker 沙箱(单容器)
隔离的、一次性代理任务
无服务间网络通信
Docker Compose
开发期多服务应用
配置更多,攻击面更广
Devcontainers
团队级标准化环境
需要 VS Code 或兼容 IDE
对于大多数任务(针对单个仓库运行代理、调试脚本、重构模块),纯 Docker 沙箱是最安全的默认选择。
当 Claude Code 需要与正在运行的数据库、API 或前端服务交互时,Docker Compose 就有意义了。
Devcontainers 适用于团队范围的标准化环境,并预装 IDE 扩展。值得注意的是,Anthropic 官方参考 devcontainer 内置防火墙,将出站连接限制在可信白名单内,也正因这种隔离,才能安全地以完全无人值守方式运行带有
--dangerously-skip-permissions的 Claude Code。本教程将同时介绍单容器沙箱和 Compose 设置。
为 Claude Code 准备 Docker 容器
既然架构和部署选项已明确,我们就先确保环境配置妥当再写代码。我见过太多人跳过这一步,而这也是此类教程半途失败的最常见原因。
系统与软件要求
在第一次运行
docker build前,您需要具备以下条件:Docker Desktop(macOS 或 Windows)或 Docker Engine(Linux),且守护进程处于运行状态。macOS 与 Windows 需在 BIOS/固件中启用虚拟化。Linux 上请将您的用户加入
docker组(sudo usermod -aG docker $USER),或在每条 Docker 命令前加sudo。宿主机安装 Node.js v18 或更高版本,因为 Claude Code CLI 是一个 npm 包。用
node --version确认。一把 Anthropic API 密钥,您可在 Claude Console 生成。
继续之前,先快速做一次健全性检查,确认 Docker 本身工作正常:
如果看到
Hello from Docker!,说明守护进程响应正常,可以继续。认证与环境变量
确认守护进程健康后,下一个关键是凭证。将 Anthropic API 密钥作为运行时环境变量注入,比在容器内交互式登录安全得多。
我就是吃了这方面的亏:交互式登录可能把凭证写进容器层或 shell 历史文件里,长久保留在磁盘上,等您忘了它们还在。
正确的做法是在运行时用
-e传入密钥:注意这里从宿主 shell 引用了
$ANTHROPIC_API_KEY。密钥既不会写进 Dockerfile,也不会被提交到版本控制,更不会出现在任何镜像层中。您只需在 shell 配置(~/.zshrc或~/.bashrc)里设置一次,之后它就会在每次容器运行时自动传入。工作区初始化
认证搞定后,最后一步是创建干净的工作区。我总会为每次代理会话单独建一个目录,而不是直接指向现有项目,这能避免代理“走神”到您并不打算让它修改的临近代码中。
保持此目录干净。不要把真实的
.env或任何凭证拷进去。工作区应只包含您希望代理处理的代码,别的都不要。准备就绪后,我们开始构建。在 Docker 中运行 Claude Code
环境与概念都已就绪,现在开始构建。本节将带您依次完成:先是最小单容器镜像,然后是一个可用的沙箱会话,最后是完整的多服务 Compose 栈。各步骤相互递进,建议按顺序进行,而非直接跳到后面。
1. 构建基线容器镜像
本节一切都建立在我们先前讨论的安全原则之上。下面这个最小 Dockerfile 将这些原则付诸实践:在精简的 Node.js 基础镜像上安装 Claude Code CLI。
这里有几点设计取舍值得说明。我使用
node:20-slim而非node:20-alpine,因为 Alpine 采用musllibc,偶尔会与原生 npm 包产生兼容性问题。我在第一次用 Alpine 时就踩了这个坑:Claude Code CLI 能装上,但首次运行就以一个莫名其妙的链接器错误崩溃,我花了一个小时才追溯到 musl。
slim变体基于 Debian:轻量、可靠,不会有这些幺蛾子。此外,我创建了专用的claude用户并在入口前切换到它,这样代理进程就不会以 root 权限运行,即便在容器内也能限制其能力范围。用如下命令构建镜像:
首次构建时,Docker 会拉取基础镜像并安装 CLI。之后只要 Dockerfile 未变,您会在每层旁看到“CACHED”,一旦基线构建完成,重建几乎是瞬时的。
2. 启动隔离的沙箱会话
镜像就位后,开始第一次真正的会话。
只读操作
对于列出或总结文件等只读任务,基础命令足够:
-v $(pwd):/workspace将当前目录挂载进容器,因此该命令可在任一项目目录中运行。--rm会在容器退出后自动删除它。写入操作
写入操作需要另外两个参数。
-u $(id -u):$(id -g)会把宿主用户的 UID 和 GID 传入容器,赋予claude进程写入您挂载文件的权限。没有它,您会遇到只读文件系统错误,因为容器内的claude用户与宿主文件所有权不匹配。--dangerously-skip-permissions会跳过 Claude Code 的交互式审批提示,而在容器内非交互运行时这是必要的。正是 Docker 的边界让这一行为是安全的。Claude Code 在 Docker 中的写入操作
随后检查本地文件:
cat app.py。如果您看到了文档字符串,说明卷挂载已双向生效,可以升级到多服务设置。3. 编排多服务应用
单容器沙箱适合独立任务,但真实开发往往涉及多服务同时运行。这正是 Docker Compose 大显身手之处。
下面的配置将 Claude Code 代理与一个 Web 服务和 PostgreSQL 数据库联通,是很多后端项目的典型组合:
注意这里省略了
version,因为在现代 Docker Compose 中它已过时,包含它反而会触发警告。还有两点值得指出:
首先,
claude服务挂载的是.:/workspace(当前目录),不是子目录。若使用./workspace,就需要单独的子文件夹存在,否则代理会看到空工作区。其次,需要显式传入
DATABASE_URL,这样代理才知道如何连接 Postgres。没有它,Claude 没有连接串,会向您索要。user: "${UID}:${GID}"这行与我们在独立docker run命令中用到的宿主 UID/GID 覆盖相同,确保文件写入正常。在运行前先导出二者:claude服务没有持久性的command,因此不同于web与db,它并不打算常驻运行。先启动支撑服务,再通过docker compose run按需调用 Claude:使用 Docker Compose 的 Claude Code
先用
docker compose up -d web db启动支撑服务,再用docker compose logs -f观察日志。留意带有condition: service_healthy的depends_on。我在早期一个项目中没加健康检查,结果花了 20 分钟追查数据库连接错误,最后才发现 Claude 先于 Postgres 就绪而启动。健康检查几乎没成本,却能省去这种麻烦。
4. 管理会话清理
会话完成后,清理与初始设置同样重要。孤立容器会占用内存并干扰后续运行。以我的经验,这一步往往被开发者忽视,直到出现异常行为。
以下是最常用的命令,以及各自的使用场景:
命令
作用
使用时机
docker compose down停止并移除栈中的所有容器
每次 Compose 会话结束后
docker container prune移除所有已停止的容器
如果独立运行时忘了加 --rm
docker compose down -v移除容器、网络和命名卷
完全重置,清空数据库状态
docker ps列出正在运行的容器
确认没有残留活动
需要注意的是
docker compose down的-v标志。它会删除命名卷,意味着在 Postgres 中累积的任何数据库数据都会丢失。只有在我确实需要从零开始时才会使用它。其他情况下,仅docker compose down就足够了。Claude Code 与 Docker 的集成与故障排查
在核心工作流稳定运行后,接下来看看如何扩展它,以及在出问题时如何调试。
集成本地模型与扩展
Claude Code 支持通过
ANTHROPIC_BASE_URL将推理重定向到任意与 Anthropic 兼容的本地端点。内置于 Docker Desktop 的 Docker Model Runner 正好暴露了这样的 API,使集成天然契合 Docker 生态。拉取模型并将 Claude Code 指向本地端点:
这和前面介绍的沙箱容器方法不同。此处,Claude Code 在您的宿主机上运行,推理通过 Docker Model Runner 留在本地,因此不会有 API 调用离开您的机器。
除了本地模型,您还可以通过 MCP(模型上下文协议)服务器扩展 Claude Code 的能力。如果您还不熟悉,参阅我们的MCP 指南是很好的起点。
Docker 的 MCP Toolkit 提供 200 多个预构建、容器化的 MCP 服务器,涵盖 GitHub、Jira、Supabase 等,让 Claude Code 在不暴露原始 API 凭证的前提下,获得对这些工具的受控访问。
二者结合,让您既能控制推理发生在何处,也能控制代理可访问哪些外部服务。
优化构建性能
随着 Dockerfile 体量增长,构建时间可能成为瓶颈。多阶段构建通过将安装与运行时镜像分离来解决这个问题:
层的顺序与结构同样重要,而我在这方面走了不少弯路。
较少变化的指令(如安装系统包)应放在靠上位置;变化频繁的指令(如复制源文件)应放在靠下位置。这样可最大化缓存命中率,把 30 秒的重建压缩到近乎瞬时。
调试常见的集成故障
即便结构良好,也难免出错。以下是我最常遇到问题的可重复调试循环:先描述症状,再给出要运行的命令。
出站网络被阻断:Claude Code 无法访问 Anthropic API。运行
docker run --rm alpine wget -qO- https://api.anthropic.com验证出站访问。如果失败,检查docker network inspect bridge的代理设置。卷挂载不正确:Claude Code 报告找不到文件。运行
docker run --rm -v $(pwd):/workspace alpine ls /workspace。若列表为空,说明路径错误。先确认目录确实存在。构建缓存陈旧:您更新了 Dockerfile,但行为没变化。用
docker build --no-cache -t claude-code:latest .强制全量重建。Compose 中的服务间连接失败:某服务无法访问另一服务。服务之间通过服务名(
db、web)通信,而不是localhost。运行docker compose exec web ping db测试可达性。如失败,说明服务不在同一网络。结语
在 Docker 中运行 Claude Code 带来真正的价值:您可以让自主代理自由工作,同时明确它能接触到的范围被严格限制。
本教程介绍了如何构建最小的非 root 容器镜像、管理工作区卷、用 Docker Compose 编排多服务应用,以及诊断最常见的集成故障。
这套设置我花了一个下午才打磨到位,但它完全改变了我使用代理辅助开发的方式。我现在会委派完整任务,而不是盯着每一步,Docker 的边界让这一切成为可能。
接下来,有两条方向值得探索:
首先,考察适合您团队的 devcontainer 模板。GitHub 上的Claude Code 参考 devcontainer 内置预配置的防火墙,将出站连接限制在可信域名。其次,试验 Docker MCP Toolkit,为 Claude Code 提供对您现有工具(GitHub、数据库、项目管理系统等)的结构化访问。
最后,记得定期更新基础镜像。Docker 镜像会随时间累积漏洞,执行一次
docker pull node:20-slim并重建只需几分钟。如果您对开发 AI 应用感兴趣,强烈建议报名我们的 AI Engineering with LangChain 技能路径。课程均为 AI 原生,您将获得一位陪伴式导师,根据您的实际水平帮助您以自己的节奏达成目标。