公司出於自身隱私保護須要,不想把本身的代碼開源到包管理區,可是又急需一套完整包管工具,來管理愈來愈多的組件、模塊和項目。對於前端,最熟悉的莫過於npm,bower等;可是bower的市場兼容性明顯沒有npm強壯,加之commonjs規範的日益成熟。npm應該是前端包管理的不二選擇。前端
公司對於搭建本地私有npm庫有以下要求:node
私有包託管在內部服務器中linux
項目中使用了公共倉庫上的公共包,也使用了內部服務器上的私有包nginx
但願下載的時候,公共包走公共倉庫,私有包走內部服務器的私有倉庫git
服務器硬盤有限,但願只緩存下載過的包,而不是所有同步。github
對於下載,發佈npm包有對應的權限管理,安裝方便,配置簡單,依賴少。web
nodejs/npm 軟件名稱: node-v6.9.1-linux-x64.tar.gz 下載地址:https://npm.taobao.org/mirrors/node/v6.9.1/算法
安裝命令:express
tar -xvf node-v6.9.1-linux-x64.tar.gz
npm install -g sinopia
pm2 版本:2.1.4 安裝命令:npm
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目錄 |
安裝步驟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 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命令進行~~
$npm install -g 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
$ 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安裝成功!
$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是 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 # 使用本址的鏡像地址
在客戶端ServerC假設使用者已經安裝npm/nrm而且已經正確配置
如今驗證使用剛剛搭建好的sinopia npm庫(http://serverS:4873/)進行安裝軟件和發佈軟件
修改npm的訪問代理爲剛剛搭建好的http://serverS:4873/
# cat .npmrc registry=http://serverS:4873/
執行安裝express的命令
$npm install express
安裝成功!
本地若是有可用來發布的模塊能夠直接用,本地沒有,使用npm init根據提示建立一個。
初始化建立一個模塊
$npm init
若是須要登陸才能publish則登陸
運行npm adduser註冊帳號,若是已經有帳號直接運行 npm login
登陸成功時可經過npm whoami查看
執行發佈
# npm publish chenyu/ + chenyu@1.0.0
去serverS查看剛剛publish的模塊:成功!
npm set registry http://ServerS:4873 npm adduser --registry http://Servers:4873
報錯:Incorrect username or password
解決辦法:把.npmrc中的網絡代理proxy/ https-proxy去掉便可。
檢查後發現,Server端的npm的.npmrc中和sinopia的config.yaml中上網代理未設置,加上後便可。
config.yaml是sinopia的配置文件
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
#倉庫 # 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 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
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是開源的基於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: