欢迎光临
我们一直在努力

用 Docker 隔离运行 Codex:从镜像构建到项目挂载的完整实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

最近我在本地使用 Codex 做项目开发时,遇到一个很现实的问题:Codex 很适合读取代码、修改文件、运行测试,但如果直接在宿主机上跑,它能接触到的环境就和我的日常开发环境绑定在一起。对于一些临时项目、第三方项目、实验性依赖,最好还是把 Codex 放到一个隔离环境中运行。

这篇文章记录一种实践方案:用 Docker 创建一个专门运行 Codex CLI 的容器,把项目目录挂载进去,让 Codex 只在容器和指定项目目录里工作。这样既能保留 Codex 的自动化开发能力,也能降低它对宿主机环境的影响。

1. 为什么要把 Codex 放进 Docker?

OpenAI 官方文档中,Codex CLI 被定义为可以在本地终端运行的 coding agent。它可以读取、修改当前目录中的代码,也可以运行命令来完成开发任务。

这正是 Codex 好用的地方,但也意味着我们需要认真设计运行边界:

  • 不希望 Codex 看到整个宿主机目录;
  • 不希望项目依赖污染本机环境;
  • 不希望一次实验把本机 Node、Python、JDK 等版本搞乱;
  • 希望每个项目有独立、可重建、可删除的运行环境;
  • 希望出现问题时直接删除容器即可恢复干净状态。

因此,一个比较稳妥的方案是:宿主机只负责保存代码,Docker 容器负责运行 Codex 和项目依赖。

整体结构如下:

宿主机
├── /path/to/my-project # 真实项目代码
└── Docker
└── codex-runner 容器
├── /workspace # 挂载宿主机项目目录
├── codex CLI # 容器内安装
├── node/python/git # 容器内工具链
└── ~/.codex # Codex 配置和登录缓存,可选择挂载或容器内维护

2. 基本思路

