npm私服搭建学习笔记

NPM 私服搭建完整指南

一、为什么需要搭建 NPM 私服

在企业应用开发中,搭建私有 NPM 仓库是必要的基础设施选择:

核心价值

代码私密性保障:企业内部业务组件、工具库等敏感代码需要私有化管理,避免泄露

访问速度优化:局域网内部访问,依赖下载速度显著提升,特别适合大型项目和 CI/CD 场景

权限精细控制:可针对不同团队、项目设置发布、访问权限,便于维护和管理

成本效益显著:npm 官方私有包需要付费订阅,自建私服无额外成本

适用场景

企业内部组件库、工具库共享

多项目公共模块统一管理

特定版本依赖的稳定存储

CI/CD 流程中的依赖缓存

二、主流私服方案对比

方案 优势 劣势 适用场景

Verdaccio 轻量级、零配置启动、专注 npm、配置简单 功能相对单一、企业级特性较少 中小型团队、纯前端团队、快速部署

Nexus 多格式支持(npm/Maven/Docker)、企业级权限管理、功能强大 相对重量级、配置复杂、需要 Java 环境 大型企业、多语言团队、已有 Nexus 基础设施

cnpm 国内访问快、支持大规模镜像、企业级功能强 部署复杂、需要数据库、维护成本高 超大规模团队、对国内访问速度要求极高

Artifactory 功能最全面、支持所有主流包管理器、企业级特性丰富 商业软件、价格昂贵、学习曲线陡峭 大型企业、预算充足、需要统一管理所有包管理器

推荐选型策略:

90% 的中小型团队 → Verdaccio

大型企业 / 多技术栈团队 → Nexus

超大规模团队(阿里级别)→ cnpm

三、Verdaccio 深度实践

3.1 Verdaccio 核心特性

Verdaccio 是基于 Node.js 的轻量级私有 npm 代理注册表,具有以下特点:

轻量级设计:采用 Node.js 编写,无外部数据库依赖,数据存储于本地文件系统

简单配置:单个 YAML 配置文件即可完成权限、上游代理、缓存等设置

缓存和代理:可作为上游 npm 注册表的代理,自动缓存已下载的包

灵活访问控制:支持基于用户和包的访问权限管理

插件生态:支持身份验证、审计日志等插件扩展

3.2 安装方式对比

方式一:全局安装(适合快速体验)

bash

全局安装

npm install -g verdaccio

查看基本信息

verdaccio -h

启动服务

verdaccio

注意:Verdaccio 6.x 要求 Node.js 18+,推荐使用 Node.js 20 LTS

方式二:Docker 部署(推荐用于生产环境)

基础部署命令:

bash

拉取镜像

docker pull verdaccio/verdaccio:6.x

运行容器(数据持久化)

docker run -d --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:6.x

Docker Compose 部署(推荐) :

yaml

version: '3.8'

services:

verdaccio:

image: verdaccio/verdaccio:6.x

container_name: verdaccio-prod

restart: unless-stopped

ports:

  • "4873:4873"

environment:

  • VERDACCIO_PORT=4873

  • VERDACCIO_PROTOCOL=http

HTTPS 配置时使用

- VERDACCIO_PUBLIC_URL=https://registry.example.com

volumes:

  • ./storage:/verdaccio/storage

  • ./config:/verdaccio/conf

  • ./plugins:/verdaccio/plugins

networks:

  • verdaccio-net

networks:

verdaccio-net:

driver: bridge

权限设置关键点:

bash

Docker 容器内默认使用 uid 10001 运行

sudo chown -R 10001:65533 /data/verdaccio

方式三:使用 PM2 守护进程

bash

安装 PM2

npm install -g pm2 --unsafe-perm

启动 Verdaccio

pm2 start verdaccio --name "private-npm" -- --config /opt/verdaccio/conf/config.yaml

查看状态

pm2 list

查看日志

