用 verdaccio 搭建内部 npm 仓库
目标
搭建 npm 内部 registry,在联网期间填充内容,并确认在断开上游连接之后,仍能按锁文件安装。还要亲自测量在外部生成的锁文件中的地址是如何被解析的。
为什么重要
把 node_modules 整体压缩后带进去的方式,在 node 版本不同时就会损坏,也不会留下带进去了什么的记录。内部 registry 按软件包为单位累积,而锁文件记录的是“什么、对应什么哈希”。两者咬合,在隔离网络内 npm ci 也能生成与外部相同的依赖树。这个 Pod 能访问互联网(80/443),所以承担下载端的角色,而隔离网络一侧的确认,由评分器把发往外部的 HTTP(S) 转到关闭的代理(127.0.0.1:9)上,在封闭的状态下进行。
步骤
- 在
/opt/verdaccio中安装verdaccio@6.1.6(准确固定版本,并且必须留下锁文件)。 - 编写
/root/npm/config.yaml。存储为/root/npm/storage,uplinknpmjs为https://registry.npmjs.org/,模式'**'允许任何人读取并把npmjs作为 proxy,监听地址为127.0.0.1:4873,日志写入文件/root/npm/verdaccio.log。 - 在
/etc/hosts中加入127.0.0.1 npm.airgap.internal,并用该配置启动 verdaccio。 - 在项目
/root/npm/app(必须有 package.json)的.npmrc中写入registry=http://npm.airgap.internal:4873/。 - 在
/root/npm/app中安装chalk@4.1.2,让内部 registry 从上游拉取并填充。 - 从
'**'模式中去掉 proxy,断开上游连接,并重新启动 verdaccio。 - 把 app 的
package.json和package-lock.json复制到/root/npm/app2,用新缓存(/root/npm/cache2)执行npm ci。 - 在
/root/npm/outlock/中用外部 registry 生成锁文件(chalk 4.1.2),在外部被封闭的状态下,分别用 replace-registry-host 的默认值和never对内部 registry 运行npm ci,并把结果按default=ok|fail、never=ok|fail两行写入/root/npm/lockhost.txt。
参考
- 当前生效的值:
npm config get registry(在项目目录内) - verdaccio 是否存活:
curl http://npm.airgap.internal:4873/-/ping、重新启动:先pkill -x verdaccio,再执行同样的命令 - 封闭外部后测量:
HTTPS_PROXY=http://127.0.0.1:9 HTTP_PROXY=http://127.0.0.1:9 NO_PROXY=127.0.0.1,localhost,.airgap.internal npm ci ... - 常见错误 1:用
npm install -g安装 verdaccio。在这个 Pod 中无法写入全局目录,会失败。请指定一个目录来安装。 - 常见错误 2:断开 uplink 之后,在缓存仍然存在的情况下测试。如果缓存接手了,测试的就不是 registry——请使用新的缓存目录。
导入物 1 号:固定版本的 verdaccio
在 /opt/verdaccio 中安装 verdaccio@6.1.6(必须留下锁文件)。
在目录中安装 npm 时,会在该目录生成 node_modules 和 package-lock.json。全局安装在这个 Pod 中会因权限问题而失败。请在 @ 之后准确写出版本。
配置带有上游(uplink)的代理 registry
在 /root/npm/config.yaml 中写入存储、uplink、模式、监听地址和日志文件。
在 uplinks 中写上上游 registry 的名称和地址,并在 packages 的 '**' 模式中用 proxy 指向该名称。listen 是“主机:端口”的一行。日志用 type: file 给出路径。
用内部名称启动 registry
在 /etc/hosts 中加入 127.0.0.1 npm.airgap.internal,并用 /root/npm/config.yaml 启动 verdaccio。
verdaccio 通过 --config 接收配置文件。请放到后台启动,使关闭终端后仍然存活,并通过 registry 的 ping 地址确认是否存活。
用项目 .npmrc 指向
在项目 /root/npm/app(包含 package.json)的 .npmrc 中写入 registry=http://npm.airgap.internal:4873/。
项目目录中的 .npmrc 优先于用户和全局配置。写入之后,请在该目录内用 config get 确认 npm 实际使用的是哪个值。
联网期间拉取填充一次
在 /root/npm/app 中安装 chalk@4.1.2,让内部 registry 从上游拉取并把它留存到存储中。
项目的 .npmrc 已经指向内部 registry,所以像平常一样安装即可。安装之后,请看锁文件中 resolved 地址指向哪里,以及 registry 的存储目录中生成了什么。
断开上游连接,变成隔离网络 registry
从 '**' 模式中去掉 proxy,并重新启动 verdaccio。
没有 proxy 的模式只提供本地仓库中已有的内容。配置是在启动时读取的,所以必须先停止进程再重新启动。请请求一个仓库中没有的软件包,看是否返回 404。
用新缓存按锁文件安装
把 app 的 package.json、package-lock.json 和 .npmrc 复制到 /root/npm/app2,并用新缓存 /root/npm/cache2 执行 npm ci。
npm ci 必须有锁文件,并按其原样安装。给出新的缓存目录,之前下载的内容就帮不上忙,相当于测试仅靠 registry 能否完成。
外部锁文件中的地址是如何被解析的
在 /root/npm/outlock/ 中用外部 registry 生成 chalk 4.1.2 的锁文件,并在外部被封闭的状态下,分别用默认值和 --replace-registry-host=never 对内部 registry 运行 npm ci,把 default= 和 never= 的结果(ok 或 fail)写入 /root/npm/lockhost.txt。
锁文件的 resolved 中写死的主机是默认 registry 时,npm 会怎么做,由 replace-registry-host 设置决定。两次都必须使用新缓存和新目录,并在外部被封闭的状态下运行,这样的比较才公平。请以命令的退出码来判断结果。