我写这篇文章的起因是 npm 安装软件包网速慢,如果使用淘宝的镜像源,一些非主流的包,更新不及时,还出现下载失败。如果使用官方源,网速就太慢了。
我将在这里分享自己的实践经验。
选型
verdaccio
因为考虑单纯为 npm 做本地镜像源,考虑使用 verdaccio,想做成一个后台运行的服务,可以开机自启动,就考虑到 PM2,但是有个问题,如果想 pm2 startup
生效,就必须以 root 用户运行这个命令。对系统侵入性太大了。
就考虑以 docker 的形式运行 verdaccio。
第一版 docker-compose.yml 文件:
version: '3.1'
services:
verdaccio:
image: verdaccio/verdaccio
restart: always
container_name: 'verdaccio'
ports:
- '4873:4873'
volumes:
- './storage:/verdaccio/storage'
- './config:/verdaccio/conf'
- './plugins:/verdaccio/plugins'
创建 config 文件夹,在里面创建 config.yaml 文件:
mkdir config
cd config
touch config.yaml
config.yaml 文件内容:
#
# This is the default config file. It allows all users to do anything,
# so don't use it on production systems.
#
# Look here for more config file examples:
# https://github.com/verdaccio/verdaccio/tree/master/conf
#
# path to a directory with all packages
storage: /verdaccio/storage
# path to a directory with plugins to include
plugins: /verdaccio/plugins
# print logs
# logs: ./logs
web:
title: Verdaccio
# comment out to disable gravatar support
# gravatar: false
# by default packages are ordercer ascendant (asc|desc)
# sort_packages: asc
# convert your UI to the dark side
# darkMode: true
# HTML tags injected after manifest <scripts/>
# scriptsBodyAfter:
# - '<script type="text/javascript" src="https://my.company.com/customJS.min.js"></script>'
# HTML tags injected before ends </head>
# metaScripts:
# - '<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>'
# - '<script type="text/javascript" src="https://browser.sentry-cdn.com/5.15.5/bundle.min.js"></script>'
# - '<meta name="robots" content="noindex" />'
# HTML tags injected first child at <body/>
# bodyBefore:
# - '<div id="myId">html before webpack scripts</div>'
# Public path for template manifest scripts (only manifest)
# publicPath: http://somedomain.org/
# translate your registry, api i18n not available yet
# i18n:
# list of the available translations https://github.com/verdaccio/ui/tree/master/i18n/translations
# web: en-US
auth:
htpasswd:
file: ./htpasswd
# Maximum amount of users allowed to register, defaults to "+inf".
# You can set this to -1 to disable registration.
# max_users: 1000
# a list of other known repositories we can talk to
uplinks:
npmjs:
url: https://registry.npmjs.org/
taobao:
url: https://registry.npmmirror.com/
tencent:
url: https://mirrors.cloud.tencent.com/npm/
packages:
'@*/*':
# scoped packages
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
'**':
# allow all users (including non-authenticated users) to read and
# publish all packages
#
# you can specify usernames/groupnames (depending on your auth plugin)
# and three keywords: "$all", "$anonymous", "$authenticated"
access: $all
# allow all known users to publish/publish packages
# (anyone can register by default, remember?)
publish: $authenticated
unpublish: $authenticated
# if package is not available locally, proxy requests to 'npmjs' registry
proxy: npmjs
server:
# deprecated
keepAliveTimeout: 60
# rateLimit:
# windowMs: 1000
# max: 10000
middlewares:
audit:
enabled: true
listen: 0.0.0.0:4873
# log settings
logs:
# Logger as STDOUT
{ type: stdout, format: pretty, level: http }
# Logger as STDOUT as JSON
# { type: stdout, format: json, level: http }
# Logger as STDOUT as JSON
# { type: stdout, format: pretty-timestamped, level: http }
# Logger as STDOUT as custom prettifier
# { type: stdout, plugin: { dest: '@verdaccio/logger-prettify' : options: { foo: 1, bar: 2}}, level: http }
# Logger as file
# { type: file, path: verdaccio.log, level: http}
# FIXME: this should be documented
# More info about log rotation https://github.com/pinojs/pino/blob/master/docs/help.md#log-rotation
# This affect the web and api (not developed yet)
i18n:
web: en-US
意外
启动容器
docker-compose up
报错 permission denied, mkdir
第二版
version: '3.1'
services:
verdaccio:
image: verdaccio/verdaccio
restart: always
user: 1000:1000
container_name: 'verdaccio'
ports:
- '4873:4873'
volumes:
- './storage:/verdaccio/storage'
- './config:/verdaccio/conf'
- './plugins:/verdaccio/plugins'
通过修改文件夹的所有者
id
uid=1000(luo) gid=1000(luo) 组=1000(luo),4(adm),24(cdrom),27(sudo)
sudo chown -R 1000:100 storage/ config/ plugins/
就解决问题了,user 的设置要你自己 Linux 服务器上一致,通过 id
命令获得,格式为 user: uid: gid
。
启动
docker-compose up -d
在网页浏览器里输入 http://ip:4873
,然后再终端输入,进行设置,使用本地的软件源
npm set registry http://ip:4873/
Nexus 3
选一个通用型软件镜像服务(Nexus 3),大部分的开发语言都支持,一次投入,多次收益,如图:
docker-compose.yml 文件
version: "3.6"
services:
nexus:
image: sonatype/nexus3:3.49.0
restart: always
environment:
- INSTALL4J_ADD_VM_PARAMS=-Xms2g -Xmx2g -XX:MaxDirectMemorySize=2g -Djava.util.prefs.userRoot=/nexus-data/javaprefs -Duser.time volumes:
- ./nexus-data:/nexus-data
ports:
- "8081:8081"
Java 应用要限制一下内存,避免把宿主机的内存全吃掉,可根据实际情况调整。
启动
docker-compose up -d
还是遇到权限问题
mkdir: cannot create directory '../sonatype-work/nexus3/log': Permission denied
mkdir: cannot create directory '../sonatype-work/nexus3/tmp': Permission denied
解决办法:参考资料
sudo chown -R 200 ~/dockerVolume/nexus
重新启动
docker-compose up -d
获得 admin 的登录密码
# 在启动应用的目录中执行
cat nexus-data/admin.password
# 或者直接使用 Docker CLI 执行容器命令
docker exec -it nexus.lab.io cat /nexus-data/admin.password
通过网页浏览器输入 http://ip:8081
访问管理后台。在输入了正确的初始账号和密码后,新版软件会人性化的引导我们设置新密码,以及设置是否允许匿名用户使用。
如果是个人使用,或者团队在内网使用,可以勾选“允许匿名访问”。
然后建个 npm(hosted) 和 npm(proxy),组成一个 npm(grounp),
具体教程可以看 这个,但不要像它里面开放多个端口,没必要。
设置 npm 使用本地软件源(根据你的服务器的实际 IP 或者域名进行修改)
npm set registry http://192.168.2.114:8081/repository/npm-group/
总结
docker 存储方面的权限设置是个问题,解决办法:
- 自己构建 docker 镜像,从根源上解决问题,这难度比较大,要自己不断学习尝试。
- 多查找网络资料,通过设置解决。
docker 部署方便,避免对系统的入侵,具有良好的隔离性,并且多平台支持,但是在权限安全方面还有很多要注意的。
如果你对这篇文章有任何疑问,或者如果你想和我探讨更多技术内容,欢迎和我联系。我的邮箱是:luojiyin@hotmail.com。