Ubuntu 20.04 安装 Codex CLI:Node 与 npm 镜像源
1. 先搞清楚 Codex CLI 到底装的是什么Codex CLI 是官方出品的命令行 AI 编程代理跑在终端里能读你当前目录的代码、改文件、跑命令用自然语言下指令就行。它不是一个聊天窗口而是把模型能力塞进了codex这条命令里让它在你的项目目录中干活。这篇文章要解决的就是在 Ubuntu 20.04 这个已经有点年头的 LTS 系统上把它干净地装起来并且在国内网络环境下把依赖下载这一关过掉。适合两类人看一是在 Ubuntu 20.04 上做开发、想试试命令行 AI 编程助手的同学二是被npm install卡在下载阶段、装到一半报错不知道从哪下手的人。整套流程我会从运行时选型一路讲到卸载回滚中间踩过的坑都会写清楚。Ubuntu 20.04 这个版本有点尴尬。它发布于 2020 年系统自带的软件源里 Node.js 还停在 10.19而 Codex CLI 需要 Node 18 以上的运行时实际用下来 22 LTS 最省心。这就意味着你不能直接apt install nodejs然后npm i -g了事第一步的运行时选择就必须想清楚。第二个门槛是 npm registry 的连通性这个包在安装过程中会去拉平台对应的原生二进制文件包体不小直连官方源经常在reify阶段卡住几分钟然后超时。这两件事解决掉剩下的都是常规操作。我见过不少人一上来就照着某篇教程敲sudo npm install -g结果装完发现命令能用但每次升级都得 sudo.npmrc里的用户级配置也不生效后面换镜像源的时候一头雾水。所以这篇文章的顺序是先定运行时再走官方安装路径确认能跑通最后再引入镜像加速。反过来做——先换源再装——一旦出问题你分不清是源的问题还是环境的问题排查成本会翻倍。2. Node 运行时怎么选这一步决定后面顺不顺2.1 apt 源里的 Node 为什么直接用不了Ubuntu 20.04 的apt install nodejs装出来是 10.19.0node -v一看就知道不行。就算你用 NodeSource 的源也要注意版本对应关系NodeSource 为 focal 提供了 18、20、22 的源但每个源是独立的装了 22 的源之后系统级的nodejs包会被替换掉跟 apt 自带的那个不能共存。这带来的副作用是如果你机器上还有别的项目依赖系统 Node比如某些 apt 装的工具链会调用/usr/bin/node升级会影响它们。另一种更常见的做法是用 nvm 管版本。nvm 把 Node 装在用户目录下~/.nvm/versions/node/v22.x.xnpm 全局包也随之落在用户目录里npm install -g再也不需要 sudo权限类问题直接消失。代价是 shell 里必须加载 nvm 脚本非交互式 shell比如 cron、某些 IDE 的终端、systemd 服务默认读不到这个环境需要额外处理。我的建议很直接开发机用 nvm服务器或者需要被其他进程调用的场景用 NodeSource 系统级安装。判断标准就一条——这个codex命令会不会被非登录 shell 调用。如果只是你自己在终端里手敲nvm 完胜。2.2 nvm 与 NodeSource 的取舍对照维度nvm用户级NodeSource系统级安装位置~/.nvm/versions/node//usr/bin/node、/usr/lib/node_modules是否需要 sudo 装全局包不需要需要或改 prefix多版本共存原生支持nvm use切换需要手动切换源麻烦非交互式 shell 可用性需额外配置默认不可用直接可用对系统其他组件影响无会替换系统 nodejs 包卸载干净度删目录即可需 apt remove 并清理源表格左边那一列对个人开发机来说优势太明显了。我自己的几台 Ubuntu 20.04 机器全部走 nvm从来没为EACCES权限问题折腾过。右边那一列更适合那些需要把codex挂到 CI 步骤或者别的服务里调用的场景因为系统路径稳定、可预测。2.3 用 nvm 把 Node 22 装上的完整过程先装 nvm 本身。官方安装脚本会往~/.bashrc里追加一段加载逻辑装完记得source ~/.bashrc或者重开终端否则nvm命令找不到。curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash注意这一步如果拉取脚本很慢可以直接下载脚本文件到本地再执行或者手动 clone 仓库后运行./install.sh。不要去猜脚本内容装之前用cat看一眼是基本习惯。装完之后export NVM_NODEJS_ORG_MIRRORhttps://npmmirror.com/mirrors/node/ nvm install 22 nvm alias default 22 node -v npm -v第一行那个环境变量是关键。nvm 下载 Node 二进制包默认走官方地址国内拉 40MB 左右的压缩包会等很久。设置这个镜像变量之后nvm 会从国内镜像站取包速度差别非常明显。这个变量建议写进~/.bashrc以后每次装新版本都省事。nvm alias default 22这行别省。不设默认版本的话新开一个终端node可能是空的或者指向旧版本回头你排查半天以为是安装失败其实只是版本没切过来。设完之后验证一下which node # 应该输出 /home/你的用户名/.nvm/versions/node/v22.x.x/bin/node路径在用户目录下就对了。如果输出/usr/bin/node说明 nvm 没生效先解决这个再往下走。3. 官方安装路径先把能跑通这件事验证掉3.1 装之前的三项前置检查很多人跳过检查直接装出问题后无法定位。花一分钟做这三件事第一确认 Node 版本。node -v输出 v22.x 或至少 v18.x。低于这个数npm install -g会报engines相关的警告甚至直接失败。第二确认 npm 的全局前缀在用户目录下。执行npm config get prefix输出应该是/home/xxx/.nvm/versions/node/v22.x.x这种形式。如果输出/usr或/usr/local说明你用的不是 nvm 的 node或者全局 prefix 被改过后面装包会撞权限墙。第三确认当前目录不是项目目录。npm install -g是全局安装在项目目录里执行时如果存在package.json某些情况下 npm 会误判虽然全局安装不受项目依赖影响但为了避免混淆我习惯先cd ~再操作。完成后顺手看一眼磁盘空间df -h ~。Codex CLI 连同依赖和原生二进制装完大概占用一两百 MB加上 npm 缓存会更占地方。磁盘剩余低于 1GB 的话先清一下npm cache clean --force不然可能装到一半报ENOSPC那个错看起来吓人但其实就是没空间了。3.2 npm 全局安装的完整命令与输出解读确认完毕执行npm install -g openai/codex安装过程中你会看到几个阶段。首先是reify也就是依赖树构建和下载然后是postinstall这一步比较关键——这个包会在安装时根据当前平台linux x64 或 arm64去拉对应的原生二进制。所以它不是一个纯 JS 包安装体积里大头是那个可执行文件。安装完成后验证codex --version codex --help--version能打出类似0.x.x的版本号说明二进制就位了。--help能看到子命令列表和常用参数。如果codex提示command not found八成是 npm 全局 bin 目录不在 PATH 里。查一下npm bin -g # 或者新版本 npm 用 npm config get prefix ls $(npm config get prefix)/bin | grep codex如果 bin 目录里确实有codex但 shell 找不到把这个 bin 目录加进~/.bashrc的 PATH 里就好了。提示不要用sudo npm install -g。哪怕它能装上装出来的文件属主是 root后面升级、卸载、读取配置都可能出权限问题。用 nvm 的情况下完全没有必要用 sudo。3.3 二进制直装作为备选方案有些情况下 npm 那条路走不通——比如机器上 Node 环境被别的项目绑死了不能动或者你只想在容器里跑一个独立可执行文件。这时候可以看官方仓库的 Release 页面通常会提供linux-x64的压缩包下载解压后把可执行文件放到~/.local/bin之类的目录即可。mkdir -p ~/.local/bin # 将解压出的可执行文件移动到该目录 chmod x ~/.local/bin/codex export PATH$HOME/.local/bin:$PATH这种方式的优点是零依赖缺点是不会随 npm 升级自动更新版本管理全靠自己记。我一般只在临时测试环境用这招长期使用还是走 npm。3.4 首次启动与登录方式的选择装完之后先别急着上手业务跑一次codex看看它能不能正常启动。首次运行会引导你完成身份验证常见的有两种路径一种是浏览器授权登录终端里会给一个链接和一次性码你在有图形界面的机器上打开链接确认即可另一种是直接用 API 密钥把密钥写进环境变量或者配置文件里。第二种方式在纯命令行服务器上更实用export OPENAI_API_KEY你的密钥这行建议写进~/.bashrc或单独用一个~/.env文件管理不要直接写在项目目录里。密钥泄漏最常见的场景就是不小心git add了一个临时脚本。更进一步可以把密钥放进系统钥匙串工具或者用pass之类的密码管理器通过 shell 函数注入这个看个人习惯但至少不要硬编码进会被提交的文件。4. 换国内镜像源哪些场景有效哪些场景无效4.1 三种换源方式各有各的适用面npm 的镜像源配置分三个层级优先级从低到高是全局配置文件、项目配置文件、命令行参数。第一层是用户级全局配置写在~/.npmrc里npm config set registry https://registry.npmmirror.com npm config get registry这条命令写入后当前用户所有 npm 操作都会走这个源。优点是一劳永逸缺点是如果你还要给别的项目用官方源就得来回切。第二层是项目级在项目根目录建一个.npmrcregistryhttps://registry.npmmirror.com只对这个项目生效。做全局命令行工具安装时用不上这个但如果你是在某个项目里装 Codex CLI 的 SDK 依赖这层配置就有意义了。第三层是命令行临时指定最灵活npm install -g openai/codex --registryhttps://registry.npmmirror.com这条命令不改任何配置文件装完就跟没发生过一样。我调试网络问题时最喜欢用这一层因为可以快速对比两个源的表现而不留下残留配置。4.2 为什么换了 registry 就能解决问题理解这一点你才知道什么时候换源不管用。npm 的包分为元数据package metadata和实体文件tarball两部分。npm install第一步是向 registry 请求元数据拿到依赖树第二步才是根据元数据里的地址去下载 tarball。镜像站的做法是全量同步官方 registry 的元数据和 tarball所以对绝大多数包来说换源等于换了一条下载路径效果立竿见影。但有两个例外必须知道。第一镜像同步有延迟通常几分钟到十几分钟。如果你要装的版本刚发布镜像上可能还是旧的npm view openai/codex version在两个源上查一下就能对比出来。第二也是最容易踩的坑如果某个包在安装脚本里自己去外部地址下载文件换 registry 完全无效。因为那段下载逻辑走的是包内自带的 URL跟 npm 的 registry 配置没关系。Codex CLI 的原生二进制是通过平台相关的包分发的这类包本身也发布在 registry 上所以换源是有效的。但如果你遇到安装很慢、日志里出现的不再是 registry 域名而是别的下载地址那就要意识到换源帮不上忙了得从别的角度想办法。4.3 换源后的验证与回滚清单换完源别急着装先做两个验证。npm config get registry npm view openai/codex version npm view openai/codex dist.tarball第一条确认配置生效。第二条确认能查到包版本如果返回 404 说明源上没这个包或者包名拼错了。第三条能看到 tarball 的实际下载地址如果这个地址指向镜像域名那后续下载就会走镜像。万一换源后出现奇怪的问题——比如装出来的包校验失败、依赖解析异常——回滚很简单npm config delete registry或者直接编辑~/.npmrc把那行删掉。恢复默认之后npm config get registry应该输出https://registry.npmjs.org/。注意不要把 registry 配成一个已经不维护的旧域名。npm 镜像站这些年换过几次地址网上很多老教程里的域名早就停止同步了用上去表现为能查到包但版本很旧或者直接超时很容易误判成自己的网络问题。5. 配置与首次实操让它真正在你的项目里干活5.1 配置文件的位置与关键项Codex CLI 的用户级配置文件默认在~/.codex/config.toml。这是个 TOML 格式的文件手写很直观。第一次运行后如果目录不存在可以自己建mkdir -p ~/.codex一个最小可用的配置大概长这样model 你的模型名 approval_policy on-request sandbox_mode workspace-write三个字段的含义值得说清楚。model指定使用哪个模型具体可选项以你所用服务商提供的为准不要照抄别人的配置。approval_policy控制它执行命令前要不要问你on-request表示由模型自己判断哪些操作需要确认never是全自动风险自己承担。sandbox_mode是沙箱策略workspace-write表示允许在当前工作目录内写文件但不能碰目录外的路径。这三个参数的设计逻辑其实很清楚AI 代理最大的风险不是它答错而是它自作主张地执行了破坏性操作。沙箱和审批策略就是两道闸门。我建议新手前几次用最保守的组合跑几十个任务、对它的行为模式有感觉之后再逐步放宽。5.2 用一个小任务把整条链路跑通别一上来就让它重构整个项目。找一个独立的、能一眼看出对错的小任务比如在这个目录下写一个把 CSV 转成 JSON 的脚本并给出使用示例。mkdir -p ~/codex-demo cd ~/codex-demo codex进入交互界面后输入需求。观察它的行为链条先读目录结构然后可能列计划接着写文件最后可能建议你运行验证。整个过程你能看到它调用了哪些工具、读了哪些文件。这一步的价值在于建立信任边界——你会直观感受到它在什么情况下会去执行命令什么情况下只是读文件。跑通之后可以试试非交互模式适合放进脚本或者快速验证codex exec 解释一下这个目录里的代码结构输出一份 200 字的摘要这种一次性调用不进入交互界面输出完就退出很适合做批处理。5.3 会话与上下文的管理习惯这类工具跑久了会遇到一个共性问题上下文越堆越长响应变慢而且早期无关信息会干扰判断。我的习惯是按任务切分会话一个任务结束就退出重开而不是在一个会话里连着做十件不相关的事。另外项目根目录放一个说明文件比如AGENTS.md之类的约定文件具体文件名以工具文档为准把项目结构、技术栈、代码风格、禁止事项写清楚。这相当于给它一份工作手册能显著减少它做出不符合项目习惯的改动。这个投入非常值——写一次后面每次调用都受益。6. 常见问题排查实录6.1 权限与路径类问题报错EACCES: permission denied。这是最高频的问题根源是用 sudo 装过包或者 npm prefix 指向了系统目录。解决思路不是加 sudo而是把 prefix 改回用户目录npm config get prefix npm config set prefix ~/.npm-global export PATH$HOME/.npm-global/bin:$PATH改完之后要把之前用 sudo 装的东西清掉否则残留文件还是 root 属主。报错codex: command not found。分两种情况。如果--version都跑不了查npm ls -g --depth0看包在不在。如果在那就是 PATH 问题把 bin 目录加进去。如果包都不在回到安装步骤重来看看当初的安装日志是不是中途失败了。6.2 版本与兼容性类问题安装时报EBADENGINE或提示 Node 版本过低。Codex CLI 对 Node 有最低版本要求Ubuntu 20.04 系统自带的 Node 10 肯定不够。用nvm ls看清楚当前激活的是哪个版本nvm use 22切换后再装。运行时报GLIBC_2.xx not found。Ubuntu 20.04 的 glibc 是 2.31如果某个二进制是用更高版本的 glibc 编译的就会缺符号。遇到这个错优先检查是不是装了错误的平台包比如在 x64 机器上装了 arm64 的包其次确认下载的二进制确实是为 focal 或更早的发行版构建的。升级后命令行为变了。这类工具迭代很快参数、配置字段可能调整。升级前先npm view openai/codex versions看看版本列表记下当前版本出问题可以回退。6.3 下载与安装类问题速查表现象可能原因处理方式reify 阶段长时间无响应registry 响应慢或超时切换镜像源或加--fetch-timeout60000安装到 90% 卡住原生二进制下载慢换源重试或清理缓存后重装ETIMEDOUT/ECONNRESET连接中断重试必要时降低并发--maxsockets5ENOSPC磁盘满npm cache clean --force清理空间装完版本比预期旧镜像同步延迟查官方源版本对比或临时用官方源卸载后重装仍旧版本npm 缓存未清npm cache clean --force后重装--maxsockets这个参数值得单独说一句。npm 默认会开多个连接并发下载依赖网络质量不好的时候并发太高反而容易触发超时。把它降到 5 左右下载速度可能略慢但成功率明显提高。这个经验是我在一次连续失败十几次之后才总结出来的日志里全是ECONNRESET看起来像源的问题实际是并发把带宽挤爆了。npm install -g openai/codex --maxsockets5 --fetch-retries36.4 镜像相关问题的排查顺序换源之后如果还是有问题按这个顺序查能省很多时间。第一步确认 registry 配置真的生效了。npm config get registry的输出和npm config list里的内容对一下注意项目级的.npmrc会覆盖全局配置。第二步确认包在镜像上存在且版本正确。npm view openai/codex version如果返回的版本明显落后说明同步延迟等一会儿或者临时切官方源。第三步看安装日志里实际请求的域名。npm install --loglevelhttp会打出每次 HTTP 请求如果日志里的域名和你配置的 registry 不一致说明有某层配置在覆盖它。第四步确认不是缓存导致的假失败。npm cache verify检查缓存完整性必要时npm cache clean --force清空重来。这四步走完绝大多数安装问题都能定位到具体环节。怕的是有些人不看日志一看失败就反复重试重试十次结果一样白白浪费时间。7. 升级、锁版本与干净卸载7.1 版本锁定与手动升级这类工具迭代快有时候一个小版本就改了配置字段。生产环境或者团队协作场景建议锁定版本npm install -g openai/codex0.x.x需要升级时手动指定新版本号而不是无脑npm update -g。个人开发机可以追新但升级前用npm view openai/codex versions --json看一眼版本列表记下当前版本出问题能立刻回退。回退命令就是重装旧版本npm 会自动覆盖npm install -g openai/codex旧版本号7.2 彻底卸载与残留清理npm uninstall -g openai/codex卸完之后还有两处可能残留需要清理。一是 npm 缓存里的包文件占空间但不影响功能npm cache clean --force可以清。二是用户配置目录~/.codex这里面可能有你的配置、会话记录、历史信息。如果只是想换个版本重装这个目录可以留着如果是彻底不用了或者要排查配置导致的异常行为把它移走更干净mv ~/.codex ~/.codex.bak用mv而不是rm -rf给自己留个后悔的机会。这个习惯我保持了几年至少救过我三次。8. 几条从实操里攒下来的经验第一先把镜像源配好再去装包。很多人是先装、失败了、再换源、再装中间那一次失败留下了半截缓存反而干扰后续判断。正确顺序是把 registry 和 nvm 的 Node 镜像变量都配好再动手安装。第二不要在项目目录里执行全局安装也不要在同一个 shell 里同时操作多个 Node 版本。nvm 切换版本是改当前 shell 的环境变量开两个终端分别用不同版本时两边互不影响这是 nvm 的一个隐性优势。第三遇到慢先分清是元数据慢还是二进制慢。用--loglevelhttp看日志如果是请求 registry 元数据慢换源有效如果是请求外部下载地址慢换源无效得从别的角度解决。这个判断一旦建立排查效率会提升一个档次。第四配置文件比命令行参数更值得花时间。每次都要敲一长串参数是效率杀手把这些写进~/.codex/config.toml和 shell 别名里长期收益很大。我现在的习惯是凡是超过三个参数的命令一律做成别名。第五留给自己的退路要留够。版本别追太新配置改动前先备份卸载时用mv不用rm。这些听起来是老生常谈但真正在半夜因为一个配置改错而抓狂的时候你会庆幸自己留了这些后手。Ubuntu 20.04 已经进入生命周期后半程很多新工具对它