Как написать хороший Dockerfile?
- Что такое multi-stage build?
- Как уменьшить размер Docker-образа и ускорить сборку?
Multi-stage: собирать в образе с компиляторами, а в финальный копировать только артефакт — образ в разы меньше. Порядок инструкций под кэш: сначала то, что меняется редко (зависимости), потом код. Маленький базовый образ (slim, distroless, alpine — с оговорками), не root, фиксированные версии, .dockerignore, exec-форма CMD для корректных сигналов.
- COPY package*.json и npm ci до COPY . — зависимости кэшируются
- Секреты не передавать через ARG/ENV — они остаются в слоях; использовать BuildKit secrets
- Один процесс на контейнер
А ещё alpine на musl иногда даёт сюрпризы с бинарными зависимостями Python и glibc-софтом
Подробно
Размер и безопасность. Компилятор, менеджеры пакетов и исходники в рабочем образе не нужны — это мегабайты и лишние уязвимости. Distroless образы содержат только рантайм.
Кэш слоёв. Каждая инструкция — слой. Если слой изменился, все следующие пересобираются. Поэтому зависимости устанавливают отдельно от кода: изменение строчки кода не скачивает заново все библиотеки.
Прочее:
- фиксировать версию базового образа (тег или digest), не
latest; - объединять
apt-get update && apt-get install … && rm -rf /var/lib/apt/lists/*в одну инструкцию; .dockerignore— не тащить.git,node_modules, секреты в контекст сборки;- HEALTHCHECK или пробы оркестратора;
- сканирование образов на уязвимости (Trivy) в CI.
Пример
# сборка
FROM eclipse-temurin:21-jdk AS build
WORKDIR /src
COPY gradle gradle
COPY gradlew build.gradle settings.gradle ./
RUN ./gradlew dependencies --no-daemon # слой зависимостей кэшируется
COPY src src
RUN ./gradlew bootJar --no-daemon
# запуск
FROM eclipse-temurin:21-jre
RUN useradd --system app
USER app
COPY --from=build /src/build/libs/app.jar /app/app.jar
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "-jar", "/app/app.jar"]Что хотят услышать
- Multi-stage и маленький базовый образ.
- Порядок инструкций и кэш.
- Безопасность: не root, секреты, версии.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Копировать весь код до установки зависимостей, брать базовый образ с тегом latest и оставлять компиляторы в финальном образе на случай отладки
- ✓Multi-stage сборка, порядок инструкций под кэш, маленький базовый образ, не root, фиксированные версии, exec-форма CMD
- ✗Тег latest для базового образа — лучший выбор
- ✗Компиляторы стоит оставлять в финальном образе
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.