首页 文章

Docker和asp.net核心通过使用“scratch”图像来最小化分发?

提问于
浏览
0

Microsoft通过Docker容器运行asp.net核心项目的指导,主张将我们的程序文件复制到Dockerfile中的microsoft / aspnetcore映像 .

我们使用图像保存和图像加载命令将我们的代码更改分发到测试服务器 .

这意味着图像非常大并且难以分发 .

是否可以使用“临时”图像,将我们的文件复制到它,然后通过docker-compose引入microsoft / aspnetcore图像,然后使用“scratch”图像构建我们的程序文件图像?

通过这种方式,我们自己的代码图像很小,可以通过图像保存和图像加载命令轻松分发 .

我已经尝试了它并且收到以下错误:“错误:对于myapp无法启动服务myapp:OCI运行时创建失败:container_linux.go:296:启动容器进程导致”exec:\“dotnet \”:找不到可执行文件在$ PATH“:未知”

撰写文件:

version: '2'

services:

  postgresserver:
     image: postgres:alpine
     restart: always
     ports:
       - 5432:5432
     environment:
         POSTGRES_PASSWORD: XXXX
     volumes:
       - /var/lib/myapp/db:/var/lib/postgresql/data
     networks:
       - myapp-network

  aspnetcoreruntime:
     image: microsoft/aspnetcore
     working_dir: /app    

  myapp:
     image: mycorp/myapp:v8.0.0-alpha.2
     restart: always
     ports:
       - 7575:7575
     volumes:
       - /var/lib:/var/lib
     environment:
        myapp_USE_URLS: http://*:7575
        myapp_DB_CONNECTION: User ID=postgres;Password=letmein;Host=postgresserver;Port=5432;Database=myapp;Pooling=true;  
        myapp_FOLDER_USER_FILES: /var/lib/myapp/files/user    
        myapp_FOLDER_BACKUP_FILES: /var/lib/myapp/files/backup
     build:
       context: ./myappdocker
       dockerfile: Dockerfile
     links:
       - postgresserver
     depends_on:
       - "postgresserver"
       - "aspnetcoreruntime"
     networks:
       - myapp-network

networks:
  myapp-network:
     driver: bridge

2 回答

  • 0

    我不知道所提到的指导,但如果你查看官方dotnet/dotnet-docker-samples并检查Dockerfile,你会看到multi-stage build正在使用:

    FROM microsoft/aspnetcore-build:2.0 AS build-env
    WORKDIR /app
    
    # copy csproj and restore as distinct layers
    COPY *.csproj ./
    RUN dotnet restore
    
    # copy everything else and build
    COPY . ./
    RUN dotnet publish -c Release -o out
    
    # build runtime image
    FROM microsoft/aspnetcore:2.0
    WORKDIR /app
    COPY --from=build-env /app/out .
    

    所以是的,其中一个步骤是复制所有程序文件,但是docker图像仅在最后阶段构建 .

  • 0

    首先我要说我不建议尝试使用"scratch" . 图像现在可能只有几百MB,但这是有充分理由的:图像包含所有.NET Core先决条件,默认情况下启用一些网络设置以简化部署,并包含ASP.NET Core运行时( 1)使用名为 crossgen 的工具对Linux进行了预优化,(2)定期使用安全补丁进行维护 .

    如果尺寸是您主要关心的问题,请查看https://github.com/aspnet/Universe/issues/833 . 在ASP.NET Core 2.1中,应该有一个基于Alpine Linux的映像,它将比当前的基础小:Debian Linux .


    也就是说,您需要使用“scratch”作为基础 .

    • 准备好自己的基础Docker镜像

    如果您希望以"scratch"为基础,则需要确保存在所有.NET Core的本机依赖项 . 见https://github.com/dotnet/core/blob/master/Documentation/prereqs.md . 这包括 libcurl3libssllibuuid 等内容 .

    • 准备自包含部署 .

    自包含部署意味着 dotnet publish 的输出将包含运行应用程序所需的几乎所有文件 . 此输出将非常大,因为它包含构成.NET Core和所有Microsoft.AspNetCore . * . dll文件的所有System . * . dll文件的副本 . 要准备自包含的应用程序,您需要:

    • 在.csproj文件中设置RuntimeIdentifier
    <PropertyGroup>
      <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    </PropertyGroup>
    
    • 执行 dotnet publish --self-contained --output ./publish/ --configuration Release

    • ./publish/ 复制到Docker镜像中

    • 使用自包含部署时,它将为您生成Linux可执行文件以启动您的应用程序 . 执行 ./publish/my-app 而不是 dotnet ./publish/my-app.dll .

    您还可以使用 dotnet publish --runtime linux-x64 将前两个步骤压缩为一个操作 . 有关详细信息,请参阅https://docs.microsoft.com/en-us/dotnet/core/deploying/

    • 设置ASP.NET Core以公开 0.0.0.0 . 默认情况下,ASP.NET Core仅绑定到localhost . 在Docker中,这意味着您必须将其更改为绑定到 IPAny 才能从Docker容器外部访问Web服务器 . 您可以通过多种方式执行此操作,但最简单的方法是设置环境变量 ENV ASPNETCORE_URLS http://*:80

    • (可选)最后,考虑使用名为"crossgen"的工具预优化应用程序 . 对于大型应用程序,它可以将应用程序时间的启动时间缩短15-30秒 . crossgen 预先JIT你的* .dll程序集 . 有关详细信息,请参阅https://github.com/dotnet/coreclr/blob/v2.0.5/Documentation/building/crossgen.md .


    还有一件事需要考虑 . 通过在"scratch"上构建自己的映像,如果在运行.NET Core的服务器上有多个应用程序,则会减少潜在的磁盘空间节省 . 如果你有两个或三个全部使用 microsoft/aspnetcore 作为基础的应用程序,Docker只保留一份 microsoft/aspnetcore . 如果您基于这两个或三个应用程序,最终将使用更多磁盘空间,因为每个映像中的大部分内容都将是重复内容:ASP.NET Core运行时 . 在运行.NET Core应用程序所需的文件大小方面,您的程序文件通常是较小的部分 .

相关问题