在这容器化的世界里,我们已经很少直接通过文件发布来运行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

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /app
COPY /. /app
RUN dotnet restore -s https://nuget.cdn.azure.cn/v3/index.json
WORKDIR /app/CoreDockerImageSizeTest
RUN dotnet publish -o ./out -c Release
EXPOSE 5000
ENTRYPOINT ["dotnet", "out/CoreDockerImageSizeTest.dll"]

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

docker build . -t coredockerimagesizetest_0.1

使用docker build命令进行打包。

REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
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在根目录。

FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 5000 FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"]
RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj"
COPY . .
WORKDIR "/src/CoreDockerImageSizeTest"
RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CoreDockerImageSizeTest.dll"]

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

REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
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 有什么区别?

FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS base
WORKDIR /app
EXPOSE 5000 FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /src
COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"]
RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj"
COPY . .
WORKDIR "/src/CoreDockerImageSizeTest"
RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CoreDockerImageSizeTest.dll"]

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

REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
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做为最终底包来打包我们的镜像。

FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS base
WORKDIR /app
EXPOSE 5000 FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /src
COPY ["CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj", "CoreDockerImageSizeTest/"]
RUN dotnet restore "CoreDockerImageSizeTest/CoreDockerImageSizeTest.csproj"
COPY . .
WORKDIR "/src/CoreDockerImageSizeTest"
RUN dotnet build "CoreDockerImageSizeTest.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "CoreDockerImageSizeTest.csproj" -c Release -o /app/publish \
--runtime alpine-x64 \
--self-contained true \
/p:PublishTrimmed=true \
/p:PublishSingleFile=true FROM mcr.microsoft.com/dotnet/runtime-deps:5.0-alpine AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["./CoreDockerImageSizeTest"]

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

REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
coredockerimagesizetest_0.5 latest dab1289626f9 6 seconds ago 54.6MB

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

总结

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

代码在这:CoreDockerImageSizeTest

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

优化 ASP.NET Core Docker 镜像的大小的更多相关文章

  1. Asp.Net Core Docker镜像更新系统从wheezy改为stretch

    之前写过一个在Asp.Net Core里调用System.Drawing.Common绘图的DEMO,部署到Docker里运行,需要更新Asp.Net Core镜像的操作系统. https://www ...

  2. ASP.NET Core Docker jexus nginx部署-CentOS实践版

    本文用图文的方式记录了我自己搭建centos+asp.net core + docker + jexus + nginx的整个过程,希望对有同样需求的朋友有一定的参考作用. 本文主要内容如下: cen ...

  3. ASP.NET Core & Docker 实战经验分享

    一.前言 最近一直在研究和实践ASP.NET Core.Docker.持续集成.在ASP.NET Core 和 Dcoker结合下遇到了一些坑,在此记录和分享,希望对大家有一些帮助. 二.中间镜像 我 ...

  4. ASP.NET Core & Docker & Jenkins 零基础持续集成实战

    原文:ASP.NET Core & Docker & Jenkins 零基础持续集成实战 一.本系列教程说明 源代码管理工具:Gogs 持续集成工具:Jenkins 容器:Docker ...

  5. ASP.NET Core Docker部署

    前言 在前面文章中,介绍了 ASP.NET Core在 macOS,Linux 上基于Nginx和Jexus的发布和部署,本篇文章主要是如何在Docker容器中运行ASP.NET Core应用程序. ...

  6. ASP.NET Core + Docker +Jenkins 实现持续集成

    1.新建一个ASP.NET Core MVC应用程序: 2.将其上传到git: 3.建立Jenkins任务 (1)选择"新建任务",输入任务名称,选择"自由风格项目&qu ...

  7. Asp.Net Core&Docker部署到树莓派3B中

    花了一点时间将吃灰数月的树莓派装上了Docker,并在容器中部署了一个Asp.Net Core应用程序,通过花生壳映射树莓派中的程序,可以使用外网访问树莓派,玩起来很有意思(外网访问地址:http:/ ...

  8. 使用ML.NET + ASP.NET Core + Docker + Azure Container Instances部署.NET机器学习模型

    本文将使用ML.NET创建机器学习分类模型,通过ASP.NET Core Web API公开它,将其打包到Docker容器中,并通过Azure Container Instances将其部署到云中. ...

  9. 详解ASP.NET Core Docker部署

    前言 在前面文章中,介绍了 ASP.NET Core在 macOS,Linux 上基于Nginx和Jexus的发布和部署,本篇文章主要是如何在Docker容器中运行ASP.NET Core应用程序. ...

随机推荐

  1. jira 优先级过滤

    jira 优先级过滤 priority project = DAP AND issuetype = 故障 AND priority = high AND resolution = Unresolved ...

  2. React 16.x Roadmap

    React 16.x Roadmap https://reactjs.org/blog/2018/11/27/react-16-roadmap.html https://reactjs.org/blo ...

  3. React Native Apps

    React Native Apps https://github.com/ReactNativeNews/React-Native-Apps github app https://github.com ...

  4. nodejs stream 创建读写流

    const fs = require("fs"); const { Writable, Readable, Duplex, Transform } = require(" ...

  5. CSS 阴影效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. DeFi里的灰度?每月获得高收益?BGV代币初探

    2020年已经接近了尾声,但是DeFi市场的热闹场面并没有停止,或者说,一直在延续.资本市场不断将大批的资金投入到DeFi市场中,以求在这波热潮中赚得一波又一波红利. 美国时间12月21日,Bacca ...

  7. python中yaml模块的使用

    1.yaml库的导入 经过尝试,发现在python2 和python3语言环境下,安装yaml库的命令行语句不一样. python2: pip install yaml python3:pip ins ...

  8. Python数据结构与算法_回文数(03)

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121输出: true 示例 2: 输入: -121输出: false解释: 从左向右读, ...

  9. MySQL命名、设计及使用规范

    本文转载自MySQL命名.设计及使用规范 导语 最近在看MySQL相关的内容,整理如下规范,作为一名刚刚学习MySQL的菜鸟,整理的内容非常的基础,中间可能涉及到有错误的地方,欢迎批评指正,看到有错误 ...

  10. [Python学习笔记]调试

    编码占了编程工作量的90%,调试占了另外90%,这是一个流传着的笑话.调试在编程中占有很大的分量,即使专业的程序员也一直在制造缺陷. 抛出异常 抛出异常相当于是说:"停止运行这个函数中的代码 ...