![zeit.sh的api](https://i-blog.csdnimg.cn/blog_migrate/5de31c62970d9eccae5b52d76ea9e753.png)
zeit.sh的api
Back in March of 2017 I blogged about Zeit and their cool deployment system "now." Zeit will take any folder and deploy it to the web easily. Better yet if you have a Dockerfile in that folder as Zeit will just use that for the deployment.
早在2017年3月,我就在Zeit和其出色的部署系统“ now ”上发表了博客。 Zeit将使用任何文件夹并将其轻松部署到Web。 更好的是,如果该文件夹中有一个Dockerfile,因为Zeit只会将其用于部署。
![image image](https://i-blog.csdnimg.cn/blog_migrate/246cab4a7af8560f1aeb98f379c74c0b.png)
Zeit's free Open Source account has a limit of 100 megs for the resulting image, and with the right Dockerfile started ASP.NET Core apps are less than 77 megs. You just need to be smart about a few things. Additionally, it's running in a somewhat constrained environment so ASP.NET's assumptions around FileWatchers can occasionally cause you to see errors like
Zeit的免费开放源帐户对生成的图像限制为100兆字节,并且使用正确的Dockerfile启动时,ASP.NET Core应用程序小于77兆字节。 您只需要对一些事情保持精明。 此外,它在某种程度上受限制的环境中运行,因此ASP.NET关于FileWatchers的假设有时会导致您看到诸如以下的错误
at System.IO.FileSystemWatcher.StartRaisingEvents()
Unhandled Exception: System.IO.IOException:
The configured user limit (8192) on the number of inotify instances has been reached.
at System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed(
While this environment variable is set by default for the "FROM microsoft/dotnet:2.1-sdk" Dockerfile, it's not set at runtime. That's dependent on your environment.
虽然默认为“ FROM microsoft / dotnet:2.1-sdk” Dockerfile设置了此环境变量,但未在运行时设置。 这取决于您的环境。
Here's my Dockerfile for a simple project called SuperZeit. Note that the project is structured with a SLN file, which I recommend.
这是我的一个名为SuperZeit的简单项目的Dockerfile。 请注意,我建议使用SLN文件来构造项目。
Let me call our a few things.
让我称呼我们几件事。
First, we're doing a Multi-stage build here.
首先,我们在这里进行多阶段构建。
- The SDK is large. You don't want to deploy the compiler to your runtime image! SDK很大。 您不想将编译器部署到运行时映像!
Second, the first copy commands just copy the sln and the csproj.
其次,第一个复制命令仅复制sln和csproj。
- You don't need the source code to do a dotnet restore! (Did you know that?) 您不需要源代码即可进行dotnet还原! (你知道吗?)
- Not deploying source means that your docker builds will be MUCH faster as Docker will cache the steps and only regenerate things that change. Docker will only run dotnet restore again if the solution or project files change. Not the source. 不部署源代码意味着您的Docker构建将更快,因为Docker将缓存步骤并仅重新生成更改的事物。 如果解决方案或项目文件发生更改,则Docker将仅再次运行dotnet restore。 不是来源。
Third, we are using the aspnetcore-runtime image here. Not the dotnetcore one.
第三,我们在这里使用aspnetcore-runtime映像。 不是dotnetcore之一。
- That means this image includes the binaries for .NET Core and ASP.NET Core. We don't need or want to include them again. 这意味着该映像包括.NET Core和ASP.NET Core的二进制文件。 我们不需要或不想再次包含它们。
If you were doing a publish with a the -r switch, you'd be doing a self-contained build/publish. You'd end up copying TWO .NET Core runtimes into a container! That'll cost you another 50-60 megs and it's just wasteful.
如果使用-r开关进行发布,则将进行独立的build / publish 。 您最终将两个.NET Core运行时复制到容器中! 这将使您再花费50至60兆,这只是浪费。
If you want to learn more, go explore the very good examples on the .NET Docker Repro on GitHub https://github.com/dotnet/dotnet-docker/tree/master/samples
如果您想了解更多信息,请在GitHub https://github.com/dotnet/dotnet-docker/tree/master/samples上的.NET Docker Repro上浏览非常好的示例。
Optimizing Container Size
优化容器尺寸
.NET Core Alpine Docker Sample - This sample builds, tests, and runs an application using Alpine.
.NET Core Alpine Docker示例-该示例使用Alpine构建,测试和运行应用程序。
.NET Core self-contained Sample - This sample builds and runs an application as a self-contained application.
.NET Core自包含示例-此示例构建并运行应用程序为自包含应用程序。
Optimizing Container Size
优化容器尺寸
- Finally, since some container systems like Zeit have modest settings for inotify instances (to avoid abuse, plus most folks don't use them as often as .NET Core does) you'll want to set ENV DOTNET_USE_POLLING_FILE_WATCHER=true which I do in the runtime image.最后,由于某些容器系统(如Zeit)对inotify实例进行了适度的设置(为避免滥用,而且大多数人不像.NET Core那样频繁使用它们),因此您需要设置ENV DOTNET_USE_POLLING_FILE_WATCHER = true,这是我在运行时映像。
So starting from this Dockerfile:
所以从这个Dockerfile开始:
FROM microsoft/dotnet:2.1-sdk-alpine AS build
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.sln .
COPY superzeit/*.csproj ./superzeit/
RUN dotnet restore
# copy everything else and build app
COPY . .
WORKDIR /app/superzeit
RUN dotnet build
FROM build AS publish
WORKDIR /app/superzeit
RUN dotnet publish -c Release -o out
FROM microsoft/dotnet:2.1-aspnetcore-runtime-alpine AS runtime
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
WORKDIR /app
COPY --from=publish /app/superzeit/out ./
ENTRYPOINT ["dotnet", "superzeit.dll"]
Remember the layers of the Docker images, as if they were a call stack:
记住Docker映像的各层,就好像它们是调用堆栈一样:
- Your app's files 您应用的文件
- ASP.NET Core Runtime ASP.NET Core运行时
- .NET Core Runtime .NET Core运行时
- .NET Core native dependencies (OS specific) .NET Core本机依赖项(特定于OS)
- OS image (Alpine, Ubuntu, etc) 操作系统映像(Alpine,Ubuntu等)
For my little app I end up with a 76.8 meg image. If want I can add the experimental .NET IL Trimmer. It won't make a difference with this app as it's already pretty simple but it could with a larger one.
对于我的小应用程序,我最终得到了76.8兆的图像。 如果需要,我可以添加实验性.NET IL Trimmer 。 这款应用程序已经非常简单,但不会造成任何变化,但更大的应用程序可能会有所作为。
BUT! What if we changed the layering to this?
但! 如果我们将分层更改为该怎么办?
- Your app's files along with a self-contained copy of ASP.NET Core and .NET Core 应用程序的文件以及ASP.NET Core和.NET Core的独立副本
- .NET Core native dependencies (OS specific) .NET Core本机依赖项(特定于OS)
- OS image (Alpine, Ubuntu, etc) 操作系统映像(Alpine,Ubuntu等)
Then we could do a self-Contained deployment and then trim the result! Richard Lander has a great dockerfile example.
然后,我们可以进行独立的部署,然后修剪结果! Richard Lander有一个很好的dockerfile示例。
See how he's doing the package addition with the dotnet CLI with "dotnet add package" and subsequent trim within the Dockerfile (as opposed to you adding it to your local development copy's csproj).
看看他是怎么做的与“DOTNET添加包”和后续的修整的Dockerfile内DOTNET CLI包除了(而不是你将它添加到你的本地开发副本的的csproj)。
FROM microsoft/dotnet:2.1-sdk-alpine AS build
WORKDIR /app
# copy csproj and restore as distinct layers
COPY *.sln .
COPY nuget.config .
COPY superzeit/*.csproj ./superzeit/
RUN dotnet restore
# copy everything else and build app
COPY . .
WORKDIR /app/superzeit
RUN dotnet build
FROM build AS publish
WORKDIR /app/superzeit
# add IL Linker package
RUN dotnet add package ILLink.Tasks -v 0.1.5-preview-1841731 -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
RUN dotnet publish -c Release -o out -r linux-musl-x64 /p:ShowLinkerSizeComparison=true
FROM microsoft/dotnet:2.1-runtime-deps-alpine AS runtime
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
WORKDIR /app
COPY --from=publish /app/superzeit/out ./
ENTRYPOINT ["dotnet", "superzeit.dll"]
Now at this point, I'd want to see how small the IL Linker made my ultimate project. The goal is to be less than 75 megs. However, I think I've hit this bug so I will have to head to bed and check on it in the morning.
现在,我想看看IL Linker做我最终项目的大小。 目标是小于75兆。 但是,我想我已经遇到了这个错误,因此我必须早上起床检查一下。
The project is at https://github.com/shanselman/superzeit and you can just clone and "docker build" and see the bug.
该项目位于https://github.com/shanselman/superzeit ,您可以克隆并“ docker build”并查看错误。
However, if you check the comments in the Docker file and just use the a "FROM microsoft/dotnet:2.1-aspnetcore-runtime-alpine AS runtime" it works fine. I just think I can get it even smaller than 75 megs.
但是,如果您检查Docker文件中的注释,并仅使用“ FROM microsoft / dotnet:2.1-aspnetcore-runtime-alpine AS运行时”,则效果很好。 我只是认为我可以得到小于75兆的电压。
Talk so you soon, Dear Reader! (I'll update this post when I find out about that bug...or perhaps my bug!)
这么说吧,亲爱的读者,您好! (当我发现该错误...或者可能是我的错误时,我将更新此帖子。)
UPDATE1 : The linker works with this Workaround. I need to set the property CrossGenDuringPublish
to false
in the project file.
UPDATE1:链接器与此替代方法一起使用。 我需要在项目文件中将属性CrossGenDuringPublish
设置为false
。
A standard ASP.NET Core "hello world" image ends up at around 75 megs on Zeit.
标准的ASP.NET Core“ hello world”映像最终在Zeit上约为75兆。
A self-contained deployment with the runtime-deps images is about 52 megs.
具有runtime-deps映像的独立部署约为52兆。
If you add trimming to that self-contained Alpine image the result is just 35 megs!
如果将修剪添加到该独立的Alpine图像,则结果仅为35兆!
![35 meg ASP.NET Core image 35 meg ASP.NET Core image](https://i-blog.csdnimg.cn/blog_migrate/d15907b3f6a099be4e04d17c16734034.png)
I'm making some headway but still hitting an inotify issue with FileSystemWatchers. More soon!
我正在取得一些进展,但仍然遇到FileSystemWatchers的问题。 很快!
UPDATE2: After some bugs found and some hard work by our friends at Zeit it looks like the inotify issue in the sentence above has been fixed. Looks like it was a misconfiguration - which is great! I was worried there was a larger architectural issue but there isn't.
UPDATE2:在Zeit上我们的朋友发现了一些错误并做出了一些努力之后,上面句子中的inotify问题似乎已得到解决。 看来这是配置错误-太好了! 我担心存在更大的体系结构问题,但没有。
zeit.sh的api