pm2 logs verdaccio

3.3 核心配置详解

配置文件结构

yaml

存储路径

storage: /verdaccio/storage

插件目录

plugins: /verdaccio/plugins

Web UI 配置

web:

enable: true

title: 企业私有 NPM 仓库

gravatar: true

darkMode: false

身份认证设置

auth:

htpasswd:

file: /verdaccio/conf/htpasswd

max_users: 1000 # -1 表示禁止新用户注册

上游代理配置

uplinks:

npmjs:

url: https://registry.npmjs.org/

timeout: 30s

taobao:

url: https://registry.npmmirror.com/

timeout: 10s

包访问权限控制(核心)

packages:

'@your-scope/*':

access: $authenticated # 只有认证用户可访问

publish: $authenticated # 只有认证用户可发布

unpublish: $authenticated # 只有认证用户可取消发布

proxy: npmjs # 私有包不需要代理

' **':

access: $all # 所有人可访问

publish: $authenticated

unpublish: $authenticated

proxy: npmjs taobao # 本地没有时,按顺序从上游拉取

服务器配置

server:

keepAliveTimeout: 60

日志配置

log:

type: stdout

format: pretty

level: http

监听配置(生产环境注意)

listen:

  • 0.0.0.0:4873 # 允许外网访问,默认是 localhost:4873

配置字段详细说明

字段 说明 可选值

storage 包存储路径 文件系统路径

plugins 插件目录路径 文件系统路径

auth.htpasswd.file 用户密码文件路径 文件路径

auth.htpasswd.max_users 最大用户数 正整数 / -1(禁止注册)

uplinks 上游代理配置 多个上游地址

packages.*.access 访问权限 all / authenticated / anonymous / 具体用户名 packages.* .publish 发布权限 authenticated / 具体用户名

packages.*.proxy 代理上游 uplinks 中定义的名称

listen 监听地址 localhost:4873 / 0.0.0.0:4873

3.4 HTTPS 和反向代理配置

方式一:直接配置 HTTPS

yaml

config.yaml

listen:

https:

key: /path/to/verdaccio-key.pem

cert: /path/to/verdaccio-cert.pem

ca: /path/to/verdaccio-csr.pem

public_url: https://registry.example.com:4873/

**证书生成 **:

bash

openssl genrsa -out verdaccio-key.pem 2048

openssl req -new -sha256 -key verdaccio-key.pem -out verdaccio-csr.pem

openssl x509 -req -in verdaccio-csr.pem -signkey verdaccio-key.pem -out verdaccio-cert.pem

方式二:Nginx 反向代理(推荐)

nginx

HTTP 配置

server {

listen 80;

server_name registry.example.com;

复制代码
location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://127.0.0.1:4873/;
    proxy_redirect off;
}

}

HTTPS 配置

server {

listen 443 ssl http2;

server_name registry.example.com;

复制代码
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://127.0.0.1:4873/;
    proxy_read_timeout 600;
    proxy_redirect off;
}

}

**Docker 部署时的环境变量 **:

bash

docker run -d

-e VERDACCIO_PUBLIC_URL='https://registry.example.com'

-p 4873:4873

verdaccio/verdaccio:6.x

3.5 客户端配置与使用

用户注册和登录

bash

注册用户(私服端需要启用注册功能)

npm adduser --registry http://localhost:4873

查看当前登录用户

npm whoami --registry http://localhost:4873

登出

npm logout --registry http://localhost:4873

发布私有包

步骤一:初始化项目

bash

创建项目目录

mkdir my-private-package

cd my-private-package

初始化 package.json

npm init -y

步骤二:修改 package.json

json

{

"name": "@your-scope/my-private-package",

"version": "1.0.0",

"private": false,

"description": "私有包示例",

"main": "index.js"

}

步骤三:发布

bash

登录(如果未登录)

npm login --registry http://localhost:4873

发布

npm publish --registry http://localhost:4873

