Docker 图片中是否应该包含静态文件?
Should static files be included in a Docker Image?
我有一个 .NET 微服务 运行 作为 docker 容器,负责向客户发送电子邮件。这些电子邮件包含额外的横幅,它是一个 png 文件。
该文件是否应该在构建过程中包含在我的 Docker 图像中?这是一个好习惯吗?
将文件上传到已构建的容器或链接存储在不同位置的文件是更好的方法吗?
Docker文件
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY src/Email.Service/Email.Service.csproj .
COPY nuget.config .
RUN dotnet restore Email.Service.csproj --configfile nuget.config
COPY src/Email.Service .
RUN dotnet build Email.Service.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish Email.Service.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
COPY src/Email.Service/Assets Assets
ENTRYPOINT [ "dotnet" ]
CMD [ "Email.Service.dll" ]
banner.png 位于项目的 Assets 目录中。
微服务的主要目标通常是独立性。微服务应该相互独立。
如果将图像存储在另一个容器中,则会引入耦合。您只能在其他容器可用时发送邮件。
所以一般来说,在微服务架构中,最好的方法是将图像包含在您的邮件图像中。
与您的用例没有直接关系,但与问题的标题有关:
假设有一个带有网络服务器 (httpd) 的图像。 htdocs 中的静态文件应该是容器镜像的一部分还是应该通过文件系统挂载?
我对此类问题的回答在一定程度上取决于网络服务器 installation/patching 的职责和生命周期以及构成内容的文档。如果您想将内容的责任移交给其他团队,您可能希望使用卷安装并授予其他团队修改该卷的权限。
这与汉斯给出的答案并不矛盾。对于一个可能比你停留时间更长的 png 运行 一个容器,我认为将其烘焙到图像中没有问题。
Should that file be included in my Docker Image during build process?
是的。这使图像成为 self-contained,您可以 运行 它,而不需要源代码树或任何外部工件。
(...还可以看到“文件存储在不同的地方”选项。)
Is it a better approach to upload the file to an already built container
不,这不是最佳做法。删除和重新创建容器是非常常规的事情(在 Kubernetes 等环境中,有时它会发生在您的控制之外)并且需要额外的手动设置步骤才能使容器正常运行,因为您忘记了这些步骤,因此可能会出现故障。
or linked the file stored in different place?
对于 production-oriented 部署,这实际上是一个很好的策略。考虑使用 Webpack 或类似工具构建并编译为静态文件的 Javascript 应用程序。 “正常的 Docker 方式”是使用 multi-stage 构建,首先构建应用程序,然后 COPY
将这些文件构建成最小的 Nginx 映像。 Webpack 具有一些允许提供旧版本应用程序的功能,因此即使最终用户没有使用 link 重新加载他们的页面到较新的资产,以前的构建仍然有效;这种“正常的 Docker 方式”实际上并不适用。
所以实际上有一个非常有效的路径来获取像这样的静态资产并将它们上传到普通的 HTTP file-serving 服务。 (我已经习惯了 Amazon 的产品,我会为此使用 AWS S3,但我相信其他 public 云也有类似的产品,实际上任何可以上传文件和 HTTP GET 的地方都可以。)你会为此使用完全正常的 not-necessarily-Docker 前端构建管道。在您的应用程序代码中,您可以自己代理 file-serving 服务或直接向其发送 URL。
正如我所说,这有点多 production-oriented,您正在考虑“昨天构建的脚本 URL 今天是否仍然有效”之类的问题;在开发环境中更难使用。如果您已经有一个 Web 应用程序发布管道并且正在尝试使后端适应 Docker,这可能是一个很好的方法。它是否“更好”取决于 URL 稳定性对您有多重要,涉及多少内容,更改的频率以及开发人员设置有多重要 self-contained.
我有一个 .NET 微服务 运行 作为 docker 容器,负责向客户发送电子邮件。这些电子邮件包含额外的横幅,它是一个 png 文件。
该文件是否应该在构建过程中包含在我的 Docker 图像中?这是一个好习惯吗?
将文件上传到已构建的容器或链接存储在不同位置的文件是更好的方法吗?
Docker文件
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY src/Email.Service/Email.Service.csproj .
COPY nuget.config .
RUN dotnet restore Email.Service.csproj --configfile nuget.config
COPY src/Email.Service .
RUN dotnet build Email.Service.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish Email.Service.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
COPY src/Email.Service/Assets Assets
ENTRYPOINT [ "dotnet" ]
CMD [ "Email.Service.dll" ]
banner.png 位于项目的 Assets 目录中。
微服务的主要目标通常是独立性。微服务应该相互独立。
如果将图像存储在另一个容器中,则会引入耦合。您只能在其他容器可用时发送邮件。
所以一般来说,在微服务架构中,最好的方法是将图像包含在您的邮件图像中。
与您的用例没有直接关系,但与问题的标题有关:
假设有一个带有网络服务器 (httpd) 的图像。 htdocs 中的静态文件应该是容器镜像的一部分还是应该通过文件系统挂载?
我对此类问题的回答在一定程度上取决于网络服务器 installation/patching 的职责和生命周期以及构成内容的文档。如果您想将内容的责任移交给其他团队,您可能希望使用卷安装并授予其他团队修改该卷的权限。
这与汉斯给出的答案并不矛盾。对于一个可能比你停留时间更长的 png 运行 一个容器,我认为将其烘焙到图像中没有问题。
Should that file be included in my Docker Image during build process?
是的。这使图像成为 self-contained,您可以 运行 它,而不需要源代码树或任何外部工件。
(...还可以看到“文件存储在不同的地方”选项。)
Is it a better approach to upload the file to an already built container
不,这不是最佳做法。删除和重新创建容器是非常常规的事情(在 Kubernetes 等环境中,有时它会发生在您的控制之外)并且需要额外的手动设置步骤才能使容器正常运行,因为您忘记了这些步骤,因此可能会出现故障。
or linked the file stored in different place?
对于 production-oriented 部署,这实际上是一个很好的策略。考虑使用 Webpack 或类似工具构建并编译为静态文件的 Javascript 应用程序。 “正常的 Docker 方式”是使用 multi-stage 构建,首先构建应用程序,然后 COPY
将这些文件构建成最小的 Nginx 映像。 Webpack 具有一些允许提供旧版本应用程序的功能,因此即使最终用户没有使用 link 重新加载他们的页面到较新的资产,以前的构建仍然有效;这种“正常的 Docker 方式”实际上并不适用。
所以实际上有一个非常有效的路径来获取像这样的静态资产并将它们上传到普通的 HTTP file-serving 服务。 (我已经习惯了 Amazon 的产品,我会为此使用 AWS S3,但我相信其他 public 云也有类似的产品,实际上任何可以上传文件和 HTTP GET 的地方都可以。)你会为此使用完全正常的 not-necessarily-Docker 前端构建管道。在您的应用程序代码中,您可以自己代理 file-serving 服务或直接向其发送 URL。
正如我所说,这有点多 production-oriented,您正在考虑“昨天构建的脚本 URL 今天是否仍然有效”之类的问题;在开发环境中更难使用。如果您已经有一个 Web 应用程序发布管道并且正在尝试使后端适应 Docker,这可能是一个很好的方法。它是否“更好”取决于 URL 稳定性对您有多重要,涉及多少内容,更改的频率以及开发人员设置有多重要 self-contained.