Skip to content

fix(docker): 容器路径别把 .env 挂进工作区(#50) - #51

Merged
LouisDM merged 1 commit into
mainfrom
fix/issue-50
Aug 12, 2026
Merged

fix(docker): 容器路径别把 .env 挂进工作区(#50)#51
LouisDM merged 1 commit into
mainfrom
fix/issue-50

Conversation

@LouisDM

@LouisDM LouisDM commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Closes #50

问题

容器那条路和 #46 修的宿主机那条同族,但更重,而且踩在 happy path 上。

docker/entrypoint.sh 生成的是 sandbox_mode = "danger-full-access"exec 模式还额外带 --dangerously-bypass-approvals-and-sandbox(Codex 的 Landlock/seccomp 在多数容器运行时下初始化失败,所以把容器本身当隔离边界)。这个取舍成立的前提是「挂进来的只有该看的工作区」。

而文档教的是 -v "$PWD:/workspace",紧跟在 lc init 把凭证写进那个目录的 .env 之后。离线部署指南第 4 节尤其明显:内网侧刚在解包目录里跑完 lc init$PWD 就是那个目录。照文档一步步走必然踩中,不是「用户手贱在工具目录里干活」。

叠加两点:

改了什么

姿态与 #46 保持一致:警告 + 文档,不阻断

文件 改动
docker/entrypoint.sh 生成配置后、exec codex 前检测 $PWD/.env,往 stderr 打警告
README.md / README.zh-CN.md / docs/offline-deployment.md / docker/Dockerfile 4 处 -v "$PWD:/workspace"-v "/path/to/your-project:/workspace",紧邻位置说明原因
docs/threat-model.md 容器路径并进「Credentials in the Codex workspace」一节,修正原来「容器路径这个分离已经成立」那句
scripts/test-entrypoint.sh 新增 4 条断言
scripts/test-project-metadata.py 文档/Dockerfile 不得再出现把当前目录挂进 /workspace 的写法

几个实现选择:

  • 判据用 $PWD/.env 而不是写死 /workspace,这样 -w 换过工作目录也成立。
  • 只报路径,不读文件、不打印任何值(有一条断言钉住这点)。
  • 检查放在必需变量校验之后,所以 --version / --help 的透传分支不会响。
  • 不阻断的理由同 bin/lcwarn_env_in_workspace():在这个目录里用 Codex 审查 airgap-coder 自己是正当用法,且这会是个破坏性变更。

断言覆盖(合并前自查)

新行为都有断言钉住,两个脚本 ci.ymlrelease.yml 都已经在调,不需要动 .github/

scripts/test-entrypoint.sh

  1. 工作区有 .env → stderr 出现警告并指出路径
  2. 警告里说明了权限级别(danger-full-access
  3. 警告不含 .env 里的值
  4. 照常执行 codex,argv 与无警告时逐字相同(不阻断)
  5. 工作区无 .env出现警告(防「永远都响的警告」)

scripts/test-project-metadata.py:文档与 Dockerfile 里不得出现 -v "$PWD:/workspace" 这类写法。

怎么验证的

变异测试确认断言真的会红,不是走过场:

变异 结果
去掉 entrypoint 里的检查(if false .env in the workspace did not produce a warning
检查改成恒真(if true workspace warning fired without a .env in the workspace
README 挂载改回 $PWD README.md mounts the current directory into the container workspace

本地全绿:py_compile / bash -n / test-project-metadata.py / test-entrypoint.sh / test-version.sh / test-lc-secrets.sh,以及 lc sync 生成器冒烟(跑完已删除生成物,git status 干净,无 .env)。

真实容器行为以 CI 的 docker job 为准。

未做

#50 的指示,没有动「把 .env 搬出仓库」——那是独立的架构决策,实现完这条之后单独开 issue 写取舍。

🤖 Generated with Claude Code

容器里 Codex 是 danger-full-access(exec 还额外带
--dangerously-bypass-approvals-and-sandbox),前提是「挂进来的只有该看的
工作区」。而文档教的是 `-v "$PWD:/workspace"`,紧跟在 `lc init` 把凭证写进
那个目录的 .env 之后——照 README / 离线部署指南一步步走必然踩中,不是假想
场景。entrypoint 特意只注入 LITELLM_MASTER_KEY(#42),挂载把整份 .env 又
送了回来;#46 给 `lc code` 加的警告在这条路上结构上不可能触发,因为容器
根本不跑 lc。

- docker/entrypoint.sh:生成配置后检测 $PWD/.env,往 stderr 打一行警告说清
  权限级别和怎么避开,只报路径不读文件。与 #46 一致:警告,不阻断。
- README / README.zh-CN / docs/offline-deployment.md / docker/Dockerfile:
  4 处 `-v "$PWD:/workspace"` 改成明确的项目目录,并在紧邻位置说明原因。
- docs/threat-model.md:把容器路径并进「Credentials in the Codex workspace」
  一节(两条路径同一个暴露面),并修正原来「容器路径这个分离已经成立」的
  说法——挂载的就是工具目录时它不成立。
- scripts/test-entrypoint.sh:有 .env 时警告且照常执行 codex、没有时不警告、
  不打印 .env 里的值。
- scripts/test-project-metadata.py:文档与 Dockerfile 不得再出现把当前目录
  挂进 /workspace 的写法。

两条断言都做过变异验证(去掉检查 / 改成恒真,各自都会红)。

Closes #50

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

容器那条路也把 .env 挂进了工作区:README 教的 -v "$PWD:/workspace" 紧跟在 cd airgap-coder 后面,而容器里是 danger-full-access

1 participant