需求(這段話是摘抄參考文檔的,因為作者也想這么說):
公司出於自身隱私保護需要,不想把自己的代碼開源到包管理區,但是又急需一套完整包管工具,來管理越來越多的組件、模塊和項目。對於前端,最熟悉的莫過於npm,bower等;但是bower的市場兼容性明顯沒有npm強壯,加之commonjs規范的日益成熟。npm應該是前端包管理的不二選擇。
公司對於搭建本地私有npm庫有如下要求:
-
私有包托管在內部服務器中
-
項目中使用了公共倉庫上的公共包,也使用了內部服務器上的私有包
-
希望下載的時候,公共包走公共倉庫,私有包走內部服務器的私有倉庫
-
服務器硬盤有限,希望只緩存下載過的包,而不是全部同步。
-
對於下載,發布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
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
安裝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中比較全的配置和說明
#倉庫 # 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:
啟動sinopia:
重啟 sinopia:
顯示 sinopia 的log:
6.參考文檔
https://segmentfault.com/a/1190000005790827
http://www.tuicool.com/articles/B3iyyya
