優化 .net core 應用的 dockerfile

2022-01-02 dotNET跨平臺

優化 .net core 應用的 dockerfileIntro

在給 .net core 應用的寫 dockerfile 的時候一直有個苦惱,就是如果有很多個項目,在 dockerfile 裡寫起來就會很繁瑣,有很多項目文件要 copy,dockerfile 還不支持直接批量複製項目文件,今天要改的一個項目也是有好多個項目文件,不想再一個一個複製,於是 google 一下看有沒有比較好的解決方案,找到一個折中的解決方案,分享一下

Solution

首先把所有的項目文件拷貝到 docker 鏡像內 COPY */*.csproj ./

然後根據項目文件名稱創建項目文件夾,並移動項目文件到對應的項目目錄下

原來的 dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine AS build-env
WORKDIR /src


COPY ActivityReservation.Common/*.csproj ActivityReservation.Common/
COPY ActivityReservation.Models/*.csproj ActivityReservation.Models/
COPY ActivityReservation.DataAccess/*.csproj ActivityReservation.DataAccess/
COPY ActivityReservation.Business/*.csproj ActivityReservation.Business/
COPY ActivityReservation.Helper/*.csproj ActivityReservation.Helper/
COPY ActivityReservation.WechatAPI/*.csproj ActivityReservation.WechatAPI/
COPY ActivityReservation.AdminLogic/*.csproj ActivityReservation.AdminLogic/
COPY ActivityReservation.API/*.csproj ActivityReservation.API/
COPY ActivityReservation/ActivityReservation.csproj ActivityReservation/



WORKDIR /src/ActivityReservation
RUN dotnet restore


COPY . .
RUN dotnet publish -c Release -o out ActivityReservation/ActivityReservation.csproj


FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine

LABEL Maintainer="WeihanLi"
WORKDIR /app
COPY --from=build-env /src/ActivityReservation/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "ActivityReservation.dll"]

修改之後的 dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine AS build-env
WORKDIR /src



COPY */*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p ${file%.*}/ && mv $file ${file%.*}/; done


WORKDIR /src/ActivityReservation
RUN dotnet restore


COPY . .
RUN dotnet publish -c Release -o out ActivityReservation/ActivityReservation.csproj


FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine

LABEL Maintainer="WeihanLi"
WORKDIR /app
COPY --from=build-env /src/ActivityReservation/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "ActivityReservation.dll"]

是不是精簡了許多,來看一下修改前後的對比,更明顯的對比一下:

核心代碼:


COPY */*.csproj ./

RUN for file in $(ls *.csproj); do mkdir -p ${file%.*}/ && mv $file ${file%.*}/; done

More

註:上面的方法適用於項目文件目錄名稱和項目文件名稱一致的情況,默認創建的項目應該都會符合這樣的要求,如果你的項目文件是三級目錄,如 src/*/*.csproj 的,需要自己根據項目情況調整 dockerfile

有沒有學到呢~~

Reference

https://stackoverflow.com/questions/51372791/is-there-a-more-elegant-way-to-copy-specific-files-using-docker-copy-to-the-work

https://andrewlock.net/optimising-asp-net-core-apps-in-docker-avoiding-manually-copying-csproj-files-part-2/

https://github.com/WeihanLi/ActivityReservation/blob/dev/Dockerfile

