# 搭建 Npm 私有服务器

DarkM 使用 Verdaccio 搭建私有 Npm 服务器,用于管理和分发前端包。


# 📋 为什么搭建私有 Npm 服务器?

场景 说明
私有包管理 内部组件库不对外公开
加速下载 内网缓存,下载速度快
离线开发 无外网环境也能安装包
权限控制 控制包的发布和访问权限
带宽节省 减少外网依赖,节省带宽

# 🎯 Verdaccio 特点

特性 说明
轻量级 基于 Node.js,资源占用少
易安装 npm install -g verdaccio
兼容性好 完全兼容 Npm/Yarn
Web 界面 友好的 Web UI
用户管理 支持用户注册和权限控制
缓存功能 代理官方源,加速下载
插件系统 支持认证/存储/中间件插件

# 🚀 安装部署

# 方式一:Docker 安装(推荐)

# 1. 创建目录

# 创建 Verdaccio 数据目录
sudo mkdir -p /srv/verdaccio/{storage,plugins}
sudo mkdir -p /srv/verdaccio/conf
sudo chmod -R 755 /srv/verdaccio
1
2
3
4

# 2. 创建配置文件

# 创建 config.yaml
sudo vim /srv/verdaccio/conf/config.yaml
1
2

配置内容:

storage: /verdaccio/storage
auth:
  htpasswd:
    file: /verdaccio/htpasswd
    max_users: 100
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
packages:
  '@darkm/*':
    access: $all
    publish: $authenticated
    unpublish: $authenticated
  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs
server:
  keepAliveTimeout: 60
log: { type: stdout, format: pretty, level: http }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 3. 启动容器

docker run --detach \
  --name verdaccio \
  --restart always \
  --publish 4873:4873 \
  --volume /srv/verdaccio/conf:/verdaccio/conf \
  --volume /srv/verdaccio/storage:/verdaccio/storage \
  --volume /srv/verdaccio/plugins:/verdaccio/plugins \
  verdaccio/verdaccio:latest
1
2
3
4
5
6
7
8

# 4. 查看状态

# 查看容器状态
docker ps | grep verdaccio

# 查看日志
docker logs -f verdaccio
1
2
3
4
5

# 5. 访问管理界面

浏览器访问:http://localhost:4873


# 方式二:Npm 安装

# 1. 安装 Node.js

# Ubuntu
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs

# macOS
brew install node

# 验证安装
node -v
npm -v
1
2
3
4
5
6
7
8
9
10

# 2. 安装 Verdaccio

# 全局安装
npm install -g verdaccio

# 验证安装
verdaccio --version
1
2
3
4
5

# 3. 启动服务

# 默认启动(http://localhost:4873)
verdaccio

# 指定端口
verdaccio --listen 5000

# 后台运行
nohup verdaccio --listen 5000 &
1
2
3
4
5
6
7
8

# 4. 配置 Systemd 服务

# 创建服务文件
sudo vim /etc/systemd/system/verdaccio.service
1
2

服务配置:

[Unit]
Description=Verdaccio NPM Registry
After=network.target

[Service]
Type=simple
User=nobody
ExecStart=/usr/bin/verdaccio
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
10
11
12
13

启动服务:

# 重载配置
sudo systemctl daemon-reload

# 启动服务
sudo systemctl start verdaccio

# 设置开机自启
sudo systemctl enable verdaccio

# 查看状态
sudo systemctl status verdaccio
1
2
3
4
5
6
7
8
9
10
11

# ⚙️ 配置详解

# 完整配置文件

# /srv/verdaccio/conf/config.yaml

# 存储路径
storage: /verdaccio/storage

# 认证配置
auth:
  htpasswd:
    file: /verdaccio/htpasswd
    # 最大用户数(-1 表示无限制)
    max_users: 100

# 上游服务器(代理官方源)
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
    timeout: 30s
    fail_timeout: 10m
    max_fails: 20
  yarn:
    url: https://registry.yarnpkg.com/

