###### tags: `Docker`, `.NET Core 3.1`, `Synology`, `MVC` # 在 Synology NAS 的 Docker 環境中部署 .NET Core 3.1 應用程式 `本文由 Grok AI 協助編輯` 本文介紹如何在 Synology NAS 的 Docker 環境中部署 .NET Core 3.1 應用程式,並以 Visual Studio 產生的簡單範例網頁為例,展示從專案建立、開發到最終部署的完整流程。本文旨在幫助讀者理解基本的 ASP.NET Core 應用程式部署流程,無需涉及複雜的自訂功能。 --- [toc] --- :::info 實驗環境 - **NAS**: RS3614RPxs, DS720P - **DSM**: 6.2.4-25556 Update 2 - **Windows 開發環境**: .NET Core 3.1 SDK, Visual Studio 2019 ::: --- # 第一部分:建立新專案 ## 步驟 1:安裝必要工具 1. **下載並安裝 Visual Studio 2019**:從 [官方網站](https://visualstudio.microsoft.com/vs/older-downloads/) 下載 Community、Professional 或 Enterprise 版本。 2. **選擇工作負載**:在安裝過程中,勾選「ASP.NET 和 Web 開發」工作負載,確保包含 .NET Core 3.1 的支援。 3. **驗證 .NET Core 3.1 SDK**:安裝完成後,打開命令提示字元,輸入以下命令確認 SDK 已安裝: ```bash dotnet --list-sdks ``` 應顯示 `3.1.xxx` 的版本號。若未顯示,請從 [官方網站](https://dotnet.microsoft.com/download/dotnet/3.1) 下載並安裝。 ## 步驟 2:建立新專案 1. 打開 Visual Studio 2019,點擊「建立新專案」。 2. 在搜尋框中輸入「ASP.NET Core Web」,選擇「ASP.NET Core Web 應用程式」,然後點擊「下一步」。 3. 配置專案: - **專案名稱**:輸入 `SimpleWeb`。 - **位置**:選擇儲存路徑,例如 `D:\NewProjects\`。 - **解決方案名稱**:保持預設或自訂。 4. 在下一個畫面中: - **框架**:選擇 `.NET Core 3.1`。 - **專案類型**:選擇「Web 應用程式(模型-視圖-控制器)」,這將建立一個基於 MVC 架構的應用程式。 - 取消勾選「啟用 Docker 支援」(因為我們將在後續步驟手動配置 Docker)。 5. 點擊「建立」,Visual Studio 將生成一個基本的 MVC 專案。 ## 步驟 3:專案初始結構 建立完成後,專案結構如下: ``` SimpleWeb/ ├── Controllers/ │ └── HomeController.cs ├── Models/ │ └── ErrorViewModel.cs ├── Views/ │ ├── Home/ │ │ ├── Index.cshtml │ │ ├── Privacy.cshtml │ ├── Shared/ │ │ ├── _Layout.cshtml │ │ ├── Error.cshtml ├── wwwroot/ │ ├── css/ │ │ └── site.css │ ├── js/ │ │ └── site.js │ ├── lib/ │ │ ├── bootstrap/ │ │ ├── jquery/ │ │ ├── jquery-validation/ ├── appsettings.json ├── Program.cs ├── Startup.cs ├── SimpleWeb.csproj ``` 這是 ASP.NET Core MVC 的標準結構,提供了一個簡單的首頁(`Index`)和隱私頁面(`Privacy`),由 `HomeController` 控制。此結構是 ASP.NET Core MVC 的預設模板,後續將用於展示基本的部署流程。 --- # 第二部分:MVC 架構介紹 ASP.NET Core 使用 **MVC(Model-View-Controller)** 架構,這是一種常見的設計模式,用於分離應用程式的業務邏輯、資料處理和使用者介面。以下是 MVC 的核心組成部分: 1. **模型(Model)**: - 負責資料的定義與處理,例如資料庫實體或業務物件。 - 在此範例中,`ErrorViewModel.cs` 是預設模型,用於處理錯誤頁面資料。 2. **視圖(View)**: - 負責顯示資料給使用者,通常是 HTML 與 Razor 語法的結合。 - 例如,`Views/Home/Index.cshtml` 是首頁,`Views/Home/Privacy.cshtml` 是隱私頁面。 3. **控制器(Controller)**: - 負責處理使用者請求,與模型交互,並返回適當的視圖。 - 例如,`HomeController.cs` 處理對 `/` 和 `/Privacy` 的請求。 ## MVC 工作流程 - 使用者發送請求(例如訪問 `/`)。 - 控制器(`HomeController`)接收請求,調用對應動作(`Index`)。 - 動作返回視圖(`Index.cshtml`),視圖渲染成 HTML 返回給使用者。 這種分層設計提高了代碼的可維護性和可測試性,是 ASP.NET Core 的核心特性之一。在此範例中,MVC 實現了基本的頁面導航功能。 --- # 第三部分:應用程式概述 此範例應用程式是 Visual Studio 自動生成的預設 MVC 專案,包含以下功能: - **首頁**:由 `HomeController` 的 `Index` 動作提供,顯示歡迎訊息。 - **隱私頁面**:由 `HomeController` 的 `Privacy` 動作提供,展示簡單的隱私聲明。 - **錯誤頁面**:由 `ErrorViewModel` 和 `Error.cshtml` 支援,用於顯示異常資訊。 此應用程式不涉及資料庫或其他複雜邏輯,僅作為展示部署流程的基礎範例。 ## 檔案結構 以下是應用程式的核心檔案結構: ``` SimpleWeb/ ├── Controllers/ │ ├── HomeController.cs // 首頁與隱私頁控制器 ├── Models/ │ ├── ErrorViewModel.cs // 錯誤頁面模型 ├── Views/ │ ├── Home/ │ │ ├── Index.cshtml // 首頁 │ │ ├── Privacy.cshtml // 隱私頁面 │ ├── Shared/ │ │ ├── _Layout.cshtml // 共用佈局 │ │ ├── Error.cshtml // 錯誤頁面 ├── wwwroot/ │ ├── css/ │ │ └── site.css // 自訂樣式 │ ├── js/ │ │ └── site.js // 自訂腳本 │ ├── lib/ │ │ ├── bootstrap/ // Bootstrap 框架 │ │ ├── jquery/ // jQuery 庫 │ │ ├── jquery-validation/ // 表單驗證 ├── appsettings.json // 應用程式配置 ├── Program.cs // 程式進入點 ├── Startup.cs // 服務與中介軟體配置 ├── SimpleWeb.csproj // 專案檔案 ``` 此結構展示了預設應用程式如何利用 MVC 提供簡單的網頁功能。 --- # 第四部分:Dockerfile 建構 為了在 Synology NAS 的 Docker 環境中運行此應用程式,我們需要創建一個適配 .NET Core 3.1 的 Docker 映像。以下是範例的 `Dockerfile`: ```dockerfile FROM FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base WORKDIR /app EXPOSE 80 # 設置時區 ENV TZ=Asia/Taipei RUN apt-get update && apt-get install -y tzdata RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # (選用) 安裝 Oracle 客戶端依賴 RUN apt-get install -y libaio1 # (選用) 設置 Oracle 語言環境 ENV NLS_LANG=AMERICAN_AMERICA.AL32UTF8 # 預設命令(啟動時等待外部應用程式檔案) ENTRYPOINT ["dotnet"] ``` ## Dockerfile 說明 1. **基礎映像**:使用 `mcr.microsoft.com/dotnet/aspnet:3.1`,包含 .NET Core 3.1 運行時。 2. **工作目錄**:設置為 `/app`,應用程式檔案將被複製到此目錄。 3. **端口暴露**:暴露 80 端口作為預設監聽端口。 4. **時區配置**:設置為 `Asia/Taipei`,確保容器時間與本地一致。 5. **(選用) 安裝 Oracle Client**:若後續需連接 Oracle 資料庫,則需安裝此項目。 6. **進入點**:使用 `dotnet` 命令啟動應用程式,具體 DLL 檔案在部署時指定。 ## 建構映像 我們將透過 Windows 建立建構腳本,並在 Synology NAS 上使用 DSM 工作排程器執行映像建構。 ### 步驟 1:編寫建構腳本 1. 在 Windows 上使用文字編輯器(例如記事本或 VS Code)建立一個名為 `build.sh` 的檔案,內容如下: ```bash #!/bin/bash cd /volume1/docker/dotnet-runtime/ docker build -t dotnet-runtime:3.1 . ``` 2. 儲存檔案後,將其上傳至 Synology NAS 的路徑 `/volume1/docker/dotnet-runtime/`。您可以使用 DSM 的「檔案站」或 FTP 工具完成上傳。 3. 確保 `build.sh` 與 `Dockerfile` 皆存在 `/volume1/docker/dotnet-runtime/` 目錄下。 ### 步驟 2:配置 Task Scheduler 1. 打開 Synology DSM,進入「控制面板 > 工作排程器」。 2. 點擊「新增 > 觸發任務 > 使用者定義指令碼」。 3. 設定以下參數: - **一般 > 任務名稱**:`Build Dotnet Runtime` - **一般 > 使用者帳號**:`root` - **一般 > 事件**:`開機`(此設定僅為範例,實際可根據需求調整為其他觸發條件) - **一般 > 已啟動**:`不勾選` - **任務設定 > 執行命令**:`sh /volume1/docker/dotnet-runtime/build.sh` 4. 點擊「確定」保存任務。 5. 在任務列表中,找到 `Build Dotnet Runtime`,右鍵點擊並選擇「執行」以立即建構映像。 6. 執行成功後,任務即可刪除;或保留但請取消勾選「已啟動」以避免開機自動執行。 ### 步驟 3:驗證映像 建構完成後,進入 DSM 的「Docker」套件,在「映像」標籤中檢查是否出現 `dotnet-runtime:3.1`。若成功,則映像已準備好用於部署。 --- # 第五部分:部署流程 ## 步驟 1:發佈應用程式 在 Visual Studio 中: 1. 右鍵點擊 `SimpleWeb` 專案,選擇「發佈」。 2. 選擇「資料夾」作為目標,設置輸出路徑為 `./publish`。 3. 點擊「發佈」,生成應用程式檔案。 或者,使用以下命令直接將應用程式發佈到 NAS 的共享路徑(假設已映射網路磁碟機): ```bash dotnet publish -c Release -r linux-x64 -f netcoreapp3.1 --self-contained false -o "\\172.19.48.55\docker\SimpleWeb" ``` ### 指令說明 - `-c Release`:以 Release 配置編譯,優化性能。 - `-r linux-x64`:指定運行時為 Linux 64 位,適配 Synology NAS 的 Docker 環境。 - `-f netcoreapp3.1`:指定框架為 .NET Core 3.1。 - `--self-contained false`:不包含 .NET Core 運行時,依賴容器中的運行時。 - `-o "\\172.19.48.55\docker\SimpleWeb"`:將發佈檔案直接輸出到 NAS 的共享資料夾(IP 為 `172.19.48.55`)。 ## 步驟 2:將發佈檔案傳輸到 NAS 若未使用上述命令直接發佈,則需手動將 `./publish` 目錄中的檔案複製到 NAS 的卷冊路徑,例如 `/volume1/docker/mywebapp/`。若 NAS 未設置共享路徑映射,請使用 DSM 的「檔案站」手動上傳。若已使用 `dotnet publish` 命令,則無需手動傳輸,因為檔案已直接發佈至 NAS 的共享路徑 `\\172.19.48.55\docker\SimpleWeb`,對應 NAS 的 `/volume1/docker/mywebapp/`(假設共享路徑已正確映射)。 ## 步驟 3:使用 Synology NAS GUI 啟動容器 1. 打開 Synology DSM,進入「Docker」套件。 2. 在「映像」標籤中,若映像已在 NAS 上建構完成,可直接選擇 `dotnet-runtime:3.1`;否則點擊「新增」 > 「從檔案新增」,選擇本機的 `dotnet-runtime:3.1` 映像。 3. 在「容器」標籤中,點擊「建立」: - **映像**:選擇 `dotnet-runtime:3.1`。 - **容器名稱**:自訂,例如 `simpleweb-container`。 - **進階設定**: - **端口設定**:本地端口設為 `62005`,容器端口設為 `5000`。 - **卷冊**:本地路徑設為 `/volume1/docker/mywebapp/`,容器路徑設為 `/app`。 - **命令**:在「執行命令」中輸入 `dotnet /app/SimpleWeb.dll`。 4. 點擊「套用」啟動容器。 ## 步驟 4:驗證部署 在瀏覽器中輸入 `http://<NAS_IP>:62005`,確認應用程式正常運行並顯示預設的 ASP.NET Core 首頁。若需測試隱私頁面,可導航至 `/Privacy`。 --- # 第六部分:修復常見問題 在部署過程中,可能遇到靜態檔案(如 CSS)無法載入的問題。以下是解決方案: 1. **修改內容根路徑**: - 編輯 `Program.cs`,修改如下: ```csharp public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseContentRoot("/app"); // 明確指定內容根 webBuilder.UseStartup<Startup>(); }); ``` - 在 `Startup.cs` 的 `Configure` 方法中確認: ```csharp public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } ``` 2. **重新發佈與部署**: - 重新執行: ```bash dotnet publish -c Release -r linux-x64 -f netcoreapp3.1 --self-contained false -o "./publish" ``` - 上傳到 `/volume1/docker/mywebapp/`,重啟容器。 --- ### 注意事項 1. **連線字串配置**:此範例不涉及資料庫,因此無需配置連線字串。若需擴展功能,請參閱後續文章。 2. **網路設定**:確保 NAS 的防火牆和 Docker 網路允許 62005 端口的外部訪問。 3. **端口衝突**:Dockerfile 暴露 80 端口,但映射到 5000。若應用程式監聽端口不符,請在 `Program.cs` 或 `appsettings.json` 中調整,例如設置 `ASPNETCORE_URLS=http://+:5000`。 --- # 結論 這篇文章展示了一個簡單的 .NET Core 3.1 MVC 應用程式從建立到部署至 Synology NAS Docker 環境的完整流程。讀者可基於此範例,進一步擴展應用程式功能,例如加入資料庫支援(將在下一篇文章中介紹)。