跳转到内容

仓库故障排查

401 Unauthorized —— 明明已经登录了

Section titled “401 Unauthorized —— 明明已经登录了”

三个常见原因:

  1. .npmrc 中缺少 always-auth=true —— 没有它,yarn 1 拒绝在 GET 请求中发送 bearer。npm/pnpm/bun 会无害地忽略该标志,所以总是把它加上就好。
  2. 令牌已被撤销 —— 检查面板中的 Packages → Manage tokens。如果那一行不见了,签发一个新的。
  3. auth 行中的 host 错误 —— 该行必须使用提供仓库服务的确切 host,例如 //pier.example.com/registry/npm/:_authToken=…。结尾多一个或少一个斜杠的不匹配会导致静默 401。

yarn berry 需要在 .yarnrc.yml 中设置 npmAlwaysAuth: true(不是在 .npmrc 中):

npmRegistryServer: "https://YOUR-PIER-HOST/registry/npm/"
npmAuthToken: "pier_npm_…"
npmAlwaysAuth: true
nodeLinker: node-modules

没有它,yarn 4 只会在 npm publish 时发送 bearer,而不会在 npm install 时发送。

你正在重新发布一个已存在的版本。在 package.json 中提升版本号(npm version patch / minor / major)。Pier 按设计拒绝重新发布 —— 这与 npm 语义一致。

如果你真的想替换一个已发布的版本,先 npm unpublish @your-org/[email protected],然后再 npm publish 新的字节。注意:那些固定了 X.Y.Z 并将其写入 lockfile 的外部使用者会遇到完整性不匹配。

packument 响应携带一个 ETag。如果你的客户端用同一个值发送 If-None-Match,Pier 会返回 304。如果你每次都看到完整的 200 响应,请检查:

  • Auth 头与之前相同。 一些 HTTP 库在请求发生变化(不同的 Accept 等)时会跳过 If-None-Match —— 确保你的 Accept 头保持稳定。
  • 压缩 —— 如果响应被 gzip 压缩而客户端请求未压缩版本(或反之),ETag 不变但某些中间件会剥离 If-None-Match。用 curl -H "Accept-Encoding: gzip" 可以稳定复现。

Bun(以及较新的 npm)会发送 Accept: application/vnd.npm.install-v1+json —— Pier 返回一个更精简的 JSON(没有 README,没有历史时间戳)。如果你的工具链需要完整的 packument,去掉这个精简版 Accept

Traefik 已启动但 Pier 在其 loopback 端口上不可达。在主机上检查 systemctl status pier。如果 pier 已启动,检查 proxy.platform_domain 是否与你访问的 host 匹配。

上游代理可能未启用。检查 Packages → Upstream proxy → Enable upstream proxy —— 关闭时,只提供私有发布的包。

如果代理已开启你仍然得到 404,那么上游可能确实返回了 404。Pier 会透传它(一个在 npmjs.org 上确实不存在的包应当是 404)。

“Tarballs on disk” 显示 0,但我刚装过

Section titled ““Tarballs on disk” 显示 0,但我刚装过”

LRU GC 可能已经把它们淘汰了。缓存上限在 Packages → Upstream proxy → Max cache size (MiB) —— 如果设了一个很小的值(例如 50)而你安装了像 Next.js 这样的大东西,较旧的 tarball 就会被回收。

如果磁盘充裕,把 Max cache size 设为 0(无限制)。

你也可以从包详情页重新拉取某个特定版本 —— Download latest (X.Y.Z) 按钮会通过 Pier 拉取单个 tarball,而无需启动 npm install

一个已知的已缓存包,详情页显示”0 versions”

Section titled “一个已知的已缓存包,详情页显示”0 versions””

packument blob 可能是空的(通常出现在一次清空了按版本行的迁移之后)。如果 blob 为空,Pier 会在详情页加载时自动刷新它 —— 首次访问可能较慢(约 1 秒),因为它要从上游拉取。后续访问则是瞬时的。

如果重新加载后仍然停留在 0,说明上游要么不可达,要么返回了 404。检查 journalctl -u pier | grep proxy

npm warn Unknown project config "always-auth"

npm 11 弃用了该标志但仍然尊重它。你可以忽略这个警告。等到 npm 12 推出并移除它时,yarn 1 会是另一个独立的问题(到那时大多数团队应该都已经迁移了)。