進行ASP.NET容器化-以ASP.NET MVC/Web API為例

進行ASP.NET容器化-以ASP.NET MVC/Web API為例

要將 ASP.NET MVC / ASP.NET Web API 轉移至 Docker Container 中運行,看似麻煩,但其實非常簡單。以下討論不使用工具與使用 Visual Studio for Docker 工具來達成轉移的工作。

Step1 - 手動進行 ASP.NET MVC / Web API 容器化

第一步,將 ASP.NET MVC / ASP.NET Web API 進行本機部署。

  • 在「發行」選擇「目錄]
  • 路徑採用預設的「bin\Release\PublishOutput」
  • 發行設定檔完成後,修改設定檔發行選項,勾選「發行期間預先編譯」

因為將要發行至 Container 進行檢視與測試,代表應用程式已經接近 Release,可以採用預先編譯。修改好了之後,可以發行至指定目錄。

第二步,我們要製作 MVC / Web API 應用程式的 Image。

首先要先選擇基礎 Image,連線至 Docker Hub - microsoft/aspnet 選擇。Docker Hub - microsoft 包含所有 Microsoft 目前所有 Docker 的 Linux / Windows 平台基礎 Images。基礎 Images 的說明請自行參考。這裡比較容易搞混的地方在於,microsoft/iismicrosoft/aspnet 兩者,microsoft/iis 想成只單純啟用 IIS 的伺服器,microsoft/aspnet 是以 microsoft/iis 為基礎 Image 再加上其他如 .NET Framework 的執行環境。這裡我們選擇 microsoft/aspnet 作為我們的基礎 Image。

在選擇 microsoft 的 Image 時,有個小技巧,請多注意 Tags 裡的編譯條件,盡量選擇 windowsservercore 或 nanoserver 的版本,少選擇 latest 版本。最明顯的差異是節省大量空間,例如,aspnet:latest 與 aspnet:4.7.1 約 7GB 大小,但 aspnet:4.7.1-windowsservercore-1709 約 4GB。有興趣的讀者可自行瞭解 Windows Server / Server Core / Nano Server 的差異。

在專案根目錄下撰寫 Dockerfile:

FROM microsoft/aspnet:4.7.1-windowsservercore-1709
COPY ./bin/Release/PublishOutput /inetpub/wwwroot

預設 microsoft/aspnet 只含 .NET Framework 4.6.2 執行環境,這裡我們採用較高的 .NET Framework 4.7.1 版本。

建議先把基礎 Image 先下載好:docker pull microsoft/aspnet:4.7.1-windowsservercore-1709

接下來就能建置出我們要的應用程式版本的 Image:

docker build -t aspnetapp .
docker run -d --name aspnetapp aspnetapp

取得取得連線 IP:

docker inspect aspnetapp
docker exec aspnetapp ipconfig

現在就能透過取得的 IP 進行 http://IP 來連線測試。

使用 Docker Support 工具進行 ASP.NET MVC / Web API 容器化

ASP.NET MVC 或 ASP.NET Web API 專案 --> 新增 --> Docker Support。

點選之間就完成所有 Docker 所需的組態檔的產生,不過和剛剛不太一樣,Docker Support 是使用 docker-compose 方式來進行建置與執行,所以 Dockerfile 的內容有些差異,而且 Visual Studio 會在背景就開始產生所需要 Image,可以在輸出視窗看到如下訊息:

========== Preparing Containers ==========
Getting Docker containers ready...
docker-compose  -f "Z:\webapp5\docker-compose.yml" -f "Z:\webapp5\docker-compose.override.yml" -f "Z:\webapp5\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose17244174905642050223 --no-ansi config
networks:
  default:
    external:
      name: nat
services:
  webapp5:
    build:
      args:
        source: obj/Docker/empty/
      context: Z:\webapp5\webapp5
      dockerfile: Dockerfile
    entrypoint: cmd /c "start /B C:\\ServiceMonitor.exe w3svc & C:\\remote_debugger\\x64\\msvsmon.exe
      /noauth /anyuser /silent /nostatus /noclrwarn /nosecuritywarn /nofirewallwarn
      /nowowwarn /timeout:2147483646"
    environment:
      DEV_ENVIRONMENT: '1'
      VBCSCOMPILER_TTL: '604800'
    image: webapp5:dev
    ports:
    - 80/tcp
    volumes:
    - Z:\webapp5\webapp5:C:\inetpub\wwwroot:rw
    - C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Remote
      Debugger:C:\remote_debugger:ro
version: '3.0'
docker-compose  -f "Z:\webapp5\docker-compose.yml" -f "Z:\webapp5\docker-compose.override.yml" -f "Z:\webapp5\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose17244174905642050223 --no-ansi build 
Building webapp5
Step 1/4 : FROM microsoft/aspnet:4.7.1-windowsservercore-1709
 ---> dc3f4d701ead
Step 2/4 : ARG source
 ---> Using cache
 ---> 9b042835351f
Step 3/4 : WORKDIR /inetpub/wwwroot
 ---> Using cache
 ---> 0cb87dce5d0a
Step 4/4 : COPY ${source:-obj/Docker/publish} .
 ---> Using cache
 ---> fafda2039875
Successfully built fafda2039875
Successfully tagged webapp5:dev
docker-compose  -f "Z:\webapp5\docker-compose.yml" -f "Z:\webapp5\docker-compose.override.yml" -f "Z:\webapp5\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose17244174905642050223 --no-ansi up -d --no-build --force-recreate --remove-orphans
Creating dockercompose17244174905642050223_webapp5_1 ... 
Creating dockercompose17244174905642050223_webapp5_1 ... done
Done!  Docker containers are ready.

Dockerfile 差異不大:

FROM microsoft/aspnet:4.7.1-windowsservercore-1709
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .

ARG source 就是宣告一個參數 source。在上面輸出訊息的 service/webapp5/build/args/source 被指定進來,其實展開後和我們手動的 Dockerfile 沒什麼差異。

如果是全新的 ASP.NET MVC 或 ASP.NET Web API 專案,那麼更簡單,在一開始開專案時就勾選「啟用 Docker Support」,等同於「專案 --> 新增 --> Docker Support」的動作。 不管是手動組態來支援 Docker 或 Docker Support 來產生 docker-compose 與 Dockerfile 的組態,你都能看到,要將現行 .NET Framework 架構的 ASP.NET MVC/Web API 專案放入 Docker Container 裡去運行都不是那麼困難。執行比較難的可能是 Windows Container 管理與操作,Windows Container 的文件資源不夠,還有週邊 Images 成熟度與配套不及 Linux Container 的事實。不過,如果你的執行環境原本就是 Windows/IIS 的話,那麼搞不好 Windows Container 反而是利多。


2 則留言:

  1. 選 Windows 系的 image 可以在 Linux Docker host 跑嗎?
    以及有授權或 CAL 之類的費用產生嗎?

    回覆刪除
    回覆
    1. 不行哦。Linux 能在 Windows 跑,Windows 不能在 Linux 的跑。

      刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。