[Node.js] Verdaccio透過IIS proxy代理架設離線npm server

  • 1291
  • 0
  • 2018-12-10

相關套件找到的有三個可以選擇sinopia、local-npm、

sinopia已經很久沒有維護了,而verdaccio是他的一個活躍分支

local-npm也是太久沒維護,安裝時相依性出錯!

最後就決定用verdaccio囉!

獨立網域方法大至整理出下列幾種方式[參考資料1]:

1. 架設代理伺服器銜接內外網,轉發內網npm request到Internet npm server
實體隔離不適用,監控就靠網管人員過濾封包

2. 打包在Internet環境install過的npm cache資料
將npm cache會將安裝過的套件保留下來,安裝時利用「--offline」 tag優先向快取抓資料,但只適合一次性安裝!
要更新或安裝其他套件就「npm cache clean --force」清除快取,然後重安裝想要的東西做一個新的cache

3. Internet環境先「npm install」,把所有套件下載到node_modules資料夾,複製整個資料夾跟package.json檔
操作單純,想要的直接在網際網路先安裝使用,其實跟快取有點像,我認為甚至更方便只要複製貼上而已...

4. 下載套件的壓縮檔 「{packageName}.tgz」,直接對壓縮檔安裝「npm install {路徑}/{packageName}.tgz」
針對單一小套件安裝簡單好用,如果套件相依很多東西就辛苦點,要不同版本的就在去下載目標版本的.tgz壓縮檔

5. 架設privated npm server
本文使用的方法!適合小套件且需要歷史版本控制。

 

基本上官網說明的很詳細了[參考資料5],但是需要一些Troubleshooting!

下列紀錄時做過程與debug的心路歷程。

 

1. 安裝nodeiis套件

讓iis可以執行node.js,詳情請看[參考資料6]

 

2. 給資料夾iis的權限

事先在IIS新增名為「iisnode」的應用程式集區,把verdaccio放在上面

所以設定權限的時候,直接把此虛擬帳戶的權限給verdaccio root資料夾

因為改代理本機安裝的verdaccio,root位置在「C:\Users\user\AppData\Roaming\verdaccio」

輸入「IIS AppPool\{程式集名稱}」,沒問題的話按檢查名稱就會通過了![參考資料10]

 

3. 將Url Rewrite Module安裝到IIS上

要再IIS上面跑node.js服務呢,需要安裝Url Rewrite Module套件,不然就會如下圖,給一個籠統的錯誤訊息。

 

4. 設定IIS的CGI

上述步驟完成後,就會再出現下個問題...

因為還要去Window功能,開啟IIS的CGI、ISAPI功能!

接著將IIS的「ISAPI及CGI限制」打開成允許

再設定ICON中找到「處理常式對應」→「新增模組對應」設將javascript檔(*.js)對應至iisnode套件

 

5. 官網提供的start.js內路徑有誤

require中cli.js的路徑調整為build資料夾底下了,不是官網的require('./node_modules/verdaccio/src/lib/cli.js'); [參考資料8]

process.argv.push('-l', 'unix:' + process.env.PORT);
require('./node_modules/verdaccio/build/lib/cli.js');

 

6. 直接進入Web時會跑出Verdaccio的json檔內容

基本上verdaccio是跑在express上,爬文說要改index.js進入[參考資料9]

已先設定改config.yaml中url_prefix設定,還是跑不出來

待研究中...

 

7. [轉捩點]決定先改用代理伺服器

將外部連過來的服務http://x.x.x.x/verdaccio轉到本機安裝的verdaccio http://127.0.0.1:4873的方法![參考資料11, 12]

先安裝IIS的Application Request Routing套件,並啟用。


若不想透過IIS UI介面設定轉發路徑就直接修改web.config,全部內容如下

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>

    <!-- indicates that the start.js file is a node.js application
    to be handled by the iisnode module -->
    <handlers accessPolicy="Read, Execute, Script">
            <remove name="WebDAV" />
            <add name="nodejs" path="*.js" verb="*" modules="iisnode" resourceType="Unspecified" />
            <!-- <add name="iisnode" path="start.js" verb="*" modules="iisnode" resourceType="Unspecified" requireAccess="Execute" /> -->
            <add name="iisnode" path="start.js" verb="*" modules="iisnode" />
            <add name="WebDAV" path="*" verb="*" modules="WebDAVModule" resourceType="Unspecified" requireAccess="Execute" />
    </handlers>

    <rewrite>
      <rules>

        <!-- iisnode folder is where iisnode stores it's logs. These should
        never be rewritten -->
        <rule name="iisnode" stopProcessing="true">
          <match url="iisnode*" />
          <action type="None" />
        </rule>

        <!-- Rewrite all other urls in order for verdaccio to handle these -->
        <!-- <rule name="verdaccio">
          <match url="/*" />
          <action type="Rewrite" url="start.js" />
        </rule> -->
        <rule name="轉到4873" enabled="true" stopProcessing="true">
          <match url="(.*)" />
          <action type="Rewrite" url="http://127.0.0.1:4873/{R:1}" />
        </rule>              
      </rules>           
    </rewrite>

    <!-- exclude node_modules directory and subdirectories from serving
    by IIS since these are implementation details of node.js applications -->
    <security>
      <requestFiltering>
        <hiddenSegments>
          <add segment="node_modules" />
        </hiddenSegments>
      </requestFiltering>
    </security>

  </system.webServer>
