# 搭建 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
3
4
# 2. 创建配置文件
# 创建 config.yaml
sudo vim /srv/verdaccio/conf/config.yaml
1
2
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
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
2
3
4
5
6
7
8
# 4. 查看状态
# 查看容器状态
docker ps | grep verdaccio
# 查看日志
docker logs -f verdaccio
1
2
3
4
5
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
3
4
5
6
7
8
9
10
# 2. 安装 Verdaccio
# 全局安装
npm install -g verdaccio
# 验证安装
verdaccio --version
1
2
3
4
5
2
3
4
5
# 3. 启动服务
# 默认启动(http://localhost:4873)
verdaccio
# 指定端口
verdaccio --listen 5000
# 后台运行
nohup verdaccio --listen 5000 &
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 4. 配置 Systemd 服务
# 创建服务文件
sudo vim /etc/systemd/system/verdaccio.service
1
2
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
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
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
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
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
2
3
4
5
6
7
8
# 查看用户
# 查看 htpasswd 文件
cat /srv/verdaccio/storage/htpasswd
1
2
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
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
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
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
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
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
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
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
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
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
2
3
4
5
6
7
8
# 📈 监控和维护
# 健康检查
# 检查服务状态
curl http://localhost:4873/-/ping
# 查看包统计
curl http://localhost:4873/-/stats
1
2
3
4
5
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
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
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
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
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
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
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
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
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
2
3
4
5
6
7
8
# 📚 相关文档
- GitLab 服务器 - 代码托管
- NuGet 服务器 - 后端包管理
- 开发规范 - 版本管理
- 编码规范 - 前端规范
# 🔗 参考链接
- Verdaccio 官方文档 (opens new window)
- Verdaccio GitHub (opens new window)
- Npm 官方文档 (opens new window)
- Npm 私有源最佳实践 (opens new window)
最后更新: 2022-08-07
← 搭建 Nuget 服务器 MSBuild →