[隨手筆記] .NET與Docker Container微服務實務應用

[上課筆記] .NET與Docker Container微服務實務應用

Docker desktop 切換至Windows Container方法

(因為 .NET Framework 程式只能跑在 Windows 容器上(不是 Linux 容器),所以 Docker Desktop 必須切換到 Windows 容器模式。)

開發人員本機電腦Windows功能勾選啟用以下兩項:
   - Containers(容器)                                                                                                                                                      
   - Hyper-V                                                                                                                                                   
                                                                                                                                                                             
須重新開機                                                                                                                                                              
                                                                                                                                                                             
Docker Desktop 設定的 「Use the WSL 2 based engine」 的選項勾消

DockerDesktop的安裝設定檔 C:\ProgramData\DockerDesktop\install-settings.json 裡面寫著:

 {
   "noWindowsContainers": true,    ← 這裡明確禁止了 Windows 容器!
   "wslEngineEnabled": false
 }

 需要把 "noWindowsContainers" 改成 false。這個檔案需要系統管理員權限才能修改。

用系統管理員身份開啟記事本或任何文字編輯器,修改這個檔案:

 路徑:C:\ProgramData\DockerDesktop\install-settings.json

 改成:
 {
   "noWindowsContainers": false,
   "wslEngineEnabled": false
 }

 改完存檔後,重新啟動 Docker Desktop(右鍵鯨魚圖示 → Restart)

C:\Program Files\Docker\Docker 目錄下執行cmd:DockerCli.exe -SwitchWindowsEngine

如此一來 Windows工作列右下角右鍵鯨魚圖示才會出現「Switch to Windows containers...」選項

cmd驗證docker desktop已切換至windows container:docker version

驗證結果:docker version 顯示 Server OS/Arch: windows/amd64,Context: desktop-windows。

.dockerignore 範例(略過哪些檔案不要打包進 image 映像檔)
.vs/
WebNet/obj/
WebNet/Properties/
packages/
*.user
*.suo
*.cs
*.vb
*.csproj
packages.config
Dockerfile
docker-compose.yml
.dockerignore
.git/
.gitignore
.Net 方案目錄下的 Dockerfile範例(描述如何打包 image 映像檔),網站名稱為Webnet
# 使用官方 ASP.NET 4.8.1 映像檔(已內建 IIS + .NET Framework 4.8.1,基於 Windows Server 2022)
# 版本相容規則:容器的 Windows 版本不能高於本機電腦的 Windows 版本。
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8.1-windowsservercore-ltsc2022

# 設定工作目錄為 IIS 預設網站位置
WORKDIR C:/inetpub/wwwroot

# 清除 IIS 預設歡迎頁面
RUN powershell -Command "Remove-Item -Recurse -Force C:\inetpub\wwwroot\*"

# 複製應用程式檔案到容器
COPY WebNet/bin/ ./bin/
COPY WebNet/Views/ ./Views/
COPY WebNet/assets/ ./assets/
COPY WebNet/App_Data/ ./App_Data/
COPY WebNet/Global.asax ./Global.asax
COPY WebNet/Web.config ./Web.config

# 建立自簽憑證並綁定到 IIS HTTPS(開發測試用)
RUN powershell -Command " \
    $cert = New-SelfSignedCertificate -DnsName 'localhost' -CertStoreLocation 'Cert:\LocalMachine\My'; \
    New-WebBinding -Name 'Default Web Site' -Protocol https -Port 443; \
    $binding = Get-WebBinding -Name 'Default Web Site' -Protocol https; \
    $binding.AddSslCertificate($cert.Thumbprint, 'My')"

# 宣告容器只使用 port 443(HTTPS)
EXPOSE 443
.Net 方案目錄下的 docker-compose.yml 範例 (描述如何啟動容器)
# 定義要執行的容器服務
services:
  # 服務名稱(自己取的,叫 webnet,用於容器間連線)
  web: # 一個服務 = 一個容器(預設情況下)
    image: webnet:v20260325        # 建置出來的映像檔名稱
    # 容器的名稱(在 Docker Desktop 裡看到的名字)
    container_name: webnet-v20260325 # 容器名稱不能用冒號,改用減號
    # 建置映像檔的設定
    build:
      # 建置的根目錄(. = 當前資料夾,也就是 .Net 方案根目錄)
      context: .
      # 使用哪個 Dockerfile 來建置
      dockerfile: Dockerfile
    # port 對應(本機電腦主機:容器)
    ports: 
      - "8443:443"  # 本機電腦的 8443 port 對應 容器內的 443 port
    restart: always # 主機重開機,永遠自動重新啟動
    

 以下cmd指令都不需要額外參數,直接複製貼上執行就好。但要注意必須在.Net 方案目錄下執行(也就是 docker-compose.yml 所在的資料夾)。

建置映像檔:docker compose build

這會讀取 docker-compose.yml 和 Dockerfile,下載基底映像檔並打包你的應用程式。首次約 5-15 分鐘。

建立容器(不啟動):docker compose create

根據映像檔建立容器,但不會啟動它。

啟動容器:docker compose start

啟動剛才建立的容器。

本機電腦的瀏覽器開啟網址瀏覽容器內的網站:https://localhost:8443

 

客戶主機Windows Server 2022 的部署方式
在客戶主機上執行PowerShell 安裝 Docker(如果尚未安裝)
    Install-WindowsFeature -Name Containers
    Restart-Computer
    Install-Module DockerMsftProvider -Force
    Install-Package Docker -ProviderName DockerMsftProvider -Force
    Restart-Computer

以下實戰我還沒遇過,但這邊先記著當作未來的待辦事項

本機開發用自簽的SSL憑證,客戶主機用正式 SSL 憑證。
同一個映像檔要支援兩種情境,透過啟動容器時的參數不同(判斷是否掛載憑證)來決定。

 本機開發

 Web.config 打包在映像檔裡面(透過 Dockerfile 的 COPY WebNet/Web.config ./Web.config),不需要額外處理。

 客戶主機

 啟動容器時用 -v 掛載客戶專用的 Web.config,覆蓋映像檔裡的那份:

 docker run -d -p 443:443 --name webnet --restart=always ^
   -v C:\certs:C:\certs ^
   -v C:\config\Web.config:C:\inetpub\wwwroot\Web.config ^
   -e CERT_PATH=C:\certs\webnet.pfx ^ 
    -e CERT_PASSWORD=憑證密碼 ^
   webnet-web

客戶主機無法連上網,本機程式部份網頁檔透過Volume的部份檔案部署更新至客戶主機

https://claude.ai/share/2ac09eb0-5a26-47a5-a6d3-bca9d86e83a8