zoukankan      html  css  js  c++  java
  • 用sinopia搭建npm私服

    需求(这段话是摘抄参考文档的,因为作者也想这么说):

           公司出于自身隐私保护需要,不想把自己的代码开源到包管理区,但是又急需一套完整包管工具,来管理越来越多的组件、模块和项目。对于前端,最熟悉的莫过于npm,bower等;但是bower的市场兼容性明显没有npm强壮,加之commonjs规范的日益成熟。npm应该是前端包管理的不二选择。

    公司对于搭建本地私有npm库有如下要求:

    1. 私有包托管在内部服务器中

    2. 项目中使用了公共仓库上的公共包,也使用了内部服务器上的私有包

    3. 希望下载的时候,公共包走公共仓库,私有包走内部服务器的私有仓库

    4. 服务器硬盘有限,希望只缓存下载过的包,而不是全部同步。

    5. 对于下载,发布npm包有对应的权限管理,安装方便,配置简单,依赖少。

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

    1.要安装的软件

    软件简介

    nodejs/npm 软件名称: node-v6.9.1-linux-x64.tar.gz   下载地址:https://npm.taobao.org/mirrors/node/v6.9.1/

    安装命令:

    tar -xvf node-v6.9.1-linux-x64.tar.gz
    sinopia    版本:1.4.0 安装命令: 
    npm install -g sinopia  

    pm2   版本:2.1.4  安装命令

     npm install -g  pm2  

    nrm   版本:1.0.0  安装命令

    npm install -g nrm  

    规划目录(下为本次安装的实际目录,可根据实际环境调整)

    目录 账户 备注
    npm、nodejs解压目录 /opt/software nadmin
    sinopia启动时目录 /home/nadmin nadmin
    sinopia的passwd路径 /home/nadmin/node_htpasswd nadmin  
    sinopia的storage路径 /home/nadmin/sinopia/storage nadmin 建议磁盘空间较大不推荐放在home目录

    2.具体安装步骤(Server端)

    创建账户nadmin

    $ useradd nadmin

    安装node和npm

    安装步骤1的目录和命令,解压软件 node-v6.9.1-linux-x64.tar.gz

    (注:npm会在安装node的时候一起安装)

    $ tar -xvf node-v6.9.1-linux-x64.tar.gz

    添加node_home到环境变量,用root账户修改/etc/profile

    $vim /etc/profile          #追加
    NODE_HOME=/opt/software/node-v6.9.1-linux-x64
    PATH=$PATH:$NODE_HOME/bin

    source 使配置生效

    $ source /etc/profile

    配置生效之后,在任意地方可查看版本如下:

    1 $ node -v
    2 v6.9.1
    3 $ npm -v
    4 3.10.8  

    配置npm

    先查看npm的配置文件地址

    $npm config get userconfig
    /home/nadmin/.npmrc

    修改此配置文件,修改后查看,内容如下

    $ cat /home/nadmin/.npmrc
    proxy=http://网络代理ip:8080/
    https-proxy=http://网络代理ip:8080/
    no_proxy=本地yum源ip
    registry=https://registry.npm.taobao.org/

    也可通过命令设置http网络代理地址和npm server的地址,如下:

    $ npm config set proxy http://server:port

    $ npm config set https-proxy http://server:port

    $ npm config set registry "http://registry.npmjs.org/"

    ~~由于上步骤npm已经安装配置完毕,所以下面的安装软件可以通过npm命令进行~~

    安装sinopia

    $npm install -g sinopia

    配置sinopia

    Sinopia的特点是,你在哪个目录运行,它的就会在对应的目录下创建自己的文件。目录下默认有两个文件:config.yaml和storage,htpasswd 是添加用户之后自动创建的

    由于每次启动默认的config.xml文件是从原始文件default.yaml拷贝而来,可先修改sinopia原始的default.yaml

    地址:sinopia安装目录/conf/ default.yaml

    查看

    $ pwd
    /opt/software/node-v6.9.1-linux-x64/lib/node_modules/sinopia/conf
    $ ll
    total 12
    -rw-rw-r-- 1 nadmin nadmin 1309 Nov 9 19:52 default.yaml
    -rw-rw-r-- 1 nadmin nadmin 4076 Jun 7 2015 full.yaml
    -rw-rw-r-- 1 nadmin nadmin   39 Jun 7 2015 README.md

    修改完毕,内如下:

    storage: ./storage
    auth:
    htpasswd:
       file: /home/nadmin/node_htpasswd
    uplinks:
    npmjs:
       url: http://registry.npm.taobao.org/
    packages:
    '@*/*':
       access: $all
       publish: $authenticated
    '*':
       access: $all
       publish: $authenticated
       proxy: npmjs
    logs:
    - {type: stdout, format: pretty, level: http}
    listen: 0.0.0.0:4873
    http_proxy: http://代理服务器ip:8080
    https_proxy: http://代理服务器ip:8080

    启动 sinopia

    在规划好的启动目录下执行命令sinopia

    $ pwd
    /home/nadmin
    $ sinopia
    warn --- config file - /home/nadmin/sinopia/config.yaml
    warn --- http address - http://0.0.0.0:4873/
    http --> 200, req: 'GET http://registry.npm.taobao.org/express', bytes: 0/578356
    http <-- 200, user: admin, req: 'GET /express', bytes: 0/34448
    http --> 200, req: 'GET http://registry.npm.taobao.org/type-is', bytes: 0/54083

    sinopia已经启动,可正常使用,此种方法日志会输出到控制台,不建议使用,后面会介绍使用pm2对sinopia进程进行托管启动的方法。

    访问http://ServerS::4873 查看页面,看到如下页面,说明sinopia安装成功!

    安装pm2

    $npm install -g pm2

    使用pm2启动sinopia

    $ pm2 start sinopia
    [PM2] Applying action restartProcessId on app [sinopia](ids: 0)
    [PM2] [sinopia](0) ✓
    [PM2] Process successfully started

    使用pm2托管的进程可以保证进程永远是活着的,尝试通过kill -9去杀sinopia的进程发现杀了之后又自动启起来。推荐使用此种方式启动sinopia.

    pm2 开机自启动sinopia

    pm2 startup centos,根据提示用root账户执行:

    # su -c "env PATH=$PATH:/opt/software/node-v6.9.1-linux-x64/bin pm2 startup centos -u nadmin --hp /home/nadmin"

    pm2 启动sinopia 4个进程,且保存日志

    $ pm2 start sinopia -i 4 --watch --merge-logs --log-date-format="YYYY-MM-DD HH:mm: Z" -l /opt/log/sinopia.log

    保存当前配置,开机自启动时按照此时配置启动

    $ pm2 save

    安装nrm

    nrm是 npm registry 管理工具, 能够查看和切换当前使用的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/
      mytestnpm  http://ServerS:4873/  

    使用命令

    $ nrm add XXXXX http://XXXXXX:4873 # 添加本地的npm镜像地址

    $ nrm use XXXX # 使用本址的镜像地址

    3.验证

    在客户端ServerC假设使用者已经安装npm/nrm并且已经正确配置

    1>npm install

    现在验证使用刚刚搭建好的sinopia npm库(http://serverS:4873/)进行安装软件和发布软件

    修改npm的访问代理为刚刚搭建好的http://serverS:4873/

    # cat .npmrc
    registry=http://serverS:4873/

    执行安装express的命令

    $npm install express  

    安装成功!

    2>npm publish

    本地如果有可用来发布的模块可以直接用,本地没有,使用npm init根据提示创建一个。

    初始化创建一个模块

    $npm init  

    如果需要登录才能publish则登录

    运行npm adduser注册账号,如果已经有账号直接运行 npm login

    登录成功时可通过npm whoami查看

    执行发布

    # npm publish chenyu/
    + chenyu@1.0.0

    去serverS查看刚刚publish的模块:成功!

     

    4.安装过程的一些报错和解决办法

    1>注册账号失败Incorrect username or password

    npm set registry http://ServerS:4873
    
    npm adduser --registry http://Servers:4873

    报错:Incorrect username or password

    解决办法:把.npmrc中的网络代理proxy/ https-proxy去掉即可。

    2>在Client端使用新搭建的npm库安装软件的时候,报404错误

    检查后发现,Server端的npm的.npmrc中和sinopia的config.yaml中上网代理未设置,加上后即可。

    5.附录(npm、pm2等的使用方法)

    config.xml文件详解:

    config.yaml是sinopia的配置文件

    1>其常用的配置

    storage: 仓库保存的地址,publish时仓库保存的地址。

    auth: htpasswd file:账号密码的文件地址,初始化时不存在,可指定需要手工创建。

                   max_users:默认1000,为允许用户注册的数量。

                        为-1时,不允许用户通过npm adduser注册。

                      但是,当为-1时,可以通过直接编写htpasswd file内容的方式添加用户。

    语法:用户名:{SHA}哈希加密的字符=:autocreated 时间

    加密算法:SHA1哈稀之后再转换成 Base64 输出就好

    uplinks: 配置上游的npm服务器,主要用于请求的仓库不存在时到上游服务器去拉取。

    packages: 配置模块。access访问下载权限,publish包的发布权限。

          格式如下:

    scope:

              权限操作

     scope:两种模式

    一种是 @*/* 表示某下属的某项目

      另一种是 * 匹配项目名称(名称在package.json中有定义)

     权限:

    l  access: 表示哪一类用户可以对匹配的项目进行安装(install)

    l  publish: 表示哪一类用户可以对匹配的项目进行发布(publish)

    l  proxy: 如其名,这里的值是对应于 uplinks 的名称,如果本地不存在,允许去对应的uplinks去取。

      操作:

    l  $all 表示所有人(已注册、未注册)都可以执行对应的操作

    l  $authenticated 表示只有通过验证的人(已注册)可以执行对应操作,注意,任何人都可以去注册账户。

    l  $anonymous 表示只有匿名者可以进行对应操作(通常无用)

    l  或者也可以指定对应于之前我们配置的用户表 htpasswd 中的一个或多个用户,这样就明确地指定哪些用户可以执行匹配的操作

    listen:配置监听端口和主机名。

           localhost:4873 #默认

           0.0.0.0:4873 #在所有网卡监听

    代理

    #http_proxy: http://something.local/  #http代理

    #https_proxy: https://something.local/  #https代理

    #no_proxy: localhost,127.0.0.1  #不适用代理的iP

    修改了配置文件后,运行命令

    $ sinopia -c config.yml

    2>附录github中比较全的配置和说明

    https://raw.githubusercontent.com/rlidwka/sinopia/master/conf/full.yaml
    #仓库
    # path to a directory with all packages
    storage: ./storage
     
    # a list of users
    #
    # This could be deprecated soon, use auth plugins instead (see htpasswd below).
    users:
      admin:
        # crypto.createHash('sha1').update(pass).digest('hex')
        password: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
     
    #是否支持web接口
    web:
      # web interface is disabled by default in 0.x, will be enabled soon in 1.x
      # when all its issues will be fixed
      #
      # set this to `true` if you want to experiment with web ui now;
      # this has a lot of issues, e.g. no auth yet, so use at your own risk
      #enable: true
     
      title: Sinopia
      # logo: logo.png
      # template: custom.hbs
     
    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
    #上游npm服务器配置
    uplinks:
      npmjs:
        url: https://registry.npmjs.org/
     
    #设置请求无应答超时时间
        # amount of time to wait for repository to respond
        # before giving up and use the local cached copy
        #timeout: 30s
     
    #设置数据认为最新的时间为2分钟,2分钟同一个数据的请求不会向上游服务器请求
        # maximum time in which data is considered up to date
        #
        # default is 2 minutes, so server won't request the same data from
        # uplink if a similar request was made less than 2 minutes ago
        #maxage: 2m
     
    #设置访问失败达到某次数,就停止一段时间不访问上游服务器,默认是2次不应答,5分钟不去请求
        # if two subsequent requests fail, no further requests will be sent to
        # this uplink for five minutes
        #max_fails: 2
        #fail_timeout: 5m
     
        # timeouts are defined in the same way as nginx, see:
        # http://wiki.nginx.org/ConfigNotation
     
    #包权限配置
    packages:
      # uncomment this for packages with "local-" prefix to be available
      # for admin only, it's a recommended way of handling private packages
      #'local-*':
      #  access: admin
      #  publish: admin
      #  # you can override storage directory for a group of packages this way:
      #  storage: 'local_storage'
     
      '*':
        # allow all users to read packages (including non-authenticated users)
        #
        # you can specify usernames/groupnames (depending on your auth plugin)
        # and three keywords: "$all", "$anonymous", "$authenticated"
        access: $all
     
        # allow 'admin' to publish packages
        publish: admin
     
    #如果包本地不存在,则去npmjs去请求
        # if package is not available locally, proxy requests to 'npmjs' registry
        proxy: npmjs
     
    #####################################################################
    # Advanced settings
    #####################################################################
     
    # if you use nginx with custom path, use this to override links
    #url_prefix: https://dev.company.local/sinopia/
     
    # You can specify listen address (or simply a port).
    # If you add multiple values, sinopia will listen on all of them.
    #
    # Examples:
    #
    #listen:
    # - localhost:4873            # default value
    # - http://localhost:4873     # same thing
    # - 0.0.0.0:4873              # listen on all addresses (INADDR_ANY)
    # - https://example.org:4873  # if you want to use https
    # - [::1]:4873                # ipv6
    # - unix:/tmp/sinopia.sock    # unix socket
     
    #https证书配置(listen需要设置成https)
    # Configure HTTPS, it is required if you use "https" protocol above.
    #https:
    #  key: path/to/server.key
    #  cert: path/to/server.crt
     
    # type: file | stdout | stderr
    # level: trace | debug | info | http (default) | warn | error | fatal
    #
    # parameters for file: name is filename
    #  {type: 'file', path: 'sinopia.log', level: 'debug'},
    #
    # parameters for stdout and stderr: format: json | pretty
    #  {type: 'stdout', format: 'pretty', level: 'debug'},
    logs:
      - {type: stdout, format: pretty, level: http}
      #- {type: file, path: sinopia.log, level: info}
     
    #代理设置
    # you can specify proxy used with all requests in wget-like manner here
    # (or set up ENV variables with the same name)
    #http_proxy: http://something.local/
    #https_proxy: https://something.local/
    #no_proxy: localhost,127.0.0.1
     
    #设置json文档大小上限
    # maximum size of uploaded json document
    # increase it if you have "request entity too large" errors
    #max_body_size: 1mb
     
    # Workaround for countless npm bugs. Must have for npm <1.14.x, but expect
    # it to be turned off in future versions. If `true`, latest tag is ignored,
    # and the highest semver is placed instead.
    #ignore_latest_tag: false
     

    npm常见使用命令

    1>常用命令

    npm install XX :本地安装,安装到当前的目录中

    npm install –g XX :模块将被安装到【全局目录】

    查看全局目录npm config get prefix

    设置全局目录npm config set prefix XXX

    查看缓存目录npm config get cache

    设置缓存目录npm cofnig set cache XXX

    一般采用全局安装,方便管理、结构清晰还可以重复利用

    其他命令如下:

    npm install <name>安装nodejs的依赖包

    例如npm install express 就会默认安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本,如npm install express@3.0.6

    npm install <name> -g  将包安装到全局环境中

    但是代码中,直接通过require()的方式是没有办法调用全局安装的包的。全局的安装是供命令行使用的,就好像全局安装了vmarket后,就可以在命令行中直接运行vm命令

    npm install <name> --save  安装的同时,将信息写入package.json中

    项目路径中如果有package.json文件时,直接使用npm install方法就可以根据dependencies配置安装所有的依赖包

    这样代码提交到github时,就不用提交node_modules这个文件夹了。

    npm init  会引导你创建一个package.json文件,包括名称、版本、作者这些信息等

    npm remove <name>移除

    npm update <name>更新

    npm ls 列出当前路径下安装的了所有包

    npm root 查看当前包的安装路径

    npm root -g  查看全局的包的安装路径

    npm help  帮助,如果要单独查看install命令的帮助,可以使用的npm help install

    npm config get cache 查看npm的缓存目录

    下过的包都在里面,比如刚刚下载的loadash

    2>关于npm缓存目录的一些记录

    npm安装的模块有两个缓存目录:
    默认*inux和mac下是在用户主目录下的.npm目录下,通过npm config get cache 可以查看。window下则在%AppData%/npm-cache 目录下。

    该目录下的模块结构为.npm/module_name/module_version/这种方式命名。

    值得注意的是,执行npm install命令的时候npm只会检查node_modules中是否存在该模块,如果没有则会去registry下载,无论.npm文件夹下是否存在。这也是install速度慢的一个原因。

    解决办法使用npm install --cache-min <整数时间> <package-name>;
    这个命令的意思是从缓存中进行安装,只有再超过参数时间的时候才从regitry上安装。但内在也进行了一次与registry的交互,只是交互的etag属性,服务器返回304表示没有更新不需要下载

    另外也可以将缓存目录设置成node_modules目录。

    pm2命令详解

    pm2是开源的基于Nodejs的进程管理器。包括进程、日志、监控的一整套完整功能。它带有负载均衡功能,当你要把你的独立代码资源利用全部的服务器所有cpu,保证进程永远都是活着的,0秒的重载,PM2是完美的。

    常用的命令介绍:

    以下是pm2常用的命令行

    $ pm2 start app.js              # 启动app.js应用程序

    $ pm2 start app.js -i 4         # cluster mode 模式启动4个app.js的应用实例

                                    # 4个应用程序会自动进行负载均衡

                                   

    $ pm2 start app.js --name="api" # 启动应用程序并命名为 "api"

    $ pm2 start app.js --watch      # 当文件变化时自动重启应用

    $ pm2 start script.sh           # 启动 bash 脚本

    $ pm2 list                      # 列表 PM2 启动的所有的应用程序

    $ pm2 monit                     # 显示每个应用程序的CPU和内存占用情况

    $ pm2 show [app-name]           # 显示应用程序的所有信息

    $ pm2 logs                      # 显示所有应用程序的日志

    $ pm2 logs [app-name]           # 显示指定应用程序的日志

    $ pm2 flush

    $ pm2 stop all                  # 停止所有的应用程序

    $ pm2 stop 0                    # 停止 id为 0的指定应用程序

    $ pm2 restart all               # 重启所有应用

    $ pm2 reload all                # 重启 cluster mode下的所有应用

    $ pm2 gracefulReload all        # Graceful reload all apps in cluster mode

    $ pm2 delete all                # 关闭并删除所有应用

    $ pm2 delete 0                  # 删除指定应用 id 0

    $ pm2 scale api 10              # 把名字叫api的应用扩展到10个实例

    $ pm2 reset [app-name]          # 重置重启数量

    $ pm2 startup                   # 创建开机自启动命令

    $ pm2 save                      # 保存当前应用列表

    $ pm2 resurrect                 # 重新加载保存的应用列表

    $ pm2 update                    # Save processes, kill PM2 and restore processes

    $ pm2 generate                  # Generate a sample json configuration file

    $ pm2 deploy app.json prod setup    # Setup "prod" remote server

    $ pm2 deploy app.json prod          # Update "prod" remote server

    $ pm2 deploy app.json prod revert 2 # Revert "prod" remote server by 2

    $ pm2 module:generate [name]    # Generate sample module with name [name]

    $ pm2 install pm2-logrotate     # Install module (here a log rotation system)

    $ pm2 uninstall pm2-logrotate   # Uninstall module

    $ pm2 publish                   # Increment version, git push and npm publish

    命令验证:

    停止sinopia:

    $ pm2 stop sinopia
     

    启动sinopia:

    $ pm2 start sinopia

    重启 sinopia:

    $ pm2 retart sinopia
     

    显示 sinopia 的log:

    $ pm2 logs sinopia

    6.参考文档

    https://segmentfault.com/a/1190000005790827

    http://www.tuicool.com/articles/B3iyyya

  • 相关阅读:
    360安全桌面的屏保图片在哪个目录下?
    IntelliJ 注解@Slf4j后找不到log问题解决
    运行springboot项目报错:Field userMapper in XX required a bean of type 'xx' that could not be found.
    springsecurity
    Error creating bean with name 'sqlSessionFactory' defined in class path resource [config/spring/applicationContext.xml]: Invocation of init method failed;
    idea热部署
    数据结构导论 三 线性表-顺序存储
    数据结构导论 二 时空性
    树莓派安装、卸载、更新软件
    数据结构导论第一章
  • 原文地址:https://www.cnblogs.com/LittleSix/p/6053549.html
Copyright © 2011-2022 走看看