安装私有包

bash

方式一:临时指定源

npm install @your-scope/my-private-package --registry http://localhost:4873

方式二:配置作用域(推荐)

npm config set @your-scope:registry http://localhost:4873

npm install @your-scope/my-private-package

3.6 使用 NRM 管理镜像源

安装 NRM

bash

全局安装

npm install -g nrm

解决 open 包兼容性问题(Node 16+)

npm install -g nrm open@8.4.2

NRM 常用命令

bash

查看所有镜像源

nrm ls

切换镜像

nrm use taobao

添加自定义镜像

nrm add company-npm http://npm.company.com:4873

删除镜像

nrm del company-npm

测试镜像速度

nrm test taobao

添加私服到 NRM

bash

添加 Verdaccio 私服

nrm add verdaccio http://localhost:4873

切换到私服

nrm use verdaccio

验证

nrm ls

四、Nexus 企业级方案

4.1 Nexus 核心概念

Nexus 支持三种仓库类型:

仓库类型 用途 配置要点

Hosted(托管) 存储私有包 Deployment policy 设为 Allow redeploy

Proxy(代理) 代理远程仓库 Remote storage 填写上游地址

Group(组) 聚合多个仓库 添加 Hosted 和 Proxy 到 Members

4.2 Nexus 配置流程

步骤一:创建 Blob 存储

plaintext

设置 → Blob Stores → Create blob store

名称:npm-blob

类型:File

步骤二:创建 Hosted 仓库

plaintext

设置 → Repository → Repositories → Create repository

选择:npm (hosted)

名称:npm-private

Blob store:npm-blob

Deployment policy:Allow redeploy(允许覆盖发布)

步骤三:创建 Proxy 仓库

plaintext

设置 → Repository → Repositories → Create repository

选择:npm (proxy)

名称:npm-proxy

Remote storage:https://registry.npmmirror.com/

Blob store:npm-blob

步骤四:创建 Group 仓库

plaintext

设置 → Repository → Repositories → Create repository

选择:npm (group)

名称:npm-group

Blob store:npm-blob

Members:

  • npm-private
  • npm-proxy

4.3 Nexus 客户端配置

bash

配置为组仓库地址

npm config set registry http://nexus.example.com:8081/repository/npm-group/

登录

npm login --registry=http://nexus.example.com:8081/repository/npm-private/

发布到私有仓库

npm publish --registry=http://nexus.example.com:8081/repository/npm-private/

五、作用域包(Scoped Packages)深度解析

5.1 作用域包的概念

作用域包是 npm 提供的命名空间机制,格式为 @scope/package-name:

**解决命名冲突 **:包名只需在作用域内唯一

**清晰的归属关系 **:@babel/core 明确属于 babel 组织

**支持私有化 **:天然适合企业私有包管理

5.2 作用域包的配置方式

方式一:通过 .npmrc 配置(推荐)

在项目根目录创建 .npmrc 文件:

ini

作用域路由:@your-scope 开头的包走私有仓库

@your-scope:registry=https://nexus.example.com/repository/npm-private/

认证信息

//nexus.example.com/repository/npm-private/:_authToken=your-token-here

强制认证

//nexus.example.com/repository/npm-private/:always-auth=true

其他包走公共源

registry=https://registry.npmjs.org

方式二:命令行配置

bash

设置作用域对应的 registry

npm config set @your-scope:registry http://localhost:4873

验证配置

npm config get @your-scope:registry

5.3 发布作用域包

发布到公共仓库

bash

初始化时指定作用域

npm init --scope=@your-org

首次发布必须指定访问权限

npm publish --access public

发布到私有仓库

bash

package.json

{

"name": "@your-org/private-package"

}

发布(私有包默认为 restricted)

npm publish --registry http://localhost:4873

5.4 .npmrc 配置优先级

级别 位置 优先级 说明

项目级 项目根目录/.npmrc 最高 推荐用于项目特定配置