</configuration>

重點在「

<rule name="轉到4873" enabled="true" stopProcessing="true">

<match url="(.*)" />

<action type="Rewrite" url="http://127.0.0.1:4873/{R:1}" />

</rule>

」[參考資料13]

一開始誤將「模式」設定成「/*」轉向url「http://127.0.0.1:4873/」

雖然會將網址變成「http://127.0.0.1/verdaccio/{PackageName}/#/」,又跳到http://127.0.0.1:4873/的Web介面

這樣的話「npm install」 會出現錯誤「< in JSON at position 0...」

因為一般來說,下指令「npm install {PackageName}」時會向http://127.0.0.1/verdaccio/{PackageName}索取套件JSON格式的詳細資料

丟回一個html格式報錯很正常~

 

8. 匯入公開套件至verdaccio

匯入私人package就不多贅述,官網的教學說得很清楚,這邊說明匯入npm上面「公開發佈的套件」到自己內網

其實方法大同小異,:

1.先用「npm-package-downloader」下載一個{package}.tgz壓縮檔

2.解壓縮後開啟「命令提式員」切換目錄到解壓縮位置

3.「npm publish --registry http://127.0.0.1/verdaccio」發佈到自己的verdaccio,此時會同步抓「https://registry.npmjs.org/」上面此套件的JSON格式說明檔

4.接著「C:\Users\user\AppData\Roaming\verdaccio\storage」底下就會看到{package}名稱的資料夾,裡面還附個精美的package.json詳細記載此套件資訊

5.把{package}其他版本的.tgz檔一併放在「C:\Users\user\AppData\Roaming\verdaccio\storage\{package}」資料夾

註:{package}為套件名稱,看你想要什麼套件

 

9. 修改npm config,執行安裝

打開command window下指令「npm set registry http://127.0.0.1/verdaccio」,將存取位置改成自己的verdaccio

(記得要先讓「verdaccio」整個服務執行起來...)

在專案裡「npm install {package}@{version}」就會到privated npm server抓資料了

安裝速度超快的!

最後雖然還沒成功在iis上面直接跑verdaccio,但透過iisnode可以跑跑其他JavaScript~

 

 

總結

只寫大流程跟一些troubleshooting的東西,還有很多細節沒寫上去,

像是verdaccio在config.yaml設定權限、增加使用者帳戶等細節

真的寫完可以從外太空寫道內子宮,已整理很多[參考資料],就從中再延伸出去找資料吧!

 

常用指令

改npm指令目標server位置
npm set registry http://127.0.0.1/verdaccio
改回internet npm server
npm set registry https://registry.npmjs.org/

改npm快取位置
npm config set cache C:\Devel\nodejs\npm-cache --global

查詢npm config細節
npm config list -l

清除快取
npm cache clean --force

發佈套件
npm publish --registry http://127.0.0.1/verdaccio

 

好用下載工具

下載.tgz檔的套件

https://www.npmjs.com/package/npm-package-downloader

 

verdaccio、sinopia官方位置:

https://www.npmjs.com/package/verdaccio

https://verdaccio.org/docs/en/protect-your-dependencies

https://www.npmjs.com/package/sinopia

 

參考文章

1. 前端工程研究:如何在企業內部使用「完全離線」的方式安裝 npm 套件, https://blog.miniasp.com/post/2018/06/16/Offline-installation-of-npm-packages-for-Enterprise.aspx

2. Offline installation of npm packages, https://addyosmani.com/blog/using-npm-offline/

3. 搭建私有npm仓库, https://itony.net/post/private-npm.html

4. IIS 上的 ASP.NET 程式出現 500.19 (0x8007000d) 錯誤?!, https://blog.yowko.com/iis-50019-0x8007000d/

5. Installing on IIS server, https://verdaccio.org/docs/en/iss-server

6. 在Window IIS上跑NodeJs, https://blog.gss.com.tw/index.php/2017/09/11/windowiisnodejs/

7. Running a local npm repository on Windows Server using Verdaccio, https://robertwray.co.uk/blog/running-a-local-npm-repository-on-windows-server-using-verdaccio

8. Problems hosting under IIS using Azure/IISNode , https://github.com/verdaccio/verdaccio/issues/1102

9. Host Sinopia in IIS on Windows, https://gist.github.com/HCanber/4dd8409f79991a09ac75

10. 介紹 IIS 7.5 的應用程式集區與新增的「虛擬帳戶」特性, https://blog.miniasp.com/post/2009/09/09/Introduce-IIS-75-Application-Pool-Identity-and-Virtual-Account.aspx

11. 如何利用 IIS7 的 ARR 模組實做 Reverse Proxy 機制, https://blog.miniasp.com/post/2009/04/13/Using-ARR-to-implement-Reverse-Proxy.aspx

12. IIS 透過REVERSE PROXY上HTTPS, http://blog.davidou.org/archives/1411

13. IIS URL Rewrite 基本規則, http://www.pureexample.com/tw/c-sharp/iis-url-rewrite-basic-rewrite-rules.html

14. The Sweet Sensation of Automation, http://zeke.sikelianos.com/npm-and-github-automation-with-heroku/

15. all-the-package-names, https://github.com/nice-registry/all-the-package-names