使用 docker 搭建 verdaccio

创建 & 配置config.yaml文件

# Read about the best practices
# https://verdaccio.org/docs/best

# path to a directory with all packages
storage: /verdaccio/storage/data
# path to a directory with plugins to include
plugins: /verdaccio/plugins

# 包体积上限,默认10mb
max_body_size: 1024mb


web:
  enable: true
  title: Mozzie-NPM
  # gravatar: false
  # login: true
  pkgManagers:
    - npm
    - yarn
    - pnpm
  html_cache: true
  showFooter: false

auth:
  htpasswd:
    file: /verdaccio/storage/htpasswd
    # 关闭注册,手动添加用户,默认Bcrypt算法,随便找个网页生成个密码,使用账号:密码添加到 htpasswd 文件中,例如 test:$2a$10$0xPGVnpcdxcfmFxtWyWDx./TRtm/W/gSzib/jck3w.sF9x.Ur8t8W
    max_users: -1


i18n:
  web: zh-CN

# notify: # 配置 Webhook 推送到钉钉,记得修改 access_token 和 atMobiles
#  method: POST
#  headers: [{ "Content-Type": "application/json" }]
#  endpoint: https://oapi.dingtalk.com/robot/send?access_token=xxxx
#  content: '{"msgtype":"text", "at": {"atMobiles": ["13000000000"] }, "text":{"content":"NPM 发布新包:\n > 包名称:{{name}} \n > 版本号:{{#each versions}}{{version}}{{/each}} \n > 发布者:{{publisher.name}} "}}'

uplinks:
  npmjs:
    url: https://registry.npmjs.org/
  yarn:
    url: https://registry.yarnpkg.com/
    timeout: 10s
  taobao:
    url: https://registry.npmmirror.com/
    timeout: 10s

packages:
  "@*/*":
    # 可访问权限,web界面看不见,不登陆,也无法 install 包
    access: $authenticated # $all
    # 发布权限, $authenticated 表示只有通过验证的人
    publish: $authenticated
    # 可取消发布权限
    unpublish: $authenticated
    # 包不存在时的代理
    proxy: npmjs yarn taobao
  "**":
    access: $authenticated # $all
    publish: $authenticated
    unpublish: $authenticated
    proxy: npmjs yarn taobao

middlewares:
  audit:
    enabled: true
listen: 0.0.0.0:4873
log: { type: stdout, format: pretty, level: http }

创建容器,环境变量,VERDACCIO_PUBLIC_URL是静态资源的前缀地址,由于nginx挂了ssl,如果使用http可以不添加

docker run \
-p 4873:4873 \
--restart=always \
--network mozzie.cn-net \
--network-alias verdaccio \
--env VERDACCIO_PORT=4873 \
--env VERDACCIO_PUBLIC_URL=https://npm.mozzie.cn \
--ip 172.21.0.196 \
--name verdaccio \
-v /www/wwwroot/nginx/html/verdaccio/storage:/verdaccio/storage \
-v /www/wwwroot/nginx/html/verdaccio/config:/verdaccio/conf \
-v /www/wwwroot/nginx/html/verdaccio/plugins:/verdaccio/plugins \
-d verdaccio/verdaccio

配置nginx的反向代理conf,注意所在的docker网络,使用container_name

server {
    # listen 80;
    listen 443 ssl;
    server_name npm.mozzie.cn;
    ssl_certificate  /etc/nginx/ssl/npm.mozzie.cn_bundle.pem;
    ssl_certificate_key  /etc/nginx/ssl/npm.mozzie.cn.key;
    gzip on;

    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;
      proxy_set_header X-NginX-Proxy true;
      proxy_pass http://verdaccio:4873/;
      proxy_redirect off;
    }
}

运行添加用户,报错,因为 htpasswd默认创建在宿主机,也就是上面挂载的/www/wwwroot/nginx/html/verdaccio/storage目录中

npm adduser --registry https://npm.mozzie.cn/

配置htpasswdstorage 文件夹权限

# 宿主机中执行
cd /www/wwwroot/nginx/html/verdaccio/storage
touch htpasswd
sudo chown 10001:65533 htpasswd
sudo chown -R 10001:65533 /www/wwwroot/nginx/html/verdaccio/storage

verdaccio 用户管理

由于在 config.yml 中关闭了可访问权限

auth:
  htpasswd:
    file: /verdaccio/storage/htpasswd
    # 关闭注册,手动添加用户,默认Bcrypt算法,
    max_users: -1

packages:
  "@*/*":
    # 可访问权限,web界面看不见,不登陆,也无法 install 包
    access: $authenticated # $all
    # 发布权限, $authenticated 表示只有通过验证的人
    publish: $authenticated
    # 可取消发布权限
    unpublish: $authenticated
  "**":
    access: $authenticated
    publish: $authenticated
    unpublish: $authenticated

默认的 addUser 策略是 Bcrypt 生成密码,随便找个网页生成个密码,使用账号:密码添加到 htpasswd 文件中,例如

test:$2a$10$0xPGVnpcdxcfmFxtWyWDx./TRtm/W/gSzib/jck3w.sF9x.Ur8t8W

因此在实际开发中,管理员手动给用户创建好账号,然后根据用户的包管理工具,进行登录,例如以 npm 为例

npm adduser --registry https://npm.mozzie.cn/
# 输入 Username: mozzie | Password: xxx | Email: (this IS public) himozzie@foxmail.com
# 提示登陆成功 Logged in as mozzie on https://npm.mozzie.cn/.

在系统的 cat ~/.npmrc 中会增加一行,就可以正常的进行以来的安装了

//npm.mozzie.cn/:_authToken="Do/wrh5QzsnYaNU4x3ZlVA=="

项目 .npmrc Scope区分

需要指定 .npmrc 来区别 Scope 的安装地址,例如一个包名为 @mozzie/hook,对应的私库为 https://npm.mozzie.cn/

registry=http://registry.npm.taobao.org/
@mozzie:registry=https://npm.mozzie.cn
# npm拉包的校验
//https://npm.mozzie.cn/:_authToken=xxxxxxxxxxxxx