Перейти к содержимому
Главная страница » Как уменьшить размер Docker образа

Как уменьшить размер Docker образа

Уменьшение размера образов Docker имеет решающее значение для оптимизации рабочих процессов разработки, ускорения сборки и минимизации времени развертывания, а также для экономии ценного места для хранения. 

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

Используйте минимальный базовый Docker образ

Выбор минимального базового образа — один из самых эффективных способов уменьшить размер образа Docker. Минимальные базовые образы, такие как alpinescratch, или debian-slim, значительно меньше, чем более крупные базовые образы, такие как ubuntu или debian, поскольку в них есть только самое необходимое.

Пример с Python

Рассмотрим разницу в размере между типичным изображением Python на основе ubuntu— и изображением Python на основе alpine-:

Использование Ubuntu в качестве базового образа:

FROM python:3.11-slim
  • Размер образа: примерно 60 МБ (Python 3.11 с базовым образом Ubuntu)

Использование Alpine в качестве базового изображения:

FROM python:3.11-alpine
  • Размер образа: примерно 23 МБ (Python 3.11 с базовым образом Alpine)

Образ на основе Alpine примерно в 3 раза меньше, чем образ на основе Ubuntu. Такое значительное уменьшение размера связано с тем, что Alpine Linux — это минимальный дистрибутив, специально разработанный для сред Docker. Использование таких минимальных базовых образов не только уменьшает размер образа, но и снижает вероятность атаки, повышая безопасность.

Многоступенчатые сборки

Многоэтапные сборки позволяют отделить среду сборки от среды выполнения, гарантируя, что в конечный образ попадут только необходимые файлы. Такой подход помогает уменьшить размер конечного образа Docker, исключая инструменты сборки и зависимости, которые не нужны во время выполнения.

Пример с Python

Рассмотрим приложение на Python, в котором вы хотите использовать многоэтапные сборки, чтобы уменьшить размер итогового образа:

Многоступенчатая сборка Dockerfile:

# Build stage
FROM python:3.11-slim AS builder
WORKDIR /app

# Install build dependencies
COPY requirements.txt .
RUN pip install --user -r requirements.txt

# Copy application code
COPY . .

# Final stage
FROM python:3.11-slim
WORKDIR /app

# Install only runtime dependencies
COPY --from=builder /root/.local /root/.local
COPY . .

# Set the path to include user-installed packages
ENV PATH=/root/.local/bin:$PATH

CMD ["python", "app.py"]

Сравнение размеров

  • Без многоэтапных сборок: если вы используете одноэтапный Dockerfile, конечный образ будет включать в себя как зависимости сборки, так и код приложения. Например:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
  • Размер образа: примерно 150 МБ (включая зависимости для сборки и выполнения).

При многоэтапной сборке: при использовании приведенного примера многоэтапной сборки итоговое изображение будет значительно меньше:

  • Размер образа: примерно 60 МБ (содержит только зависимости времени выполнения и код приложения).

Удалите ненужные файлы

Очистка ненужных файлов, таких как кэш, временные файлы и зависимости сборки, является важным шагом в уменьшении размера образа Docker. Эта практика гарантирует, что ваш образ содержит только необходимые компоненты для запуска вашего приложения, при этом сводя к минимуму размер и потенциальную уязвимость.

Пример с Python

Вот пример того, как удалить ненужные файлы в Dockerfile для приложения на Python:

Перед очисткой:

FROM python:3.11-slim

WORKDIR /app

# Install build dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy application code
COPY . .

CMD ["python", "app.py"]

С очисткой:

FROM python:3.11-slim

WORKDIR /app

# Install build dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt \
# Clean up temporary files and caches
&& rm -rf /root/.cache/pip

# Copy application code
COPY . .

CMD ["python", "app.py"]

Без очистки: в Dockerfile, где ненужные файлы не удаляются, размер образа может быть больше из-за остатков кэша и временных файлов:

  • Размер образа: примерно 150 МБ (включая кэши сборки и ненужные файлы).

С помощью очистки: использование команд очистки, таких как rm -rf /root/.cache/pip для удаления кэша и временных файлов, может уменьшить размер итогового изображения:

  • Размер изображения: примерно 120 МБ (после очистки кэша и временных файлов).

Использовать .dockerignore Файл

Файл .dockerignore работает так же, как и файл .gitignore , но для сборок Docker. Он определяет, какие файлы и каталоги следует исключить из контекста сборки Docker. Это помогает уменьшить размер контекста сборки, что приводит к более быстрой сборке и уменьшению размера образов Docker.

Преимущества использования .dockerignore

  1. Уменьшение размера контекста сборки: исключая ненужные файлы, вы минимизируете объем данных, отправляемых в демон Docker, что ускоряет процесс сборки.
  2. Меньшие по размеру образы Docker: исключение файлов, которые не нужны в конечном образе, позволяет не включать их, что помогает уменьшить размер образа.
  3. Повышенная эффективность сборки: меньшие контексты сборки означают, что Docker может более эффективно кэшировать слои, что приводит к более быстрой сборке.

