背景:公司内部有许多前端内部子包,会频繁发布,维护在现有的npm私有仓。
现存的问题是:
- 原有verdaccio的版本太低3.x,缺少一些特性,最重要的是该版本有一些bug
- 磁盘空间满了,运维反馈无法扩容了,且全都安装在root目录下
- npm仓库地址使用ip,而非域名,迁移需要比较大范围的修改配置
谨以此文,记录一下在全新服务器从零到一搭建、迁移、踩坑的全过程~
选型
-
官方私有npm服务:团队版$7/人/月这个价格就已经直接劝退,且不说npm在国内的网络情况不容乐观。
-
直接安装git代码:直接通过npm install 引入对应git代码确实有一定的便利性,但是当全局包多了之后不便于维护且权限难以管理
-
sinopia:基于Node.js实现的一个开源npm库,年久失修。最近一次提交是6年前,直接放弃。
-
cnpm:阿里出的npm私有方案,权限控制较为全面但是配置复杂,需要自己搭建mysql之类的数据库存储。
-
verdaccio:基于sinopia继续开发,目前维护很频繁而且配置简单,可以快速搭建。
安装
1. 安装nvm
-
下载好nvm-0.39.3.tar.gz,选择在home目录下解压:
tar -zxvf nvm-0.39.3.tar.gz -C nvm
-
配置nvm.sh的位置:
vim ~/.bashrc
注:可解决每次重新登录进来,
nvm ls
或者node --version
就不正常运作
-
重新加载文件:
source ~/.bashrc
-
自此安装完毕,检测一下:
nvm -v
2. 安装node
本着尽可能使用更高版本node的原则,于是开始了@18 -> @16 -> @14版本的尝试:
- @18:
centos7服务器使用nvm安装的node之后,只要使用npm或者node,均会出现以下问题
vbnet
[root@172 ~]# npm -v
node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by node)
node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by node)
node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by node)
node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by node)
查看系统内安装的glibc版本
csharp
[root@172 glibc-2.28]# strings /lib64/libc.so.6 |grep GLIBC_
GLIBC_2.2.5
...
GLIBC_2.17
....
根据分析可得知:新版的node v18开始,都需要GLIBC_2.27支持,可是目前系统内却没有那么高的版本。
最直接的解决方法是更新glibc,但是我没有强硬的要求一定要18,所以我选择降到了16。
参考链接:
www.cnblogs.com/dingshaohua...
- @16
kotlin
[root@template ~]# npm i -g verdaccio
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm ERR! code 127
npm ERR! path /root/nvm/versions/node/v16.20.1/lib/node_modules/verdaccio/node_modules/core-js
npm ERR! command failed
npm ERR! command sh -c -- node -e "try{require('./postinstall')}catch(e){}"
npm ERR! sh: node: 未找到命令
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2023-07-03T07_51_06_212Z-debug-0.log
To fix the "NPM Error Code 127" we can do the following:
- Check your system PATH environment variable to see if you have the correct command
- Clear NPM node_modules and package-lock.json and reinstall
- Check to see if you have the right versions of Node/NPM
参考链接:
weekendprojects.dev/posts/how-t...
- node@14
nvm install 14
安装完毕,检测一下
nvm ls
nvm use 14.21.3
node --version
3. 设置npm
修改npm全局安装依赖的路径
npm config set prefix /xxx/nvm/versions/node/v14.21.3
npm config set cache /xxx/nvm/versions/node/v14.21.3/npm-cache
4. 安装verdaccio
npm i verdaccio -g
安装完毕后,需要对verdaccio进行一些配置(config.yaml):
- 存储配置:对storage等目录进行修改,免得直接放在根目录下。
- 权限配置:verdaccio 5.x可以对不同类型的包的access,publish,unpublish的权限分别进行控制。由于踩过一些unpublish的坑(可以看下文-问题),因此在此只对unpublish进行严格控制。
- 日志配置:默认的配置没有开启时间戳,个人觉得这个对于排查问题还是很有帮助的。
- uplinks: 默认是npm官方库,国内经常连不上吧,于是改为了淘宝镜像。
- listen:默认是只能本地访问(localhost),要修改为0.0.0.0:4873,才可以通过别的ip访问。
5. 安装pm2
pm2用以持久化node程序,安装也很简单:npm i pm2 -g
修改pm2 logs文件位置,因为logs文件会越来越大,占用root空间也没必要。参考:pm2.fenxianglu.cn/docs/genera...
初始化pm2的配置文件:pm2 init simple
修改好配置好启动:pm2 start ecosystem.config.js
注:如果修改配置,记得restart!
6. 数据迁移
从原先的3.11.6,跨了2个大版本到5.29.0。但总体来说,verdaccio的兼容性做的还不错,没有什么特别的点。
- storage:各npm包资源,直接复制过来就好了。
- .verdaccio-db.json :原 sinopia-db.json,最好用新的文件名.verdaccio-db.json,存储了所有内部的包名。迁移过来的时候,注意不要全部复制旧的文件,要保留新的
secret
(在最后面)。详见verdaccio.org/docs/cli/#d... - htpasswd:将上一个服务器的用户信息进行迁移,免得大家都重新注册
7. 域名配置
这事交给运维,把ip和想要的域名定好就可以了。顺便提一句,要是不想要域名后面带4873端口号,可以修改verdaccio的端口号配置指向80端口,这样子默认用域名就可以访问了,向优雅更进一步。
问题
-
E503,没法发布新包
-
问题复现:发布已有包的新版本,能正常发布,但是需要发新的包,则遇到了如下提示,乍一看是权限问题?
-
问题解决:修改config.yaml,将
allow_offline
修改为true
-
-
E404,unpublished问题
-
问题复现:在storage中,在页面上看,明明都存在着的包,为什么一执行
npm view xxx --json
就报错说不存在? -
问题解决:去服务器上查看该包的package.json,发现有一个奇怪的版本号:unpublished,简单粗暴的解决方案是------删除该行&控制unpublish权限。但是对于产生的具体原因还未明确,大概是与unpublish操作相关,但是实际上执行unpublish操作的包和出现unpublished版本号的包,不是同一个,有点费解。而且问题多次发生下来,发现不管unpublish操作哪个包,产生unpublished版本号的包都是同一个,就更费解了。
-
-
ENOTFOUND
DNS配置问题
-
.npmrc registry
在有些项目中会存在.npmrc registry的配置,这个优先级是最高的,即使全局配置了npm仓库地址,指向了私有仓地址,但是可能会发现安装包的时候,还是去别的地址找,这个时候可以排查一下是否是由于更高优先级的registry配置。