本文翻譯自Hans Kilian的文章 Creating a containerized .NET core application in less than 10 lines of code https://medium.com/@hkkilian/creating-a-containerized ...
本文翻譯自Hans Kilian的文章
Creating a containerized .NET core application in less than 10 lines of code
Docker的一個優勢是你可以在別人的容器之上創建你自己的容器。在這片文章我將向你展示怎麼快速得創建一個包含.net core應用的docker容器。
我們需要的僅僅只是一臺安裝了docker的機器,並且能連接上internet。
創建一個目錄並且在該目錄中創建一個文件“Dockerfile”。打開那個文件,粘貼一下的代碼行,並且保存。
FROM microsoft/dotnet:2.1-sdk AS build-env WORKDIR /app RUN dotnet new razor RUN dotnet publish -c Release -o out FROM microsoft/dotnet:2.1-aspnetcore-runtime-alpine WORKDIR /app COPY --from=build-env /app/out ./ ENTRYPOINT ["dotnet", "app.dll"]
在終端中執行命令 “docker build -t myapp .”
這行命令從當前目錄的Dockerfile文件創建了一個docker鏡像並且給這個鏡像取了一個名字叫做“myapp”的標簽。
然後我們就可以通過輸入命令“docker run -d -p 80:80 myapp”運行這個容器化的應用了。
然後當你打開你的瀏覽器並且導航到http://localhost/你將看到下麵顯示的屏幕:
這是怎麼運行的呢?
上邊的那個Dockerfile指定了多級構建,包含有兩個部分,每個部分四行。第一部分為要運行的應用生成並編譯了源碼,第二部分把編譯好的應用打包進一個我們能運行的容器中。多級構建在docker17.05中才開始有介紹,因此如果你要使用該特性的話你需要17.05或者更新的docker版本。
- 第一行指出了我們將基於微軟提供的.NET core 2.1 SDK來構建我們想要的docker鏡像。我們給.NET core 2.1 SDK取個別名“build-env”,這在後邊會用到。
- 第二行中我們創建了一個工作目錄“/app”。
- 第三行中我們在上邊創建的目錄中執行命令“dotnet new razor”,這行命令使用Razor pages創建了一個基本的asp.net應用程式所需要的所有的源代碼。
- 第四行中我們發佈上邊的應用到“out”目錄。全路徑是“/app/out”。“publish”命令足夠智能,它可以在發佈之前自動還原所需要的Nuget包並且進行編譯。
Dockerfile中的最後四行將發佈了的應用程式打包進一個只包含.net core運行時環境的docker鏡像中。當我們運行這個應用的時候完全沒有必要包含整個的sdk。我們想要運行的鏡像越小越好。
第一行我們首先指定我們想要開始構建一個跟上一個不一樣的docker鏡像。這次我們將會使用基於包含了ASP.NET core運行時環境的Alpine linux分支開始構建。Alpine是一個非常小的linux發行版本,並且被廣泛地使用與docker基礎鏡像中。
然後我們再次創建了一個工作目錄“/app”,這跟第一次創建的“/app”不是同一個目錄,因為我們現在正在構建一個新的docker鏡像。
然後我們從第一個創建的鏡像中複製應用的文件。“--from=build-env”選項指定了我們想要的是從第一個創建的鏡像中複製。我們從第一個創建的鏡像中複製了所有的“/app/out”目錄下的文件到當前的目錄/app
然後我們指定了容器的運行入口是dotnet 命令並且還要跟上參數“app.dll”。
當我們運行這個鏡像的時候,我們指定了幾個運行參數。第一個參數“-d”指定了該鏡像應該在後臺運行。第二個參數“-p 80:80”指定了容器中的80埠應該被映射到運行容器的機器的80埠上。如果你機器上的80埠被占用了,你可以使用其他埠進行映射。比如你想映射到運行docker的機器的8080埠,你可以使用“-p 8080:80”,然後你可以通過“http://localhost:8080/”訪問該應用。不管你映射到機器上的哪個埠,應用程式表現出來的是不變的,就像它一直使用的是80埠一樣。
你可以使用docker命令“docker ps”查看當前運行的docker鏡像。
你也可以使用“docker kill <name>”停止容器。
從這裡我們將要進一步學習些什麼?
當然了這不是一個有用的示例。為了讓示例更加接近實際,你可以很容易地改變這個例子去容器化一個自定義的c#工程項目。假設你有一個子目錄“code”,其中含有你的項目源碼,你可以替換“RUN dotnet new razor” 為“COPY ./code/ ./”,僅僅就改變這一行,你就可以構建你自定義的項目。或者你還可以從使用“git clone”命令從git上拉取項目。
在docker容器中構建你的解決方案的另外一個好處是你不需要擔心你電腦上安裝的sdk的版本衝突。如果你想嘗試NET core 2.2 preview,你可以很簡單地使用下邊的代碼來使用2.2 的SDK和2.2的 ASP.NET 運行時環境:
FROM microsoft/dotnet:2.2.100-preview3-sdk AS build-env WORKDIR /app RUN dotnet new razor RUN dotnet publish -c Release -o out FROM microsoft/dotnet:2.2.0-preview3-aspnetcore-runtime-alpine WORKDIR /app COPY --from=build-env /app/out ./ ENTRYPOINT [“dotnet”, “app.dll”]
如果你不喜歡這樣的結果(2.2 preview現在似乎沒有2.1好用),你不需要卸載任何的2.2的preview SDK,因為你的機器上從來沒有安裝過它。2.2 SDK僅僅只是安裝在docker鏡像之中的,僅僅只是下載下來並沒有運行,除非你要求運行該鏡像的時候。
如果你想查看其他的合適的.NET Docker鏡像,你可以從這裡開始https://hub.docker.com/r/microsoft/dotnet/
我希望這篇文章可以鼓勵你嘗試使用docker或者.NET core,如果你從來沒有嘗試過的話。添加一個類似PostgreSQL 資料庫將會非常簡單,因為這裡已經有構建好的合適的docker鏡像可以使用,你根本不需要任何的定製化。當你有多個需要相互之間進行通信的容器的時候,docker-compose是一個很棒的工具,它可以使用一個簡單的命令加速並接管控制多個容器。