Codex 沙箱中 Bun、Bunx 与 uv 的环境和权限排障

2026-09-16

常见现象

在 Codex 沙箱中使用 Bun 和 uv 时,可能遇到以下错误:

bun: command not found
bunx: command not found
error: Could not acquire lock
Caused by: Read-only file system at /root/.cache/uv/...
error: EROFS accessing temporary directory.
Please set $BUN_TMPDIR or $BUN_INSTALL

访问 npm Registry 时还可能出现:

error: GET https://registry.npmjs.org/... - 403
Network access to "registry.npmjs.org" was blocked:
local/private network addresses are blocked by the sandbox policy.

这些错误分别涉及 Shell 初始化、文件系统沙箱和网络沙箱,应当分层排查。

一、Bun 和 Bunx 已安装,但命令无法解析

首先确认命令是否在 PATH 中:

command -v bun
command -v bunx
command -v uv

如果 Bun 安装在以下默认位置,但 command -v 没有输出:

/root/.bun/bin/bun
/root/.bun/bin/bunx

应检查 Bun 的环境配置是否只写在 ~/.bashrc 中。许多 .bashrc 文件包含如下判断:

[ -z "$PS1" ] && return

Codex 通常通过非交互 Shell 执行命令,因此 .bashrc 可能在加载 Bun 配置前提前返回。

将 Bun 配置加入 ~/.profile

export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"

使用全新的登录 Shell 验证:

bash -lc 'command -v bun'
bash -lc 'command -v bunx'
bash -lc 'bun --version'

修改环境配置后,应重启 Codex 客户端并新建任务。已经启动的任务通常不会动态刷新进程环境。

二、uv 可执行,但默认缓存不可写

下面的命令只验证 uv 二进制是否可用:

uv --version

一些 uv 子命令还需要在默认缓存目录中创建锁文件或临时文件:

/root/.cache/uv

如果该目录未被 Codex 沙箱授予写权限,就会出现 Read-only file system

临时解决方法是把缓存重定向到 /tmp

UV_CACHE_DIR=/tmp/uv-cache uv python find

如果希望保留默认缓存位置,应通过 Codex 权限 profile 精确开放该目录。

三、创建开发工具缓存权限 Profile

编辑 ~/.codex/config.toml,定义一个继承自 :workspace 的自定义 profile:

default_permissions = "workspace-with-dev-caches"

[permissions.workspace-with-dev-caches]
extends = ":workspace"

[permissions.workspace-with-dev-caches.filesystem]
"/root/.cache/uv" = "write"

这样可以保留工作区沙箱的默认保护,只增加指定缓存目录的写权限。

配置完成后执行严格校验:

codex --strict-config --version

四、Bunx 报 EROFS 不一定是临时目录问题

bunx 报告以下错误时:

EROFS accessing temporary directory

不要直接假设 /tmp 不可写。Bun 运行一次性包时还会使用全局包缓存:

/root/.bun/install/cache

可以通过临时重定向确认问题:

mkdir -p /tmp/bun-cache /tmp/bun-tmp

BUN_INSTALL_CACHE_DIR=/tmp/bun-cache \
BUN_TMPDIR=/tmp/bun-tmp \
bunx some-cli@latest --version

如果 EROFS 消失,说明真正缺少写权限的是 Bun 全局缓存。将其加入同一个权限 profile:

[permissions.workspace-with-dev-caches.filesystem]
"/root/.cache/uv" = "write"
"/root/.bun/install/cache" = "write"

不建议直接开放 /root/.bun/root/.cache 或整个用户目录。

五、为包管理器配置域名白名单

当缓存可写后,bunx package@latest 还需要访问包注册表。可以启用 Codex 网络代理并设置精确的域名白名单:

[features]
network_proxy = true

[permissions.workspace-with-dev-caches.network]
enabled = true

[permissions.workspace-with-dev-caches.network.domains]
"registry.npmjs.org" = "allow"

如果所使用的工具还需要访问自己的官方下载或元数据服务,应单独添加经过确认的域名,而不是使用 "*" = "allow"

六、域名已允许,但仍被私网保护拦截

部分代理、容器或企业 DNS 环境会把公共域名解析到本地或私有地址。此时即使域名已加入白名单,Codex 仍可能返回:

local/private network addresses are blocked by the sandbox policy

这是 Codex 用于防止 DNS 重绑定和意外访问本地服务的保护机制。

如果已确认白名单域名可信,并且当前网络环境确实需要这种解析方式,可以启用:

[permissions.workspace-with-dev-caches.network]
enabled = true
allow_local_binding = true

该选项允许白名单域名连接其解析得到的本地或私有地址,但域名白名单仍然有效。由于它放宽了私网保护,只应与精确的域名白名单一起使用。

完整配置示例

下面是一份同时支持 uv 缓存、Bun 缓存和 npm Registry 的配置:

default_permissions = "workspace-with-dev-caches"

[features]
network_proxy = true

[permissions.workspace-with-dev-caches]
extends = ":workspace"

[permissions.workspace-with-dev-caches.filesystem]
"/root/.cache/uv" = "write"
"/root/.bun/install/cache" = "write"

[permissions.workspace-with-dev-caches.network]
enabled = true
allow_local_binding = true

[permissions.workspace-with-dev-caches.network.domains]
"registry.npmjs.org" = "allow"

如果实际环境不需要私网地址解析,应删除 allow_local_binding = true,保留默认保护。