Зачем нужны многоступенчатые Docker-файлы?
Давайте соберем
Этап 2: Runtime
Теперь мы переключаем передачу.
На этапе выполнения используется более компактный образ: mcr.microsoft.com/dotnet/aspnet:8.0.
Это просто среда выполнения ASP.NET – ни SDK, ни дополнительного багажа.
В качестве рабочего каталога я выбрал /app, потому что именно там мы будем жить.
Безопасность имеет большое значение, поэтому я добавляю пользователя, не являющегося root, под именем appuser.
Работать от имени root в контейнере – все равно что оставлять входную дверь незапертой, не самая лучшая идея.
Затем я забираю опубликованные файлы со стадии сборки с помощью COPY –from=build /app ./. Быстрый chown передает права на appuser, а USER appuser гарантирует, что мы не работаем от имени root.
Я открываю порт 8080 (вы можете изменить его, если ваше приложение использует что-то другое), и ENTRYPOINT запускает приложение с dotnet YourAppName.dll.
Не забудьте вставить сюда имя вашей реальной DLL!
Запуск
Чтобы увидеть все в действии, откройте терминал в папке с проектом и запустите его:
docker build -t mycoolapp .docker run -p 8080:8080 mycoolapp
Нажмите http://localhost:8080 в браузере, и бум – ваше приложение готово к работе.
Итак, в чем же заключается выгода?
Во-первых, конечный образ получается крошечным по сравнению с одноэтапной сборкой.
Вы не таскаете с собой SDK или инструменты сборки – только среда выполнения и ваше приложение.
Кроме того, это более безопасно при использовании не root-пользователя.
А благодаря кэшированию Docker изменение кода не означает пересоздание всего с нуля.
Меньшие образы означают более быстрое развертывание, а постоянство Docker позволяет мне не бороться с проблемами «работает на моей машине».
Настройки и советы
Это надежная отправная точка, но вы можете подстроить ее под свои нужды.
Нужна проверка хэлс чек ?
Добавьте:
VOLUME /app/data
Заключение
Многоступенчатые Docker-файлы стали моей палочкой-выручалочкой для приложений .NET Core.
Они требуют некоторой настройки, но как только вы освоите их, все пойдет как по маслу.
Вы получаете более компактный контейнер, готовый к работе от сборки до выполнения.
Попробуйте его в своем следующем проекте – наверняка вы удивитесь, как раньше обходились без него.
см. также:
![]()
