У меня есть микросервис .NET, работающий как док-контейнер, который отвечает за отправку электронных писем клиентам. Эти электронные письма содержат дополнительный баннер, который представляет собой файл png.

Должен ли этот файл быть включен в мой образ Docker во время процесса сборки? Это вообще хорошая практика?

Лучше ли загрузить файл в уже созданный контейнер или связать файл, хранящийся в другом месте?

Dockerfile

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 в проекте.

0
Mikolaj 26 Янв 2022 в 16:36

3 ответа

Лучший ответ

Должен ли этот файл быть включен в мой образ Docker во время процесса сборки?

Да. Это делает образ автономным, и вы можете просто запустить его, не нуждаясь в исходном дереве или каких-либо внешних артефактах.

(... но также см. вариант «файл хранится в другом месте».)

Лучше ли загружать файл в уже построенный контейнер?

Нет, это не лучшая практика. Удалять и воссоздавать контейнеры очень рутинно (а в таких средах, как Kubernetes, иногда это происходит вне вашего контроля), и необходимость дополнительных шагов ручной настройки, чтобы сделать контейнер функциональным, рискует сломаться, потому что вы забыли шаг.

или связал файл, хранящийся в другом месте?

Для развертывания, ориентированного на производство, это действительно может быть хорошей стратегией. Рассмотрим приложение Javascript, созданное с помощью Webpack или аналогичного инструмента и скомпилированное в статические файлы. «Обычным способом Docker» было бы использование многоэтапной сборки, которая сначала собирала приложение, а затем COPY эти файлы в минимальный образ Nginx. Webpack имеет некоторые функции, которые позволяют обслуживать старые версии приложения, поэтому предыдущая сборка все еще работает, даже если конечный пользователь не перезагрузил свою страницу со ссылкой на более новые ресурсы; этот «обычный способ Docker» на самом деле не работает с этим.

Таким образом, на самом деле есть очень правильный способ взять статические ресурсы, подобные этому, и загрузить их в обычную службу обслуживания файлов HTTP. (Я привык к предложениям Amazon, и я бы использовал для этого AWS S3, но я считаю, что другие общедоступные облака имеют аналогичные предложения, и действительно все, где вы можете загружать файлы и HTTP GET их, будет работать.) Вы бы использовали совершенно нормальный для этого не обязательно использовать конвейер сборки интерфейса Docker. В коде вашего приложения вы либо сами проксируете файлообменную службу, либо напрямую отправляете ей URL-адрес.

Как я уже сказал, это немного больше ориентировано на производство, когда вы думаете о таких проблемах, как «действителен ли URL-адрес сценария из вчерашней сборки сегодня»; с ним сложнее работать в среде разработки. Если у вас уже есть конвейер публикации веб-приложений и вы пытаетесь адаптировать серверную часть к Docker, это может быть хорошим подходом. Будет ли это «лучше», зависит от того, насколько важна для вас стабильность URL-адреса, сколько контента задействовано, как часто он меняется и насколько важно, чтобы настройка разработчика была более автономной.

1
David Maze 26 Янв 2022 в 17:49

Основной целью микросервисов, как правило, является независимость. Микросервисы должны быть независимы друг от друга.

Если вы храните изображение в другом контейнере, вы вводите связанность. Вы можете отправлять письма только тогда, когда доступен другой контейнер.

В общем, лучший способ в микросервисной архитектуре — включить изображение в изображение для рассылки.

1
Hans Kilian 26 Янв 2022 в 16:43

Не имеет прямого отношения к вашему варианту использования, но связано с заголовком вопроса:

Предположим, у вас есть изображение с веб-сервером (httpd). Должны ли статические файлы в htdocs быть частью образа контейнера или они должны проходить через монтирование файловой системы?

Мой ответ на такой вопрос будет немного зависеть от ответственности и жизненного цикла установки / исправления веб-сервера, а также документов, составляющих контент. Если вы хотите передать ответственность за содержимое какой-либо другой команде, вы, вероятно, захотите использовать монтирование тома и предоставить другой команде доступ для изменения этого тома.

Это не противоречит ответу Ганса. Для одного png, который, вероятно, остается дольше, чем вы запускаете контейнер, я не вижу проблем с его запеканием в изображение.

1
Hiran Chaudhuri 26 Янв 2022 в 17:21