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

时间:2018-03-09 20:02:30

标签: docker asp.net-core docker-compose

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

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

这意味着图像非常大,难以分发。

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

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

我试过了,收到以下错误: “错误:for myapp无法启动服务myapp:OCI运行时创建失败:container_linux.go:296:启动容器进程导致”exec:\“dotnet \”:$ PATH中找不到可执行文件“:unknown”

撰写文件:

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 :(得分: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图像只在最后阶段构建。

答案 1 :(得分: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"作为你的基地。

  1. 准备自己的基础Docker镜像
  2. 如果您希望将其基于" scratch",则需要确保存在所有.NET Core的本机依赖项。见https://github.com/dotnet/core/blob/master/Documentation/prereqs.md。其中包括libcurl3libssllibuuid等内容。

    1. 准备一个自包含的部署。
    2. 自包含部署意味着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/

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

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

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