用户级 ~/.npmrc 中 影响当前用户所有项目

全局级 npm config -g 低 影响系统所有用户

默认级 npm 内置 最低 公共仓库 https://registry.npmjs.org

**配置合并规则 **:优先级高的配置会覆盖优先级低的配置。

六、生产环境最佳实践

6.1 安全配置建议

Verdaccio 安全配置

yaml

禁用公开注册

auth:

htpasswd:

max_users: -1 # -1 表示禁止新用户注册

私有包移除代理(避免依赖混淆攻击)

packages:

'@your-scope/*':

access: $authenticated

publish: $authenticated

unpublish: $authenticated

移除 proxy: npmjs

限制上传包大小

server:

max_body_size: 10mb

启用审计日志

middlewares:

audit:

enabled: true

Nexus 安全配置

plaintext

Security → Anonymous Access:关闭匿名访问

Security → Realms:添加 npm Bearer Token Realm

Security → Roles:创建细粒度权限角色

6.2 备份与恢复

Verdaccio 备份

bash

备份存储目录

tar -czf verdaccio-backup-$(date +%Y%m%d).tar.gz /data/verdaccio/storage

备份配置文件

tar -czf verdaccio-config-backup-$(date +%Y%m%d).tar.gz /data/verdaccio/conf

Nexus 备份

bash

备份 nexus-data 目录

tar -czf nexus-backup-$(date +%Y%m%d).tar.gz /path/to/nexus-data

6.3 高可用部署

使用 Docker Swarm

yaml

version: '3.8'

services:

verdaccio:

image: verdaccio/verdaccio:6.x

deploy:

replicas: 3

update_config:

parallelism: 1

delay: 10s

restart_policy:

condition: on-failure

ports:

  • "4873:4873"

volumes:

  • verdaccio-storage:/verdaccio/storage

  • ./config:/verdaccio/conf

networks:

  • verdaccio-net

volumes:

verdaccio-storage:

driver: local

networks:

verdaccio-net:

driver: overlay

使用 Kubernetes + Helm

bash

添加 Helm 仓库

helm repo add verdaccio https://charts.verdaccio.org

helm repo update

部署

helm install npm-registry verdaccio/verdaccio

--namespace npm

--create-namespace

-f production-values.yaml

6.4 CI/CD 集成

GitHub Actions 示例

yaml

name: Publish to Private NPM

on:

push:

tags:

  • 'v*'

jobs:

publish:

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v3

    复制代码
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '20'
    
    - name: Configure .npmrc
      run: |
        echo "@your-scope:registry=${{ secrets.NPM_REGISTRY }}" >> ~/.npmrc
        echo "//${{ secrets.NPM_REGISTRY }}/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc
        echo "//${{ secrets.NPM_REGISTRY }}/:always-auth=true" >> ~/.npmrc
    
    - name: Publish
      run: npm publish
      env:
        NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

七、常见问题排查

7.1 Verdaccio 常见问题

问题 原因 解决方案

无法从外网访问 listen 配置为 localhost 改为 0.0.0.0:4873

发布 401 错误 未登录或权限不足 执行 npm login 重新登录

npm ERR! code E401 认证失败 检查 .npmrc 中的 Token 是否正确

安装包时卡住 上游代理配置错误 检查 uplinks 配置或更换上游源

PM2 启动失败 路径问题 使用 pm2 start \which verdaccio``

7.2 Nexus 常见问题

问题 原因 解决方案

401 Unauthorized Realms 未配置 添加 npm Bearer Token Realm

发布 400 错误 Hosted 仓库未允许 redeploy 修改 Deployment policy 为 Allow redeploy

找不到包 Group 仓库配置错误 检查 Members 列表是否包含所有仓库

Token 失效 Token 过期 重新登录获取新 Token

7.3 NPM 客户端常见问题

.npmrc 配置问题

**问题 1 **:401 认证失败

