npm私服搭建与包发布

需求与背景

需求

  • 公司开发环境与外网隔绝,需要搭建内网私有npm库,确保私密性
  • 确保npm服务快速、稳定,减少开发人员和CI服务器的重复下载量并提高下载速度
  • 控制npm模块质量和安全,对于下载、发布npm包有对应的权限管理

当下流行的解决方案

  • 使用 Nexus 搭建 npm 私服

    Nexus仓库管理平台支持范围广泛,可用于maven、npm等仓库。目前Nexus Repository Manager更新到了3,查看官方文档

  • 使用 Sinopia 搭建 npm 私服

    Sinopia是一个零配置的私有的带缓存功能的npm包管理工具。

搭建过程

使用Nexus

  • 下载解压

    官方下载链接](help.sonatype.com/repomanager…),执行:

    $ wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz #下载
    $ sudo mv latest-unix.tar.gz /opt/nexus3.tar.gz #移动到 /opt 目录
    $ sudo tar -xzvf nexus3.tar.gz #解压
    复制代码

    注意运行Nexus需要Java 8 运行时环境(JRE),请自行安装。

  • 创建运行用户

    单独创建一个 nexus 用户用来运行

    # 创建用户、指定用户目录、授权
    $ sudo useradd -d /home/nexus -m nexus
    $ sudo chown -R nexus:nexus /home/nexus
    $ sudo chown -R nexus:nexus /opt/nexus-3.15.2-01
    $ sudo chown -R nexus:nexus /opt/sonatype-work/
    复制代码

    修改运行用户配置项:修改 /opt/nexus-3.15.2-01/bin 目录下的配置文件nexus.rc为 run_as_user="nexus"

  • 运行

    修改端口指8073并开放iptables防火墙,对/opt/sonatype-work/nexus3/etc/nexus.properties文件进行修改:

    # Jetty section                                                     
    application-port=8073
    application-host=0.0.0.0                                                                 # nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml                                               
    # nexus-context-path=/                                                                   # Nexus section                                                                         # nexus-edition=nexus-pro-edition                                                       # nexus-features=\                                                                       #  nexus-pro-feature  
    复制代码

    启动服务,以下为nexus服务命令:

    # 启动 nexus 服务
    $ sudo service nexus start
    # 重启 nexus 服务
    $ sudo service nexus restart
    # 停止 nexus 服务
    $ sudo service nexus stop
    # 查看 nexus 服务状态
    $ sudo service nexus status 
    复制代码

    查看日志检查服务状态:

    $ tail -f /opt/sonatype-work/nexus3/log/nexus.log
    复制代码

    至此,nexus 服务已搭建完毕!可使用默认账号admin/admin123 登录ip:8073后对npm仓库进行管理

  • 仓库管理

    创建仓库,npm 仓库有三种,这三种我们都需要创建

  1. npm(proxy) - 代理npm仓库

    将公共 npm 服务器的资源代理缓存,减少重复下载,加快开发人员和CI服务器的下载速度。

    创建时需填写Name(npm-external)和Remote Storage(公有库地址,填写官方或淘宝镜像,https://registry.npmjs.org/)。

    该仓库地址为:http://ip:8073/repository/npm-external/

  2. npm(hosted) - 私有npm仓库

    用于 上传自己的npm包 以及第三方npm包。

    创建时只需填写Name(npm-internal)。

    该仓库地址为:http://ip:8073/repository/npm-internal/

    请注意:发布包时请将registry设为该地址。

  3. npm(group) - npm仓库组

    用于将多个内部或外部 npm 仓库统一为一个 npm仓库。可以新建一个npm仓库组将 上面两个刚刚创建的两个 npm 仓库都添加进去。这样可以通过这个 npm仓库组,既可以访问 公有npm仓库 又可以访问自己的 私有npm仓库。

    创建时需填写Name(npm-all),然后选择需要添加到组里的 其他 npm 仓库(npm-externalnpm-internal)。

    该仓库地址为:http://ip:8073/repository/npm-all/

    请注意:安装包以及卸载包时请将registry设为该地址。

  • 用户管理

    将包发布到nexus npm仓库需要设置一下 Nexus Repository Manager 的权限。否则无法登陆到我们的私服。在Security->Realms栏目里,将npm Bearer Token Realm 选入Active。

之后我们需要在Security->Users栏目里添加用户,只有这样添加的用户才可以发布包。经测试,在客户端使用 npm adduser 创建的用户没有发布权限。

使用Sinopia

  • 服务器上安装node

    Node 官网已经把 linux 下载版本更改为已编译好的版本了,我们可以直接下载解压后使用,下载链接

    我们选择node-v11.9.0-linux-x64.tar.gz这个版本:

    $ wget https://nodejs.org/dist/v11.9.0/node-v11.9.0-linux-x64.tar.gz   #下载
    $ tar xf node-v11.9.0-linux-x64.tar.gz       #解压
    $ cd node-v11.9.0-linux-x64/                 #进入解压目录
    $ ./bin/node -v                              #执行node命令 查看版本
    v11.9.0
    复制代码

    使用ln命令设置软链接到/usr/local/bin目录,/usr/local/bin是给用户放置自己的可执行程序的地方:

    ln -s /usr/local/node-v11.9.0-linux-x64/bin/npm   /usr/local/bin/ 
    ln -s /usr/local/node-v11.9.0-linux-x64/bin/node   /usr/local/bin/
    复制代码
  • 服务器上安装Sinopia

    使用默认npmjs.org registry,在服务器上安装sinopia:

    $ npm install -g sinopia
    $ sinopia                    
    -bash: sinopia: command not found     #测试sinopia命令,此时会报找不到命令
    复制代码

    找不到命令,原因在于环境变量没设置,修改/etc/profile文件,在末尾添加以下内容:

    export NODE_HOME=/usr/local/node-v11.9.0-linux-x64  #Node所在路径
    export PATH=$NODE_HOME/bin:$PATH
    复制代码

    执行命令 source /etc/profile使生效,再次运行sinopia:

    $ Sinopia doesn't need superuser privileges. Don't run it under root.
     warn  --- config file  - /root/.config/sinopia/config.yaml
     warn  --- http address - http://localhost:4873/
    复制代码

    修改iptables设置,开放4873端口:

    $ iptables -I INPUT 4 -p tcp -m state --state NEW -m tcp --dport 4873  -j ACCEPT        #允许 4873  端口
    $ service iptables save                         #保存 iptables  规则
    复制代码

    【坑1】访问虚拟机的npm仓库地址被拒绝

    除了开放iptables的4873端口外,还需要在sinopia的配置文件末尾加上:

    listen: 0.0.0.0:4873
    复制代码

    重新启动

    $ Sinopia doesn't need superuser privileges. Don't run it under root.
     warn  --- config file  - /root/.config/sinopia/config.yaml
     warn  --- http address - http://0.0.0.0:4873/
    复制代码

    这样我们就能通过自己虚拟机的ip:4873访问了

配置文件在/root/.config/sinopia/config.yaml,相关配置字段意义在文件中都有注释

  • 使用守护进程启动(pm2)

​ 安装:npm install -g pm2 启动:pm2 start sinopia

  • 用户管理

    配置文件中关于鉴权的默认配置为:

    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  //默认为1000,改为-1后,禁止注册
    复制代码

    添加用户的方法:在客户端终端运行 npm adduser --registry http://xxxxx:4873/ ,设置相应的用户名、密码、邮箱后即可登录、发布包。

    如果将配置项max_users设为-1,表示禁用 npm adduser 命令来创建用户,需手动在htpasswd文件中添加用户信息来初始化用户。

客户端使用

使用 nrm 管理registry

$npm install -g nrm
 
$ nrm ls
* npm ---- https://registry.npmjs.org/
  cnpm --- http://r.cnpmjs.org/
  taobao - https://registry.npm.taobao.org/
  nj ----- https://registry.nodejitsu.com/
  rednpm - http://registry.mirror.cqupt.edu.cn/
  npmMirror  https://skimdb.npmjs.com/registry/
  edunpm - http://registry.enpmjs.org/
  
$ nrm add ynpm http://XXXXXX:4873 # 添加私服的npm镜像地址
$ nrm use ynpm # 使用私服的镜像地址
复制代码

安装包

npm install lodash # sinopia发现本地没有 lodash包,就会从 官方镜像下载
npm --loglevel info install lodash  # 设置loglevel 可查看下载包时的详细请求信息
复制代码
[storage]$ ls      
#下载过之后,私服的storage目录下回缓存安装包
[storage]$ ls                                                                                   
lodash
复制代码
rm -rf node-modules # 删除目录
npm insatll lodash # 第二次安装就会从缓存下载了,速度很快
复制代码

发布包与撤销发布包

在项目根目录下运行$ npm publish发布新包。

运行$ npm unpublish 包名 --force撤销发布包。

$ npm publish
+ @shawn280/ly-cli@1.0.0
复制代码

查看发布的包,已成功发布:

作用域scope管理发布包

经常有看到@xxx/yyy类型的开源npm包,原因是包名称难免会有重名,如果已经有人在 npm 上注册该包名,再次 npm publish 同名包时会告知发布失败,这时可以通过 scope 作用域来解决

  • 定义作用域包

    修改package.json中包名称:

    {
         "name": "@username/project-name"
    }
    复制代码

    需要注意的是,如果是发布到官方registry,scope一定要是自己注册的用户名,而如果是发布到自己的npm私服,scope可以不是用户名

  • 发布作用域包

    作用域模块默认发布是私有的

    发布到官方registry时,直接npm publish会报错,原因是只有付费用户才能发布私有 scope 包,免费用户只能发布公用包,因此需要添加 access=public 参数;

    发布到自己的npm私服时,不加access=public参数也可以发布

    npm publish --access=public
    复制代码
  • 使用作用域包

    npm install @username/project-name
    var projectName = require('@username/project-name')
    复制代码

总结

  • 以上的情况并没有考虑在遇到一些黑客攻击的情况下,所以为了尽量保证代码的安全,可以在前端加一层 Nginx 然后配置 SSH 公钥来作为双层验证。

  • 两种解决方案的对比:

    1. 都缓存了从proxy仓库下载过的包,没有同步整个proxy仓库的包。
    2. 存储方式:nexus使用blob store,sinopia直接保存包文件到storage目录。
    3. nexus管理界面可以清缓存;sinopia貌似没有命令和工具,但是可以删除通过删除storage目录下包目录的方式清除缓存。
    4. 使用nexus时,发布包安装、卸载包需要设置不同的registry,而Sinopia一直用同一个就可以。
    5. nexus管理页面上展示了更多的包信息,相比而言sinopia也就是nodejs风格的包主页上信息较少。
    6. sinopia更适合前端工程,优点是配置简单,对环境依赖少(仅node就够了),并且支持在windows系统下运行;nexus支持仓库种类最多,是用户群体最大的一个仓库平台,maven、docker、npm、gradle均支持,java需要maven仓库、android需要gradle仓库、运维需要docker仓库,前端需要npm仓库,如果公司已有nexus平台管理这些仓库,接入新的仓库会较方便。
    7. sinopia 的权限管理比较弱,对用户权限,发布权限,下载权限控制不是很得心应手;缓存优化不足,经常会在安装共有包的时候处于挂起状态

One more thing...

sinopia 在15年的时候就停止更新了,继而由 verdaccio 提供更新升级,两者用法基本上都是一致的。对于企业级的应用来说,技术选型时请慎重选择sinopia,建议选择verdaccio。

参考文档

juejin.im/entry/5bceb…

zhuanlan.zhihu.com/p/35907412

segmentfault.com/a/119000000…

www.cnblogs.com/LittleSix/p…

huang-x-h.github.io/2016/06/09/…

segmentfault.com/a/119000001…

转载于:https://juejin.im/post/5c89184f5188257ded10e165

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值