docker容器化.NET程式

疾风不问归途發表於2024-10-12

C# 使用 docker 容器化程式

建立 dockerfile

單專案應用:如果你的應用只有一個 .csproj 檔案,建議將 Dockerfile 放在該 .csproj 檔案所在目錄,這樣更加簡單、清晰,且易於維護。

多專案解決方案:如果你的專案有多個子專案,並且你希望構建整個解決方案或特定的子專案,建議將 Dockerfile 放在解決方案根目錄下(與 .sln 同一層級)。這樣可以更容易地管理依賴關係,並構建多個專案。

適用於多專案解決方案:這種方法更適合有多個子專案的解決方案。如果你有多個 .csproj 檔案,並且需要構建整個解決方案,這種結構是最佳選擇。
管理多個專案:可以從解決方案層級管理和構建多個專案,而不是單個專案。
選擇哪種方式?

編寫dockerfile

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /App

COPY . ./

RUN dotnet restore

RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]

解釋dockerfile

#第一階段:構建階段

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env:
#指定.NET SDK 8.0 的官方基礎映象來定義了一個名為 build-env 的構建環境,我們可以在後面引用這個環境。

WORKDIR /App:
#這會在容器內建立一個工作目錄 /App 並將其設為當前工作目錄。後續的所有命令都將在這個目錄中執行。
#如果 /App 目錄不存在,它會自動建立。

COPY . ./:
#將當前目錄(也就是包含 Dockerfile 的目錄)的所有檔案複製到容器的 /App 目錄中。

RUN dotnet restore:
#執行 dotnet restore 命令,恢復專案依賴項和 NuGet 包。它會基於專案的 .csproj 或 .sln 檔案下載專案的依賴庫。
#這個步驟通常會快取起來以避免每次構建都重複下載依賴項。


RUN dotnet publish -c Release -o out:
#這個命令會編譯專案併發布(生成)一個釋出版本(Release)的構建。
#-c Release 指定構建配置為 Release(最佳化後的生產環境版本)。
#-o out 表示將編譯好的檔案輸出到 /App/out 目錄中。


#第二階段:執行時環境

FROM mcr.microsoft.com/dotnet/aspnet:8.0:
#使用的是較輕量的 .NET Runtime 映象,也就是 ASP.NET Core 執行時映象,只包含執行 .NET 應用程式的必要元件,而沒有用於構建和除錯的工具,這使得它體積較小,非常適合生產環境部署。


WORKDIR /App:
#再次建立並設定工作目錄為 /App,這次是在執行時映象中建立的。


COPY --from=build-env /App/out .:
#這裡是多階段構建的關鍵之處。
#COPY --from=build-env 表示從之前的 build-env 階段中複製檔案。
#具體來說,它將構建階段中 /App/out 目錄下的所有已編譯和釋出的檔案複製到當前階段(執行時階段)的工作目錄 /App 下。


ENTRYPOINT ["dotnet", "DotNet.Docker.dll"]:
#這個命令定義了容器啟動時的預設命令。在這裡,ENTRYPOINT 指定容器執行時將執行 dotnet DotNet.Docker.dll,也就是執行編譯好的 .NET 應用程式。
#DotNet.Docker.dll 是在之前的 dotnet publish 階段生成的應用程式的主可執行檔案。
#(DotNet.Docker.dll 這個是自己專案釋出的檔案,可以去釋出目錄檢視自己的執行檔案)

構建映象

#若是提示(許可權不足)connect: permission denied

#那就在命令前面新增 sudo

#如 docker images 就寫成 sudo docker images   (檢視映象)
#sudo docker images -a (檢視所有映象)

#如 docker ps 就寫成 sudo docker ps   (檢視執行中的容器)
#sudo docker images -a (檢視所有容器)
docker build -t image-name -f Dockerfile .

#1. docker build
#docker build 命令用於從指定的 Dockerfile 構建一個 Docker 映象。它會根據 Dockerfile 中的指令,逐步建立映象層,並最終生成一個可以執行的 Docker 映象。

#2. -t image-name
#-t 選項是 --tag 的簡寫,它用於為構建的映象指定一個標籤(tag)。

#3. -f Dockerfile
#-f 選項是 --file 的簡寫,它用於指定構建過程中使用的 Dockerfile。

#4. .(上下文)
#. 代表構建上下文(build context)。構建上下文是指 Docker 將哪些檔案傳送到 Docker 守護程序(Docker Daemon)用於映象的構建。
#在這個命令中,. 表示當前目錄作為上下文。也就是說,當前目錄下的所有檔案和子目錄會被髮送給 Docker 守護程序供其使用。

現在你已經建立好一個映象了

根據映象建立容器

docker create core-name image-name
#create 命令建立容器,core-name是容器名稱,image-name是映象名稱


docker run image-name
#run 命令 建立並執行容器 

#可選引數

#1. 後臺執行容器(Detached Mode)
#docker run -d image-name
#使用 -d 選項可以讓容器在後臺執行,通常稱為“守護模式”(detached mode)。
#這將基於 myapp:latest 映象啟動一個容器,並使其在後臺執行,而不會佔用當前終端。

#2. 命名容器
#docker run --name my_container image-name
#使用 --name 選項可以為容器指定一個名稱,方便管理和跟蹤。
#這會建立並執行一個名為 my_container 的容器。

#3. 繫結埠
#docker run -p 8080:80 image-name
#如果容器中的應用程式監聽某個埠(如 Web 伺服器),你可以使用 -p 選項將主機埠對映到容器內部埠。
#這會將主機的埠 8080 對映到容器的埠 80。如果容器中的應用執行在 80 埠,你可以透過訪問主機的 8080 埠與之互動。

#4. 互動模式(Interactive Mode)
#docker run -it ubuntu /bin/bash
#使用 -it 可以讓容器以互動模式執行,通常用於需要與容器內部的命令列互動。
#這會啟動一個基於 ubuntu 映象的容器,並開啟一個互動式的 Bash 終端。你可以在容器中執行命令,退出容器時,它會自動停止。

#5. 掛載卷
#docker run -v /path/on/host:/path/in/container image-name
#使用 -v 選項可以將主機上的目錄掛載到容器中,方便資料共享或持久化。
#這會將主機上的 /path/on/host 目錄掛載到容器的 /path/in/container 目錄。

#6. 自動刪除容器
#docker run --rm image-name
#使用 --rm 選項可以在容器停止後自動刪除它。這樣可以避免堆積無用的停止狀態的容器。

#7. 檢視日誌
#docker logs <container_name_or_id>
#當容器在後臺執行時,可以使用 docker logs 檢視容器的輸出日誌。

#8. 環境變數
#docker run -e MY_ENV_VAR=value image-name
#使用 -e 選項可以向容器傳遞環境變數。
#這會在容器內部設定 MY_ENV_VAR 環境變數,值為 value。

其他

連線到容器來檢視輸出。 使用 docker attach 命令檢視輸出流

docker attach --sig-proxy=false core-counter
#core-counter為容器名稱

將映象儲存匯出

docker save -o save-image-name.tar image-name
#將名為'image-name'的映象,儲存到當前目錄下,名稱為'save-imaage-name.tar'

docker匯入映象

docker load -i save-image-name.tar
#將當前目錄下的 save-image-name.tar 映象檔案匯入至docker

停止容器

docker stop core-counter
#core-counter為容器名稱

刪除容器與映象

docker rm core-counter
#core-counter為容器名稱

docker rmi image-name
#core-counter為容器名稱

相關文章