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 回答
我不知道所提到的指导,但如果你查看官方dotnet/dotnet-docker-samples并检查Dockerfile,你会看到multi-stage build正在使用:
所以是的,其中一个步骤是复制所有程序文件,但是docker图像仅在最后阶段构建 .
首先我要说我不建议尝试使用"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”作为基础 .
如果您希望以"scratch"为基础,则需要确保存在所有.NET Core的本机依赖项 . 见https://github.com/dotnet/core/blob/master/Documentation/prereqs.md . 这包括
libcurl3
,libssl
,libuuid
等内容 .自包含部署意味着
dotnet publish
的输出将包含运行应用程序所需的几乎所有文件 . 此输出将非常大,因为它包含构成.NET Core和所有Microsoft.AspNetCore . * . dll文件的所有System . * . dll文件的副本 . 要准备自包含的应用程序,您需要:执行
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应用程序所需的文件大小方面,您的程序文件通常是较小的部分 .