**排查步骤 **:

bash

检查当前 registry

npm config get registry

检查作用域配置

npm config get @your-scope:registry

验证 token

npm config get //registry.example.com/:_authToken

**问题 2 **:包发布到了错误的位置

**原因 **:作用域配置缺失

**解决 **:

bash

在 .npmrc 中显式配置

@your-scope:registry=https://your-private-registry.com/

八、性能优化建议

8.1 Verdaccio 优化

yaml

日志级别优化(生产环境)

log:

type: file

path: ./logs/verdaccio.log

format: pretty

level: warn

上游超时优化

uplinks:

npmjs:

url: https://registry.npmjs.org/

timeout: 60s

maxage: 30d # 缓存有效期

连接保持优化

server:

keepAliveTimeout: 60

8.2 Nexus 优化

plaintext

设置 → Repository → Cleanup Policies

  • 启用自动清理策略
  • 基于时间清理:保留最近 30 天
  • 基于版本数清理:每个包保留最近 10 个版本

九、技术演进路线

9.1 Sinopia → Verdaccio

**Sinopia **:早期流行的私服工具,2015 年停止维护

**Verdaccio **:Sinopia 的分支项目,持续更新维护

**兼容性 **:Verdaccio 5.x 仍支持 Sinopia 插件,6.x 已移除支持

9.2 版本选择建议

Verdaccio 版本 Node.js 版本 推荐场景

4.x Node 14 遗留系统维护

5.x Node 16-18 稳定生产环境

6.x Node 18-20 LTS 新项目推荐

十、总结与建议

快速决策树

plaintext

你的团队规模?

├─ 小型团队(< 10 人)

│ └─ Verdaccio + Docker Compose

├─ 中型团队(10-50 人)

│ └─ Verdaccio + Docker Swarm / Kubernetes

└─ 大型团队(> 50 人)

└─ Nexus(如果已有)或 Verdaccio(纯前端)

推荐配置模板

**小型团队 Verdaccio 配置 **:

yaml

storage: ./storage

plugins: ./plugins

web:

title: 私有 NPM 仓库

auth:

htpasswd:

file: ./htpasswd

max_users: 10

uplinks:

npmjs:

url: https://registry.npmmirror.com/

packages:

'@company/*':

access: $authenticated

publish: $authenticated

proxy: npmjs

'** ':

access: $all

publish: $authenticated

proxy: npmjs

server:

keepAliveTimeout: 60

listen:

  • 0.0.0.0:4873

log:

type: stdout

format: pretty

level: http

下一步行动

评估需求:根据团队规模和现有基础设施选择方案

快速验证:使用 Docker 快速部署 Verdaccio 验证可行性

渐进式迁移:从公共包代理开始,逐步引入私有包

建立规范:制定包命名规范、发布流程、权限管理策略

监控与优化:建立监控体系,持续优化性能和稳定性

附录:参考资料

Verdaccio 官方文档

Nexus 官方文档

npm 作用域包文档

NRM GitHub 仓库

相关推荐
丝斯20112 小时前
AI学习笔记整理(77)——Python学习6
笔记·学习
正经人_x2 小时前
学习日记35:Rep3d
学习
九成宫2 小时前
IT项目管理期末复习——Chapter 4 项目综合管理
笔记·项目管理·软件工程
抠脚学代码2 小时前
Linux开发--> UBoot学习
linux·学习·uboot
zero15972 小时前
Python 8天极速入门笔记(大模型工程师专用):第二篇-Python基础入门(变量、数据类型、print输出)
开发语言·笔记·python
客梦2 小时前
数据库基础
数据库·笔记
人还是要有梦想的3 小时前
QT的基本学习路线
开发语言·qt·学习
路小雨~3 小时前
经典神经网络结构学习笔记
rnn·学习·机器学习·cnn·ann
Hammer_Hans3 小时前
DFT笔记31
笔记