Docker: Лучшие практики и распространённые ошибки. Часть 5
Docker значительно упрощает упаковку, распространение и развёртывание приложений. Но при неправильном подходе вы можете столкнуться с неэффективными образами, уязвимостями и трудностями при сопровождении. В этом гайде разберём:
- как оптимизировать Dockerfile
- на что обращать внимание с точки зрения безопасности
- как уменьшить размер образов
Оптимизация Dockerfile
1. Используйте официальный базовый образ (если возможно)
Проверенные образы вроде python:3.11-slim
, node:20-alpine
и ubuntu:22.04
регулярно обновляются и минимизируют уязвимости.
2. Минимизируйте количество слоёв
Каждая инструкция RUN
, COPY
, ADD
создаёт новый слой. Объединяйте команды в один RUN
:
1RUN apt-get update && \
2 apt-get install -y curl git && \
3 apt-get clean && rm -rf /var/lib/apt/lists/*
3. Удаляйте временные файлы и кэш
Избавляйтесь от кэша, логов и временных зависимостей в том же слое, где вы их создаёте.
4. Используйте .dockerignore
Файл .dockerignore
работает аналогично .gitignore
и помогает не копировать в образ ненужные файлы (node_modules, .git, .env и т.п.):
.git
node_modules
.env
*.log
5. Указывайте конкретные версии зависимостей
Это повышает воспроизводимость сборки:
RUN pip install flask==2.2.5
6. Используйте multi-stage build
Отделяйте сборку от финального образа. Это особенно актуально для приложений на Go, Node.js, Java.
1# Этап сборки
2FROM node:20 as builder
3WORKDIR /app
4COPY . .
5RUN npm install && npm run build
6
7# Финальный образ
8FROM nginx:alpine
9COPY --from=builder /app/dist /usr/share/nginx/html
Безопасность
1. Никогда не храните секреты в Dockerfile или в образе
Не прописывайте пароли, ключи API или токены в Dockerfile. Используйте переменные окружения (-e
) или внешние секрет-хранилища (Vault, AWS Secrets Manager).
2. Работайте от непривилегированного пользователя
По умолчанию Docker запускает процессы от root-пользователя. Это может быть опасно. Лучше создать отдельного пользователя:
1RUN addgroup app && adduser -S -G app appuser
2USER appuser
3. Следите за уязвимостями базовых образов
Используйте инструменты:
4. Обновляйте зависимости
Не забывайте регулярно обновлять образы и пакеты. Старые версии библиотек часто содержат известные уязвимости.
5. Отключайте ненужные службы и порты
Чем меньше открыто — тем безопаснее. Удалите лишние пакеты и отключите всё, что не используется.
Управление размером образов
1. Используйте Alpine-образы
alpine
— минималистичная Linux-сборка весом ~5 МБ. Подходит для большинства приложений:
1FROM python:3.11-alpine
❗ Не все пакеты корректно работают в Alpine — проверяйте совместимость (особенно с gLibc).
2. Удаляйте всё ненужное
Удаляйте временные каталоги, кэш менеджеров пакетов (APT, npm, pip), сборочные зависимости.
3. Используйте multi-stage build
(повторение важно!)
На этапе сборки можно использовать тяжёлые зависимости и инструменты, а в финальный образ попадёт только готовое приложение.
4. Минимизируйте установку системных пакетов
Устанавливайте только то, что нужно. Не используйте apt install -y <много всего>
, если можно обойтись меньшим набором.
5. Анализируйте образы
Инструменты:
docker image inspect
docker history
Dive
(https://github.com/wagoodman/dive)
Заключение
Docker — мощный инструмент, но требует внимания к деталям. Следуйте лучшим практикам:
- Пишите чистый и воспроизводимый
Dockerfile
- Не храните секреты в образе
- Минимизируйте размер образов
- Используйте современные инструменты анализа и обновлений