---
# System prepended metadata

title: IIS 新增站台 + 前後端發佈教學
tags: [Andy, IIS, Domain, Tutorial, DNS]

---

###### tags: `Tutorial`, `DNS`, `IIS`, `Domain`, `Andy`
[toc]

# IIS 新增站台 + 前後端發佈教學
不管是在給客戶Demo、跟同事合作或者跟外包夥伴協作時，常常需要在我們公司的`Web Server`中新增一個站台，這篇文章會紀錄要在公司裡架站台的詳細步驟。最後會教學如何發佈及設定 `Angular` 專案及 `.Net Core WebAPI` 專案到 IIS 上。

## 流程大綱
本次的需求是因公司需要一個 `Domain` 用來放展示給客戶的專案，名稱要叫做 `app.zerosum.com.tw`。
所以我會先使用該 `Domain` 新增一個站台，之後再個別把前端 `Angular` 及 後端 `.Net Core WebAPI` 專案新增到該站台中並轉換成網頁來測試網頁功能，最後再把API專案整到Web資料夾，讓管理上更一目瞭然。

## DNS 設定
如果你今天是要新增一個==域名(Domain)==(如：`zerosum.com.tw`)，你需要先==擁有(購買)該域名==，可以Google`購買域名`就能搜尋到一些可以購買域名的網站了，我們公司目前所有的域名都是在[網路中文](https://www.net-chinese.com.tw/)購買的，購買後還要到 `DNS` 中新增一個區域，但因為==本篇文章的背景是在已經購買`zerosum.com.tw`並且在 `DNS` 中也新增好區域的前提==下所進行的，所以這步就略過，有興趣架設自己的網站的人可以自行搜尋。

要進入設定 `DNS` 的步驟前，還需要提到兩點：

1. `DNS` 有分為==自管==及==代管==兩種：
    * ==代管== 就是由==供應商來幫你架設DNS==，至於DNS的一些設定應該會在供應商提供的網頁中可以調整。
    * ==自管== 顧名思義就是==自己架設DNS==。

2. 我們公司就是使用==自管==的方式，而自管的 `DNS` 主機分為兩台：`公司內部212`及`國網`，所以接下來關於 `DNS` 的設定==在上述兩台 `DNS` 主機中都要設定==。

接下來就直接進入設定 `DNS` 的步驟(很簡單！只需兩步驟)：

1. 連到 `DNS` 主機(`公司內部212`及`國網`) -> 開啟 `DNS管理員` -> 在`正向對應區域`找到目標域名 -> 右鍵選擇 `新增主機(A或AAAA)`。
    ![01](https://hackmd.io/_uploads/SyJhsigq6.png)

2. 在`名稱`中輸入想要的==站台名稱==，`IP位址`則是輸入公司的==對外IP==，確認無誤後按`新增主機`。
    ![02](https://hackmd.io/_uploads/B1Z2ojx96.png)

## IIS 新增站台
1. 連到 `WebServer` 主機(`公司內部211`) -> 開啟 `IIS管理員` -> `站台` 右鍵選擇 `新增網站...`。
    ![03](https://hackmd.io/_uploads/ByE2ojl9a.png)

2. `站台名稱`強烈建議填寫想要的 `Domain` 以便辨認 -> `實體路徑`可以在`F:\Web`中新增一個資料夾後選取 -> `主機名稱`填寫想要的 `Domain` -> 確認無誤後按`確定`。
    ![04](https://hackmd.io/_uploads/rk_noig56.png)

3. 建立完成後應該會出現對應的應用程式集區(Application pool)。
    ![05](https://hackmd.io/_uploads/Bkshoolqp.png)

4. 選擇該應用程式集區按右鍵 -> 基本設定 -> `.Net CLR版本`選擇`沒有Managed程式碼`，`Managed管線模式`選擇`整合式`。
    ![06](https://hackmd.io/_uploads/ryZ6sie5a.png)
    ![07](https://hackmd.io/_uploads/Skbpsjxca.png)

## 發布 Angular 專案
### IIS 建立應用程式資料夾
1. 在 IIS 站台列表中找到剛新增好的站台 -> 右鍵選擇 `瀏覽` 可以打開實體路徑資料夾。
    ![08](https://hackmd.io/_uploads/S1XJhog9T.png)

2. 新增一個資料夾並將名稱命名為你想要的路由名稱，這個資料夾就接下來要放應用程式的資料夾，這邊命名為`JewelCloudWeb`。
    ![09](https://hackmd.io/_uploads/S1BJhje56.png)

### 建置並發布 Angular 專案
1. 在 Terminal 中輸入 `ng build --base-href /JewelCloudWeb/` 以建置專案。
    * `--base-href`：這個參數定義路由是要從甚麼地方開始，由於上一個步驟中我們有在 IIS 新增一個名為`JewelCloudWeb`的資料夾，所以要進到網頁的起始路由會是`app.zerosum.com.tw/JewelCloudWeb`，也因為如此，我們就必須加上這個參數才能正常運作，換言之，如果你的Angular專案要直接發在`app.zerosum.com.tw`資料夾中，就不需要加此參數。

2. 到 `dist` 資料夾中把建置好的檔案都複製起來(或壓縮後複製zip檔)。
    ![10](https://hackmd.io/_uploads/Skt1hsecT.png)

3. 回到 IIS 的 `JewelCloudWeb` 貼上。

4. 進到 IIS 將資料夾轉換為應用程式。
    ![11](https://hackmd.io/_uploads/BJaknil9p.png)

5. 在應用程式集區選擇相對應的應用程式集區，選擇好後按確定。
    ![12](https://hackmd.io/_uploads/S1kghseca.png)

6. 完成後應該會看到圖示改變如下：
    ![13](https://hackmd.io/_uploads/BJbx3ol9T.png)

7. 在網頁中開啟`http://app.zerosum.com.tw/JewelCloudWeb/` 檢查成果。
    ![14](https://hackmd.io/_uploads/SyVg2jeqT.png)

### 錯誤發生
網頁發布好後，雖然看起來沒問題，但只要在子路由下重新整理，或是想直接使用網址導到其他頁面時就會發生`404-找不到檔案或目錄`，要解決這個問題==有兩種解法==，接著就一一做說明。
    ![15](https://hackmd.io/_uploads/SyPx3ogcp.png)

### 解法一：根路由使用usehash參數
1. 在 `app-routing.module.ts` 中，在路由模組加上 `useHash: true` 參數。
    ![16](https://hackmd.io/_uploads/BJ2xhsgcT.png)

2. 重新建置並發布到 IIS 上。

3. 再次開啟網頁並強制重新整理，會發現網址中多了`#`的符號，而網頁的路由也可以正常運作了。
    ![17](https://hackmd.io/_uploads/r10ehil56.png)

### 解法二：IIS 轉址設定
第一種解法大家應該會注意到雖然問題被解決了，==但有個`#`號在那邊總是有點醜==，這時候就可以使用接下來要介紹的第二種解法。
1. 將根路由恢復到 ==沒有加 `useHash: true`== 的狀態建置並發布到 IIS 上。

2. 在應用程式資料夾中，新增一個`web.config`檔，內容如下：
    ```xml=
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <rewrite>
                <rules>
                    <rule name="Angular SPA Rule" stopProcessing="true">
                        <match url=".*" />
                        <conditions>
                            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        </conditions>
                        <action type="Rewrite" url="/JewelCloudWeb/" />
                    </rule>
                </rules>
            </rewrite>
        </system.webServer>
    </configuration>
    ```
    > 這個設定檔內容主要是在設定當路由的重寫(Rewrite)規則，將此檔案放好後應該可以看到`URL Rewrite`的內容會出現一筆設定
    > ![18](https://hackmd.io/_uploads/Bk4Wnog9T.png)
    > ![66](https://hackmd.io/_uploads/rJh4ajgcp.png)
    > ==如果沒有看到有可能是IIS沒有安裝`URL Rewrite`套件==，請先到`取得新的網頁平台元件`安裝`URL Rewrite Module 2.0`
    > ![19](https://hackmd.io/_uploads/Byi-3ol5T.png)

3. 設定好後就OK囉！現在路由應該可以正常運作，而且也沒有`#`號，如下圖：
    ![20](https://hackmd.io/_uploads/rk9Gnil9p.png)

## 發布 .Net Core WebAPI 專案
### IIS 建立應用程式資料夾
1. 在站台新增一個應用程式的資料夾，這邊命名為`JewelCloudAPI`。
    ![21](https://hackmd.io/_uploads/ByRMnjeca.png)

2. 之後回頭看 `IIS`，應該可以看到站台地下多出了你剛剛新增的資料夾。
    ![22](https://hackmd.io/_uploads/HJGXhoeqp.png)

### 建置並發布 .Net Core Web API 專案
1. 將 `.Net Core Web API` 專案發布好後直接把檔案丟到`JewelCloudAPI`資料夾中。

2. 右鍵`.Net Core Web API` 資料夾選擇 `轉換成應用程式`。
    ![23](https://hackmd.io/_uploads/rkS7nog5p.png)

3. `應用程式集區`也選擇 `app.zerosum.com.tw` 後按確定。
    ![24](https://hackmd.io/_uploads/rJwXnslcp.png)

4. 測試開啟`app.zerosum.com.tw/JewelCloudAPI/swagger/index.html`，測試結果如下圖：
    ![25](https://hackmd.io/_uploads/By5Qnol5p.png)

## 將 .Net Core Web API 專案 放在 Angular 專案裡面運行
截至目前恭喜你已經會發布前後端專案囉！接下來我們可以進一步把前端跟後端API專案整在一起，讓應用程式更好被管理！
1. 先將 `JewelCloudAPI` 移除。
    ![26](https://hackmd.io/_uploads/Skh7noxcT.png)

2. 將 `JewelCloudAPI` 資料夾重新命名為 `API`，並搬到 `JewelCloudWeb` 裡面。
    ![27](https://hackmd.io/_uploads/B1x4njx5a.png)

3. 在 `JewelCloudWeb/web.config` 中新增針對API的重寫設定，整體程式碼如下，這次新增的程式碼是第10行。
    ```xml=
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <rewrite>
                <rules>
                    <rule name="Angular SPA Rule" stopProcessing="true">
                        <match url=".*" />
                        <conditions>
                            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                            <add input="{PATH_INFO}" pattern="API/.*" negate="true" />
                        </conditions>
                        <action type="Rewrite" url="/JewelCloudWeb/" />
                    </rule>
                </rules>
            </rewrite>
        </system.webServer>
    </configuration>
    ```

4. 在 IIS 站台中展開 `JewelCloudWeb` 應該可以看到 `API` 資料夾，將他轉換成應用程式。
    ![28](https://hackmd.io/_uploads/S1-Lnig96.png)

5. 這樣設定就完成囉！可以開啟網頁測試看看，前端路由維持不變，後端路由起始則會變成 `app.zerosum.com.tw/JewelCloudWeb/API`，下圖一樣測試 API 的 Swagger 頁面。
    ![29](https://hackmd.io/_uploads/rJUN2jg56.png)
