社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

优化 ASP.NET Core Docker 镜像的大小

dotNET跨平台 • 5 年前 • 599 次点击  

在这容器化的世界里,我们已经很少直接通过文件发布来运行asp.net core程序了。现在大多数情况下,我们都会使用docker来运行程序。在使用docker之前,我们往往需要打包我们的应用程序。asp.net core程序的镜像打包,网上有很多教程,其中大多数是使用sdk这个镜像来直接打包。打出来的包有好几百MB,3.1 SDK打出来的包甚至超过了1GB。那么有什么办法来缩小我们打出来的镜像吗?最小能缩小到多少呢?这篇文章就来介绍下如何缩小asp.net core 打包出来镜像的大小。

新建asp.net core 程序

新建一个asp.net core应用程序,用来演示打包。首先我们演示下如果使用dotnet sdk5.0来打包 docker 镜像。

sdk:5.0

  1. FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build

  2. WORKDIR /app

  3. COPY /. /app

  4. RUN dotnet restore -s https://nuget.cdn.azure.cn/v3/index.json

  5. WORKDIR /app/CoreDockerImageSizeTest

  6. RUN dotnet publish -o ./out -c Release

  7. EXPOSE 5000

  8. ENTRYPOINT ["dotnet", "out/CoreDockerImageSizeTest.dll"]

在项目根目录下新建一个Dockerfile文件,文件内容如上。这个Dockerfile比较简单,使用dotnet sdk:5.0最为底层包来构建,这也是最傻瓜的打包方式。那么看看这个镜像打出来有多大吧。

  1. docker build . -t coredockerimagesizetest_0.1

使用docker build命令进行打包。

  1. REPOSITORY TAG IMAGE ID CREATED SIZE

  2. coredockerimagesizetest_0.1 latest 14aea8e0c1d5 5 seconds ago 643MB

使用docker images命令来查看镜像列表,我们发现我们打出来的镜像居然有643MB,真的很大。如果是内网还好一点,如果在镜像存在docker hub等第三方仓库,这得下半天。显然这个镜像太大了,接下来看我们如何进行优化。

sdk:5.0-buster-slim

最新的VisualStudio内置了docker工具,可以自动为我们生成Dockerfile文件。我们来看看它生成的镜像文件有多大。

右键解决方案=>添加=>Docker支持=>Linux 。
选择完成后VS会为我们自动添加一个Dockerfile在根目录。

  1. FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base

  2. WORKDIR /app

  3. EXPOSE 5000


  4. FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build

  5. WORKDIR /src

  6. COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"]

  7. RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj"

  8. COPY . .

  9. WORKDIR "/src/CoreDockerImageSizeTest"

  10. RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build


  11. FROM build AS publish

  12. RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish


  13. FROM base AS final

  14. WORKDIR /app

  15. COPY --from =publish /app/publish .

  16. ENTRYPOINT ["dotnet", "CoreDockerImageSizeTest.dll"]

这个自动生成的Dockerfile使用了sdk:5.0-buster-slim这个镜像进行build跟publish,使用aspnet:5.0-buster-slim这个runtime级别的镜像做为final底包。从名字来看,很明显slim代表着轻量。让我们试试这个Dockerfile打出来的包有多大。

  1. REPOSITORY TAG IMAGE ID CREATED SIZE

  2. coredockerimagesizetest_0.2 latest 0a24618f6ece 11 seconds ago 210MB

使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为210MB。果然比上面的镜像小了很多。那么是否还能继续缩小镜像的大小呢?继续往下看。

5.0-alpine

除了使用buster-slim镜像,我们还可以选择更加小巧的alpine镜像来打包。alpine镜像是继续alpine linux创建的镜像,所以它更加轻量级更加小巧。
关于alpine linux可以查看这篇:Alpine Linux 与 CentOS 有什么区别?。

  1. FROM mcr.microsoft.com/dotnet /aspnet:5.0-alpine AS base

  2. WORKDIR /app

  3. EXPOSE 5000


  4. FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build

  5. WORKDIR /src

  6. COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"]

  7. RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj"

  8. COPY . .

  9. WORKDIR "/src/CoreDockerImageSizeTest"

  10. RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build


  11. FROM build AS publish

  12. RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish


  13. FROM base AS final

  14. WORKDIR /app

  15. COPY --from=publish /app/publish .

  16. ENTRYPOINT ["dotnet", "CoreDockerImageSizeTest.dll"]

修改Dockerfile使用aspnet:5.0-alpine及sdk:5.0-alpine来构建这个镜像。

  1. REPOSITORY TAG IMAGE ID CREATED SIZE

  2. coredockerimagesizetest_0.3 latest db34d613e21a 12 seconds ago 108MB

使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为108MB。现在这个镜像已经比我们第一次打包减少了500多MB了。那么还能更小吗?请往下看。

runtime-deps:5.0-alpine

最新的.net core程序支持自宿主及单文件发布。如果采用以上发布形式,那么我们可以选择使用runtime-deps:5.0-alpine做为最终底包来打包我们的镜像。

  1. FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS base

  2. WORKDIR /app

  3. EXPOSE 5000


  4. FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build

  5. WORKDIR /src

  6. COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"]

  7. RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj"

  8. COPY . .

  9. WORKDIR "/src/CoreDockerImageSizeTest"

  10. RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build


  11. FROM build AS publish

  12. RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish \

  13. --runtime alpine-x64 \

  14. --self-contained true \

  15. /p:PublishTrimmed=true \

  16. /p:PublishSingleFile=true


  17. FROM mcr.microsoft.com/dotnet/runtime-deps:5.0-alpine AS final

  18. WORKDIR /app

  19. COPY --from=publish /app/publish .

  20. ENTRYPOINT ["./CoreDockerImageSizeTest"]

修改Dockerfile,使用/runtime-deps:5.0-alpine做为final镜像。

  1. REPOSITORY TAG IMAGE ID CREATED SIZE

  2. coredockerimagesizetest_0.5 latest dab1289626f9 6 seconds ago 54.6MB

使用docker build命令进行打包。使用docker images命令查看镜像的大小,这个镜像的大小为54.6MB。

总结

通过以上演示,我们的镜像大小从一开始的600多MB缩小到了54MB。一般生产我主要选择buster-slim这个镜像来打包。如果选择runtime-deps打包,打出来的包是最小的,虽然演示项目是可以运行的,但是本人没有在生产使用过,还请谨慎使用。
代码在这:CoreDockerImageSizeTest

关注我的公众号一起玩转技术


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110519