# 包权限配置
packages:
  # DarkM 组织包(私有)
  '@darkm/*':
    access: $all           # 所有用户可下载
    publish: $authenticated # 仅认证用户可发布
    unpublish: $authenticated
    proxy: npmjs           # 代理官方源
  
  # 作用域包
  '@company/*':
    access: $authenticated
    publish: $authenticated
    unpublish: $authenticated
  
  # 所有其他包
  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs

# 服务器配置
server:
  keepAliveTimeout: 60
  # 自定义 HTTP 头
  headers:
    X-Served-By: verdaccio
  
# 日志配置
log:
  type: stdout
  format: pretty
  level: http
  
  # 文件日志
  - {type: file, path: /verdaccio/logs/verdaccio.log, level: info}

# 中间件配置
middlewares:
  audit:
    enabled: true

# 实验性功能
experiments:
  # 启用 token 认证
  token: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

# 权限说明

变量 说明
$all 所有用户(包括匿名用户)
$anonymous 匿名用户
$authenticated 已认证用户
user1,user2 指定用户

# 👥 用户管理

# 创建用户

# 添加用户
npm adduser --registry http://localhost:4873

# 输入信息
Username: alex
Password: ********
Email: (this IS public) alex@woowis.com
1
2
3
4
5
6
7

# 登录

# 登录到私有源
npm login --registry http://localhost:4873

# 或使用配置文件
cat > ~/.npmrc << EOF
registry=http://localhost:4873
//localhost:4873/:_authToken="token-here"
EOF
1
2
3
4
5
6
7
8

# 查看用户

# 查看 htpasswd 文件
cat /srv/verdaccio/storage/htpasswd
1
2

# 📦 发布包

# 准备包

# 创建包目录
mkdir -p ~/packages/darkm-utils
cd ~/packages/darkm-utils

# 初始化 package.json
npm init -y

# 编辑 package.json
cat > package.json << EOF
{
  "name": "@darkm/utils",
  "version": "1.0.0",
  "description": "DarkM 工具库",
  "main": "index.js",
  "author": "Alex Han",
  "license": "MIT",
  "publishConfig": {
    "registry": "http://localhost:4873"
  }
}
EOF

