使用verdaccio搭建私有npm仓库
介绍
verdaccio是一款开源轻量级的私有Npm源工具,简单来说你可以用它来搭建一个自己的Npm仓库,可以实现绝大部分Npm所提供的能力,官方网站。
- 与 yarn, npm 和 pnpm 100% 兼容
- 提供 Docker 和 Kubernetes 支持,相当容易安装和使用
- 发布的包是私有的并且访问权限可配置
- Verdaccio 按需要缓存所有相关项,并在当地或私有网络下可以加速安装
安装
官网有详细的安装教程。笔者使用的是linux服务器,并且服务器有安装docker容器,所以这里使用docker安装Verdaccio,简单快捷。
docker pull verdaccio/verdaccio
运行
使用docker运行Verdaccio。
docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio
或者使用-v挂载本地数据卷。
docker run -it --rm --name verdaccio \
-p 4873:4873 \
-v /data/verdaccio/conf:/verdaccio/conf \
-v /data/verdaccio/storage:/verdaccio/storage \
-v /data/verdaccio/plugins:/verdaccio/plugins \
verdaccio/verdaccio
注意
在官方提示中,建议使用docker volume而不是 bind mount:
Verdaccio 在容器内以非root用户(uid=10001)运行,如果使用绑定挂载覆盖默认值,则需要确保挂载目录分配给正确的用户。在上面的例子中,你需要运行 sudo chown -R 10001:65533 /path/for/verdaccio 否则你会在运行时出现权限错误。建议使用docker volume而非使用 bind mount。
在实际操作中,为了方便,笔者使用docker volume,将/verdaccio/conf, /verdaccio/storage, /verdaccio/plugins挂载到主机的同一数据卷下时,会报这个错误:
Error: EACCES: permission denied, open '/verdaccio/conf/htpasswd'
解决的方法,就是将这三个目录挂载到不同的数据卷中,错误就会解决。
使用
使用nrm
nrm 是一个 NPM 源管理器,可以使用 nrm 在不同的源切换。
- 安装nrm
npm i nrm -g
- 查看nrm 源
nrm ls
npm -------- https://registry.npmjs.org/
yarn ------- https://registry.yarnpkg.com/
cnpm ------- http://r.cnpmjs.org/
taobao ----- https://registry.npm.taobao.org/
nj --------- https://registry.nodejitsu.com/
npmMirror -- https://skimdb.npmjs.com/registry/
edunpm ----- http://registry.enpmjs.org/
- 添加或删除私有源
nrm add registry_name registry_url #添加源,registry_name为源的名称,registry_url为源的地址
nrm del registry_name #删除源
- 使用私有源
nrm use registry_name
登录私有源
再使用nrm切换到私有源之后,使用npm login登录私有源, 输入账号,密码,邮箱,就可以登录成功。
nrm use registry_name
npm login
发布包
在项目的根目录下执行npm publish就可以将包发布到私有源
npm publish
配置
在/verdaccio/conf中有一个config.yaml, 可以做相应的配置。如果使用docker数据卷挂载,则在数据卷目录中也会有相应的config.yaml,比如以上安装示例中,config.yaml就会出现在主机的/data/verdaccio/conf目录中。
配置文件:
# 包含所有包的目录的路径
storage: /verdaccio/storage/data
# 包含所有包的插件的路径
plugins: /verdaccio/plugins
#显示的网页配置
web:
# WebUI 默认启用,如果你想禁用它,只需取消注释这一行
#enable: false
title: Verdaccio
# 禁用 gravatar 支持
# gravatar: false
# 默认情况下,包是的排序是上升的 (asc|desc)
# sort_packages: asc
# darkMode: true
# logo: http://somedomain/somelogo.png
# favicon: http://somedomain/favicon.ico | /path/favicon.ico
# 多语言支持
# i18n:
# 支持的语言列表在: https://github.com/verdaccio/ui/tree/master/i18n/translations
# web: en-US
auth:
htpasswd:
file: /verdaccio/storage/htpasswd
# 允许注册的最大用户数,默认为 "+infinity".可以设置-1禁止注册用户。
# max_users: 1000
# 上游服务器,表示如果你的库中没有此文件,可以去其他上游服务器拉取
uplinks:
npmjs:
url: https://registry.npmjs.org/
# 表示是否开启缓存
cache:true
# 表示缓存多久后失效
maxage:10m
packages:
# 作用域包
'@*/*':
# 表示哪一类用户可以对匹配的项目进行安装
# 可以使用三个关键字:“$all”、“$anonymous”、“$authenticated”
# 也可以指定用户名/组名(取决于上面使用的身份验证插件,htpasswd)
access: $all
# 表示哪一类用户可以对匹配的项目进行发布
publish: $authenticated
# 表示哪一类用户可以对匹配的项目进行卸载包
unpublish: $authenticated
# 表示如果库中没有此包,此能过上面配置的npmjs去获取
proxy: npmjs
# 其他所有包
'**':
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
# 可以为传入连接指定 HTTP/1.1 服务器保持活动超时(以秒为单位)。
# 值为 0 使 http 服务器的行为类似于 8.0.0 之前的 Node.js 版本,后者没有保持活动超时
# 解决方法:通过给定的配置,您可以解决以下问题 https://github.com/verdaccio/verdaccio/issues/301。 如果 60 不够,则设置为 0。
server:
keepAliveTimeout: 60
middlewares:
audit:
enabled: true
# 日志设置
logs: { type: stdout, format: pretty, level: http }
#环境配置
#experiments:
# # 支持 npm token 指令
# token: false
# # 启用 tarball URL 重定向以使用不同的服务器托管 tarball,tarball_url_redirect 可以是模板字符串
# tarball_url_redirect: 'https://mycdn.com/verdaccio/${packageName}/${filename}'
# # 当使用 js 配置文件时,tarball_url_redirect 可以是一个函数,接受 packageName 和 filename 并返回 url
# tarball_url_redirect(packageName, filename) {
# const signedUrl = // generate a signed url
# return signedUrl;
# }
# 这会影响 web 和 api(尚未开发)
#i18n:
#web: en-US
权限配置
一般团队或者公司的私有项目,会采用不同的权限控制,配置文件的packages是配置包的权限的:
- 匹配包名
- '@/' 表示带有@/的作用域包
- ** 表示其他的所有包
- 可以配置自己的包比如:'private-', 'my-'等等
- 操作权限:
- access 表示哪一类用户可以对匹配的项目进行安装(install)
- publish 表示哪一类用户可以对匹配的项目进行发布(publish)
- proxy 表示如果库中没有此包,此能过上面配置的npmjs去获取
- 用户权限:
- $all 表示所有人都可以执行对应的操作
- $authenticated 表示只有通过验证的人可以执行对应操作
- $anonymous 表示只有匿名者可以进行对应操作(通常无用)
- 这里可以写已经注册的用户名,做到精细化控制
实际的权限配置场景
公司里有两个前端团队teamA和teamB,私有源上的所有包都可以安装,但是每个团队只能发布或移除自己团队的包。则可以使用以下配置。
packages:
# teamA
'@teamA/*':
access: $all
publish: teamA-user1 teamA-user2 teamA-user3
unpublish: teamA-user1 teamA-user2 teamA-user3
proxy: npmjs
# teamB
'@teamB/*':
access: $all
publish: teamB-user1 teamB-user2 teamB-user3
unpublish: teamB-user1 teamB-user2 teamB-user3
proxy: npmjs
# 其他所有包
'**':
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
因为是私有源,我们可以设置 config.yaml 中的 max_users: -1 来禁用 npm adduser 命令来创建用户。如果需要添加用户这里介绍两种方法:
- 可以通过安装 htpasswd-for-sinopia 来添加账号
npm install htpasswd-for-sinopia -g #全局安装htpasswd-for-sinopia
sinopia-adduser # 在 htpasswd 目录下执行
- 可以通过官方提供的工具来生成 htpasswd-generator ,将生成的段字符串添加到 htpasswd 中即可。