这个方案分成四步:

  • 写一个 Dockerfile,安装基础工具和 Codex CLI;
  • 构建一个 codex-runner 镜像;
  • 启动容器时只挂载当前项目到 /workspace;
  • 在容器里运行 codex,让 Codex 在 /workspace 内完成开发任务。
  • 这里的重点不是“让 Docker 变复杂”,而是把边界控制清楚:Codex 只看到你挂载进去的目录和容器内环境。

    3. 准备目录

    先创建一个 Docker runner 目录:

    mkdir -p codex-docker-runner
    cd codex-docker-runner

    目录结构建议如下:

    codex-docker-runner
    ├── Dockerfile
    ├── docker-compose.yml
    └── codex-home/ # 可选:用于持久化 Codex 配置,不要提交到 Git

    注意:codex-home/ 里可能会出现登录缓存或配置文件,建议加入 .gitignore。

    echo "codex-home/" >> .gitignore

    4. 编写 Dockerfile

    下面是一个适合日常使用的基础镜像。这里使用 Ubuntu 24.04,安装常见开发工具、Node.js 22、Python、Git,然后用 npm 安装 Codex CLI。

    FROM ubuntu:24.04

    ARG DEBIAN_FRONTEND=noninteractive

    RUN apt-get update && apt-get install -y –no-install-recommends \\
    ca-certificates \\
    curl \\
    git \\
    bash \\
    sudo \\
    python3 \\
    python3-pip \\
    python3-venv \\
    build-essential \\
    ripgrep \\
    jq \\
    vim \\
    less \\
    bubblewrap \\
    && rm -rf /var/lib/apt/lists/*

    # 安装 Node.js 22。Codex CLI 也可以用官方 standalone installer 安装,
    # 这里选择 npm 方式,便于在 Dockerfile 中管理版本。
    RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash – \\
    && apt-get update \\
    && apt-get install -y –no-install-recommends nodejs \\
    && npm install -g @openai/codex \\
    && npm cache clean –force \\
    && rm -rf /var/lib/apt/lists/*

    # 创建非 root 用户,避免容器内所有文件都变成 root 生成。
    RUN useradd -m -s /bin/bash codex \\
    && echo "codex ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/codex \\
    && chmod 0440 /etc/sudoers.d/codex

    USER codex
    WORKDIR /workspace

    ENV CODEX_HOME=/home/codex/.codex

    CMD ["bash"]

    构建镜像:

    docker build -t local/codex-runner:latest .

    验证 Codex 是否安装成功:

    docker run –rm local/codex-runner:latest codex –version

    5. 用 Docker Compose 挂载项目

    假设你的项目在宿主机:

    /Users/you/projects/demo-app

    可以写一个 docker-compose.yml:

    services:
    codex-runner:
    image: local/codex–runner:latest
    container_name: codex–runner–demo
    working_dir: /workspace
    tty: true
    stdin_open: true
    volumes:
    # 只把当前项目挂载给 Codex
    – /Users/you/projects/demo–app:/workspace

    # 可选:持久化 Codex 配置和登录状态
    # 注意不要把 codex-home 提交到 Git
    – ./codex–home:/home/codex/.codex
    environment:
    – TERM=xterm–256color

    启动容器:

    docker compose run –rm codex-runner

    进入容器后确认目录:

    pwd
    ls
    codex –version

    然后直接运行:

    codex

    这样 Codex 就会在 /workspace 下工作,而 /workspace 对应的就是你明确挂载进去的项目。

    6. 登录 Codex

    Codex CLI 支持 ChatGPT 登录和 API key 登录两种方式。官方文档也说明:CLI 和 IDE extension 都支持这两种登录方式,首次运行 codex 时会引导登录。

    在 Docker 里有三种常见做法:

    方式一:容器内直接登录

    适合有交互终端的情况:

    codex login

    如果浏览器回调不方便,可以尝试设备码方式:

    codex login –device-auth

    然后根据终端提示,在宿主机浏览器里完成授权。

    方式二:挂载 CODEX_HOME

    也就是上面 compose 文件里的这一行:

    – ./codex–home:/home/codex/.codex

    好处是容器删除后,Codex 登录状态和配置仍然保留在 codex-home/ 目录。坏处是这里可能包含敏感凭据,所以一定不要提交到 Git,也不要随意分享。

    方式三:自动化环境使用 API key 或 access token

    如果是 CI、私有服务器、自动化脚本,建议优先使用更适合自动化的认证方式,并做好密钥管理。不要把 API key 写进 Dockerfile,也不要把密钥硬编码进镜像。

    推荐通过运行时环境变量或 secret 注入,例如:

    docker run –rm -it \\
    -v "$PWD":/workspace \\
    -w /workspace \\
    -e OPENAI_API_KEY \\
    local/codex-runner:latest \\
    codex

    实际使用时,以你当前 Codex 版本支持的登录方式为准。

    7. 在容器里运行 Codex 的权限策略

    Codex 本身也有 sandbox 和 approval 机制。官方文档里把 sandbox 解释为 Codex 自动执行命令时的边界;approval policy 则决定什么时候需要停下来让用户确认。

    常见模式包括:

    # 默认更适合日常开发:可写 workspace,需要越界时询问
    codex –sandbox workspace-write –ask-for-approval on-request

    # 更谨慎:只读分析,不主动修改
    codex –sandbox read-only –ask-for-approval on-request

    但是要特别注意:在 Docker 这种容器化 Linux 环境里,如果宿主机或容器配置限制了 namespace、setuid、bwrap 或 seccomp,Codex 内层 Linux sandbox 可能无法正常工作。官方安全文档也提到:这种情况下可以把 Docker 容器作为外层隔离边界,然后在容器内使用:

    codex –sandbox danger-full-access

    我的建议是:

    • 如果容器支持 bubblewrap,优先保留 Codex 自身 sandbox;
    • 如果容器就是你的安全边界,才考虑在容器里使用 danger-full-access;
    • 使用 danger-full-access 时,务必只挂载当前项目,不要挂载整个 home 目录;
    • 不要把 SSH key、云厂商密钥、生产配置等敏感文件挂进容器。

    8. 一条命令启动某个项目的 Codex 容器

    日常使用时,我更喜欢写一个脚本,比如 run-codex.sh:

    #!/usr/bin/env bash
    set -euo pipefail

    PROJECT_DIR="${1:-$PWD}"
    CONTAINER_NAME="codex-runner-$(basename "$PROJECT_DIR")"

    docker run –rm -it \\
    –name "$CONTAINER_NAME" \\
    -v "$PROJECT_DIR":/workspace \\
    -v "$HOME/.codex-docker-home":/home/codex/.codex \\
    -w /workspace \\
    local/codex-runner:latest \\
    codex –sandbox workspace-write –ask-for-approval on-request

    使用:

    chmod +x run-codex.sh
    ./run-codex.sh /path/to/your-project

    如果内层 sandbox 因 Docker 限制无法使用,可以改成:

    codex –sandbox danger-full-access

    但前提还是那句话:确保 Docker 挂载范围足够小。

    9. 如何让 Codex 帮你创建这个 Docker?

    其实可以直接把需求交给 Codex,例如:

    请帮我创建一个 Docker runner,用于隔离运行 Codex CLI。
    要求:
    1. 基于 Ubuntu 24.04;
    2. 安装 Node.js 22、Git、Python、ripgrep、bubblewrap;
    3. 安装 @openai/codex;
    4. 创建非 root 用户 codex;
    5. 只把当前项目挂载到 /workspace;
    6. 提供 docker-compose.yml 和 run-codex.sh;
    7. 不要把任何密钥写入镜像。

    Codex 很适合生成这些工程化文件,然后你再 review Dockerfile、compose、脚本和权限配置。

    10. 安全注意事项

    最后总结几个我认为最重要的点:

  • 不要挂载整个 home 目录。 只挂载项目目录和必要的 Codex 配置目录。
  • 不要把密钥写进 Dockerfile。 镜像可能会被缓存、分发、上传。
  • 不要把 ~/.codex/auth.json 提交到 Git。 如果使用文件方式缓存登录状态,它就是敏感文件。
  • 不信任的项目尽量只读。 先用 read-only 让 Codex 分析,再决定是否给写权限。
  • 容器不是万能安全边界。 如果你在容器里挂载了 Docker socket、SSH key、云凭据,那么隔离意义会大幅下降。
  • 网络权限要尽量收敛。 如果项目不需要联网,就不要给容器随意访问外网的能力。
  • 11. 总结

    把 Codex 放进 Docker,本质上是在 Codex 自身 sandbox 之外,再加一层项目级隔离:

    • Codex 负责理解代码、修改代码、运行测试;
    • Docker 负责隔离工具链、依赖和文件系统边界;
    • 宿主机只暴露明确挂载的项目目录;
    • 出问题时删除容器即可恢复干净状态。

    这套方案特别适合:多项目开发、临时实验、第三方代码分析、CI/自动化任务,以及不希望污染宿主机环境的场景。

    如果只是个人日常开发,可以从最简单的 Dockerfile + docker run -v 当前项目:/workspace 开始;等流程稳定后,再补充 compose、脚本、网络限制和凭据管理。

    参考资料

    • OpenAI Codex CLI 文档:https://developers.openai.com/codex/cli
    • Codex sandboxing 文档:https://developers.openai.com/codex/concepts/sandboxing
    • Codex authentication 文档:https://developers.openai.com/codex/auth
    • Codex approvals & security 文档:https://developers.openai.com/codex/agent-approvals-security
    • OpenAI Codex GitHub 仓库:https://github.com/openai/codex
    赞(0)
    未经允许不得转载:171主机测评 » 用 Docker 隔离运行 Codex:从镜像构建到项目挂载的完整实践
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址