# 创建入口文件
cat > index.js << EOF
module.exports = {
  formatDate: (date) => {
    return date.toISOString().split('T')[0];
  },
  capitalize: (str) => {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
};
EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 发布包

# 登录
npm login --registry http://localhost:4873

# 发布包
npm publish --registry http://localhost:4873

# 发布 scoped 包
npm publish --access public --registry http://localhost:4873
1
2
3
4
5
6
7
8

# 查看已发布的包

浏览器访问:http://localhost:4873/-/web/package/@darkm%2Futils


# 🔧 配置 Npm 源

# 全局配置

# 设置私有源
npm config set registry http://localhost:4873

# 查看当前源
npm config get registry

# 添加用户
npm adduser

# 登录
npm login
1
2
3
4
5
6
7
8
9
10
11

# 项目级配置

# 在项目根目录创建 .npmrc
cat > .npmrc << EOF
registry=http://localhost:4873
//localhost:4873/:_authToken="your-token-here"
EOF
1
2
3
4
5

# 使用 Nvm 管理多个源

# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# 使用别名切换源
alias npm-public='npm config set registry https://registry.npmjs.org'
alias npm-private='npm config set registry http://localhost:4873'

# 使用
npm-public  # 切换到官方源
npm-private # 切换到私有源
1
2
3
4
5
6
7
8
9
10

# 📊 代理官方源

# 配置代理

# config.yaml
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
    timeout: 30s
  
  taobao:
    url: https://registry.npmmirror.com/
    timeout: 30s

packages:
  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs  # 默认代理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 缓存管理

# 查看缓存目录
ls -lh /srv/verdaccio/storage/

# 清理缓存
rm -rf /srv/verdaccio/storage/.cache/

# 预下载常用包
npm install lodash --registry http://localhost:4873
npm install react --registry http://localhost:4873
npm install vue --registry http://localhost:4873
1
2
3
4
5
6
7
8
9
10

# 🔒 安全配置

# 1. 启用 HTTPS

server {
    listen 443 ssl;
    server_name npm.woowis.com;

    ssl_certificate /etc/ssl/certs/npm.woowis.com.crt;
    ssl_certificate_key /etc/ssl/private/npm.woowis.com.key;

    location / {
        proxy_pass http://localhost:4873;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 2. 配置 LDAP 认证

auth:
  ldap:
    type: ldap
    client_opts:
      url: ldap://ldap.woowis.com
      baseDN: dc=woowis,dc=com
    search:
      bindDN: cn=admin,dc=woowis,dc=com
      bindCredentials: password
      attributes:
        uid: cn
        mail: mail
1
2
3
4
5
6
7
8
9
10
11
12

# 3. 限制访问

# 只允许内网访问
location / {
    allow 192.168.0.0/16;
    allow 10.0.0.0/8;
    deny all;
    
    proxy_pass http://localhost:4873;
}
1
2
3
4
5
6
7
8

# 📈 监控和维护

# 健康检查

# 检查服务状态
curl http://localhost:4873/-/ping

# 查看包统计
curl http://localhost:4873/-/stats
1
2
3
4
5

# 日志查看

# Docker 方式
docker logs -f verdaccio

# Systemd 方式
journalctl -u verdaccio -f

# 文件日志
tail -f /srv/verdaccio/logs/verdaccio.log
1
2
3
4
5
6
7
8

# 备份数据

# 备份存储目录
tar -czf /backup/verdaccio-$(date +%Y%m%d).tar.gz \
  /srv/verdaccio/storage \
  /srv/verdaccio/conf
1
2
3
4

# 性能优化

# 增加缓存
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
    cache: true
    cache_size: 10gb  # 缓存大小

# 启用压缩
server:
  compress: true
1
2
3
4
5
6
7
8
9
10

# 🔗 与 DarkM 集成

# 前端项目配置

// package.json
{
  "name": "darkm-module-admin",
  "version": "1.0.2",
  "publishConfig": {
    "registry": "http://npm.woowis.com"
  }
}
1
2
3
4
5
6
7
8

# CI/CD 自动发布

.gitlab-ci.yml 示例:

stages:
  - install
  - build
  - publish

variables:
  NPM_REGISTRY: "http://npm.woowis.com"

install:
  stage: install
  script:
    - npm install --registry $NPM_REGISTRY

build:
  stage: build
  script:
    - npm run build

publish:
  stage: publish
  script:
    - npm config set registry $NPM_REGISTRY
    - npm publish --access public
  only:
    - tags
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# ❓ 常见问题

# 1. 发布失败(401 未授权)

问题: npm ERR! 401 Unauthorized

解决:

# 重新登录
npm logout --registry http://localhost:4873
npm login --registry http://localhost:4873

# 检查权限配置
cat /srv/verdaccio/conf/config.yaml | grep publish
1
2
3
4
5
6

# 2. 包已存在

问题: npm ERR! You cannot publish over the previously published versions

解决:

# 升级版本号
npm version patch  # 1.0.0 -> 1.0.1
npm version minor  # 1.0.1 -> 1.1.0
npm version major  # 1.1.0 -> 2.0.0

# 重新发布
npm publish --registry http://localhost:4873
1
2
3
4
5
6
7

# 3. 下载速度慢

解决:

# 使用内网地址
npm config set registry http://192.168.1.100:4873

# 清除缓存
npm cache clean --force

# 检查网络连接
ping npm.woowis.com
1
2
3
4
5
6
7
8

# 4. Docker 容器启动失败

问题: container exited with code 1

解决:

# 检查配置文件
docker exec verdaccio cat /verdaccio/conf/config.yaml

# 检查存储权限
docker exec verdaccio ls -la /verdaccio/storage

# 修复权限
sudo chown -R 100:101 /srv/verdaccio
1
2
3
4
5
6
7
8

# 📚 相关文档


# 🔗 参考链接


最后更新: 2022-08-07