相關焦點

  • Dockerfile最佳實踐
    在容器領域,docker 公司提出的容器鏡像已經成為目前容器打包交付的事實標準。構建鏡像需要編寫 Dockerfile,如何編寫一個優雅的 Dockerfile 呢?在 Docker 公司的官方文檔中給出了一篇  Best practices for writing Dockerfiles。
  • docker容器dockerfile詳解
    1.3s => exporting to image 0.5s => => exporting layers
  • Docker基礎篇(Dockerfile)-雲原生核心
    編寫Dockerfile文件)A --> D(2. docker build)A --> E(3. docker run)腳本文件的樣式,以centos為例在這裡插入圖片描述腳本文件內容FROM scratchADD centos-7-x86_64-docker.tar.xz /LABEL
  • Dockerfile 中的 COPY 與 ADD 命令
    和 ADD,本文嘗試解釋這兩個命令的基本功能,以及其異同點,然後總結其各自適合的應用場景。在使用 docker build 命令通過 Dockerfile 創建鏡像時,會產生一個 build 上下文(context)。所謂的 build 上下文就是 docker build 命令的 PATH 或 URL 指定的路徑中的文件的集合。在鏡像 build 過程中可以引用上下文中的任何文件,比如我們要介紹的 COPY 和 ADD 命令,就可以引用上下文中的文件。
  • Dockerfile與Docker構建流程解讀
    docker build的流程(這部分代碼基本都在docker/builder中)1.提取Dockerfile(evaluator.go/RUN)。2.將Dockerfile按行進行分析(parser/parser.go/Parse) Dockerfile,每行第一個單詞,如CMD、FROM等,這個叫做command。
  • Docker小白到實戰之Dockerfile解析及實戰演示,果然順手
    前言使用第三方鏡像肯定不是學習Docker的最終目的,最想要的還是自己構建鏡像;將自己的程序、文件、環境等構建成自己想要的應用鏡像,方便後續部署、啟動和維護;而Dockerfile就是專門做這個事的,通過類似簡單編碼的形式,最終就可以構建出屬於自己的鏡像,所以必須學起來。正文1.
  • Docker 快速入門之 Dockerfile
    答案當然是可以的,在 Docker 中我們可以從名為 Dockerfile 的文件中讀取指令並且自動構建鏡像。在本文中,將介紹 Dockerfile 的基本語法以及基本知識。1、Dockerfile 是什麼?Dockerfile 其實是一份文本文檔,裡面包含了用戶可以用來操作鏡像的一些指令。
  • 雲計算核心技術Docker教程:Docker多階段構建
    多級構建對於在優化Dockerfile的同時使其易於閱讀和維護的任何人都非常有用。在進行多階段構建之前關於構建鏡像,最具挑戰性的事情之一是保持鏡像尺寸變小。Dockerfile中的每條指令都會在映像上添加一層,您需要記住在移至下一層之前清除不需要的任何工件。
  • 【基礎教程】Docker基礎及應用
    這裡可以看docker的logo來理解,鯨魚拖著許多貨櫃。這就解釋了另外一個應用場景:應用的分離化,假如搭建一個Web網站需要CentOS+Apache+PHP+MySQL,我們即可利用CentOS的貨櫃,Apache的貨櫃和PHP,MySQL的貨櫃來通信實現Web應用,貨櫃之間除了交換數據並沒有多餘的聯繫。0x01 Docker相關的幾個概念1.
  • Dockerfile常用使用方法
    詳解Dockerfile是一個配置文件,可以自動執行創建Docker鏡像的步驟。Docker從Dockerfile中讀取指令,以自動執行原本手動執行的步驟來創建映像。要構建鏡像,請創建一個名為Dockerfile的文件。Dockerfile描述了組裝映像所需的步驟。創建Dockerfile後,調用docker build命令,使用包含Dockerfile的目錄的路徑作為參數。
  • ASP.NET Core容器化技術Docker零基礎從入門到實戰演練
    謝謝大家的理解和支持,預祝大家學習快樂!如果您是一個開發老鳥,那麼本次課程完全不建議您進行學習!1.2、一句話總結今天我們學習達到的目標如何使用Docker來部署搭建ASP.NET Core + Mysql容器化應用程式環境。
  • 你所不了解的 coreDNS
    CoreDNS 是一個 DNS 伺服器。
  • Dockerfile官方文檔詳細介紹
    /dockerfile# syntax=docker/dockerfile:1.0# syntax=docker.io/docker/dockerfile:1# syntax=docker/dockerfile:1.0.0-experimental# syntax=example.com/user
  • Dockerfile使用入門
  • dockerfile中ENTRYPOINT與CMD的結合
    因為這兩個命令是掌握dockerfile編寫的核心,所以這邊還是單獨拿出來再講一講。二、CMD 與 ENTRYPOINT主要區別我們直接進入主題,CMD 與 ENTRYPOINT都是用於指定啟動容器執行的命令,區別在於:•當docker run 命令中有參數時,守護進程會忽略CMD命令。
  • Dockerfile文件全面詳解
    將在當前鏡像之上的新層中執行命令,在 docker build時運行。如果要覆蓋的話,需要通過 docker run --entrypoint 來指定。也就是另外一個 dockerfile FROM 了這個鏡像的時候執行。ONBUILD ADD . /app/srcONBUILD RUN /usr/local/bin/python-build --dir /app/src設置將發送到容器退出的系統調用信號。
  • Dockerfile 文件全面詳解
    如果找不到該 tag 值,構建器將返回錯誤。--platform 標誌可用於在 FROM 引用多平臺鏡像的情況下指定平臺。例如,linux/amd64、linux/arm64、 或 windows/amd64。將在當前鏡像之上的新層中執行命令,在 docker build時運行。
  • .NET Core Docker 再也不用逐個 COPY csproj 文件啦!
    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS baseRUN apt-get update && apt-get install -y libgdiplusWORKDIR /appEXPOSE 80EXPOSE 443FROM
  • .NET 之 Docker 部署詳細流程
    docker部署.net的流程,作為一種學習總結,以及後續會寫一些在該基礎之上的文章。本次示例環境:vs2019、net5、docker、postman創建項目本次事例代碼是用過vs2019創建的ASP.NET Core Web API項目目標框架是.NET 5,無需身份驗證,不配置HTTPS(根據個人需求勾選),啟動Docker(我習慣於後期添加),啟用
  • 無需 Dockerfile 的鏡像構建:BuildPack vs Dockerfile
    部署的第一步就是應用程式的容器化,持續集成的交付物從以往的 jar 包、webpack 等變成了容器鏡像。容器化將軟體代碼和所需的所有組件(庫、框架、運行環境)打包到一起,進而可以在任何環境任何基礎架構上一致地運行,並與其他應用「隔離」。我們的代碼需要從源碼到編譯到最終可運行的鏡像,甚至部署,這一切在 CICD 的流水線中完成。