Пример .dockerignore Файл

Вот простой пример .dockerignore файл:

.git
node_modules
*.log
.DS_Store

Без .dockerignore:

  • Когда ненужные файлы включаются в контекст сборки Docker, они отправляются в демон Docker и становятся частью образа Docker, даже если они не используются в конечном образе.
  • Например, включение .git каталога или node_modules папки может значительно увеличить размер контекста сборки. .git каталог может содержать несколько сотен мегабайт истории версий, а node_modules может добавить еще несколько сотен мегабайт зависимостей, которые не нужны в рабочем образе.
  • Влияние на размер контекста сборки: исключение файлов и каталогов, которые не нужны в конечном образе, помогает уменьшить размер контекста сборки, который в противном случае может достигать нескольких гигабайт в зависимости от размера и количества исключенных файлов. Приблизительный размер контекста сборки может составлять около 1 ГБ, если он включает в себя большой .gitкаталог, node_modulesи другие файлы, которые не нужны в образе.

С .dockerignore:

  • Используя .dockerignore файл для исключения ненужных файлов, вы ограничиваете контекст сборки только теми файлами, которые необходимы для приложения.
  • Это исключение может привести к значительному уменьшению контекста сборки. Например, исключение .gitnode_modulesи других больших каталогов может уменьшить размер контекста с нескольких гигабайт до нескольких мегабайт.
  • Влияние на размер образа: хотя .dockerignore сам файл напрямую не уменьшает размер конечного образа Docker, он предотвращает добавление ненужных файлов в контекст сборки. Это приводит к более эффективному процессу сборки и помогает создать более компактный конечный образ, гарантируя включение только необходимых файлов. После исключения этих ненужных файлов размер контекста сборки может быть уменьшен до 50 МБ, что может значительно сократить время сборки и сделать конечный образ Docker более эффективным.

Минимизировать слои

В Docker каждая RUNCOPY и ADD инструкция в вашем Dockerfile создает новый слой в результирующем образе. Эти слои могут увеличить общий размер образа Docker и повлиять на производительность сборки. Объединение команд в одну RUN инструкцию помогает сократить количество слоев, что приводит к созданию более эффективного и компактного образа Docker.

Без минимизации слоя:

  • Каждая отдельная инструкция (RUNCOPY и т.д.) Создает новый слой в изображении Docker. Эти слои накапливаются и могут привести к увеличению размера изображения из-за промежуточных файлов, временных данных и дополнительных метаданных.
  • Например, использование отдельныхRUNинструкций может привести к появлению нескольких слоёв, каждый из которых добавляет свои собственные метаданные и служебную информацию, что может увеличить размер итогового изображения.
  • Влияние на размер изображения: если вы используете несколько RUN инструкций, таких как:
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean

Использование нескольких RUN инструкций может привести к увеличению размера изображения примерно до 150 МБ, при этом каждый слой увеличивает нагрузку.

С минимизацией слоя:

  • Объединение команд в одну RUN инструкцию сокращает количество слоёв и помогает объединить изменения в меньшее количество более оптимизированных слоёв.
  • Например, объединение команд в одну RUN инструкция:
RUN apt-get update && apt-get install -y curl && apt-get clean

Объединение команд в одну RUNинструкцию может уменьшить размер изображения примерно до 130 МБ. Такое уменьшение достигается за счет объединения изменений в меньшее количество слоев и минимизации ненужных промежуточных данных.

Использование специальных команд COPY:

Вместо того чтобы копировать целые каталоги в образ Docker, используйте специальные COPY команды для включения только необходимых вам файлов. Такой подход позволяет избежать переноса ненужных файлов и уменьшить размер образа.

Пример:

COPY package.json .
COPY src/ src/
  • Влияние на размер: копируя только определенные файлы и каталоги, вы избегаете включения нежелательных файлов, которые могут увеличить размер образа. Например, исключение файлов разработки или артефактов сборки может уменьшить размер образа на несколько мегабайт в зависимости от размера исключенных данных.

Используйте многоарочные изображения

Создание образов Docker с несколькими архитектурами обеспечивает совместимость с различными средами (например, ARM, x86). Такой подход оптимизирует образы для различных аппаратных платформ.

Пример:

  • Влияние на размер: многоядерные изображения оптимизированы для конкретных архитектур, что потенциально уменьшает размер изображений, используемых на разных платформах. Это помогает избежать раздутых изображений, которые включают поддержку нескольких архитектур, когда нужна только одна.

Заключение

Эти рекомендации позволяют создавать более эффективные, безопасные и быстрые образы Docker, улучшая процессы управления контейнерами и их развёртывания.

Перевод инструкции: How I Cut Docker Image Size by 90%: Best Practices for Lean Containers

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *