用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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM