Сократите контекст сборки
Docker получает контекст, из которого инструкции COPY берут файлы. Исключите из него локальные окружения, Git, временные файлы и секреты. Не надейтесь на удаление секрета последующей инструкцией: он мог сохраниться в предыдущем слое.
# .dockerignore — пример для проекта Python
.git
.venv
__pycache__
*.pyc
.env
.env.*
outputСекреты сборки передавайте через предназначенный для них механизм BuildKit, а не через ARG или ENV.
Зависимости отдельно от исходников
Если сначала скопировать весь проект, любое изменение исходника может инвалидировать слой установки зависимостей. Сначала копируйте файл зависимостей, затем устанавливайте их и только потом добавляйте код. Фиксируйте версии в принятом для проекта lock-файле.
Разделяйте стадии сборки и выполнения, когда компилятор и заголовочные файлы нужны только для создания артефакта. В итоговый образ переносите результат, а не весь набор инструментов.
Явные версии и простой запуск
- Выбирайте поддерживаемый базовый образ и регулярно обновляйте его.
- Для строгой воспроизводимости фиксируйте digest и предусмотрите процесс его обновления.
- Запускайте приложение с минимально необходимыми правами.
- Проверьте обработку сигнала завершения и корректное закрытие соединений.
- Оставьте в образе только то, что необходимо во время работы.
Минимальный образ не автоматически лучший: учитывайте совместимость библиотек и способ диагностики в вашем окружении.
Проверка готового артефакта
Запустите контейнер именно из собранного образа, выполните smoke test и проверьте завершение процесса. Сканируйте зависимости, но рассматривайте результат вместе с реальным способом использования компонентов.
В журнале выпуска должны быть коммит и digest образа. Так можно установить, что именно работало в момент инцидента.
Документация и источники
Примеры иллюстративные. Имена сервисов и баз условные; команды и параметры нужно адаптировать к своему окружению.