Docker: як оптимізувати розмір контейнера з 50 ГБ до керованого рівня

event 06.05.2026 15:18
| category DevOps | person iron_will | comment 0 | visibility 10 | |

Вступ

Контейнери давно стали стандартом де-факто для доставки застосунків у production. Проте з ростом складності систем часто виникає нетривіальна проблема - неконтрольоване збільшення розміру Docker-образів. Сценарій, коли образ досягає 30–50 ГБ, на практиці зустрічається значно частіше, ніж здається, особливо у проєктах із data science, CI/CD пайплайнами або legacy-залежностями.

Надмірний розмір контейнера створює низку критичних проблем: повільне розгортання, перевитрати дискового простору, збільшений час передачі через мережу, складність масштабування та деградація продуктивності CI/CD. У середовищах із високою частотою релізів це прямо впливає на бізнес-метрики.

У цій статті розглянемо системний підхід до оптимізації Docker-образів: від аналізу причин до впровадження практичних технік з прикладами. Матеріал орієнтований на інженерів рівня junior–senior і містить реальні кейси, інструменти та фрагменти коду.

Чому Docker-образи розростаються до десятків гігабайтів

Перш ніж оптимізувати, потрібно зрозуміти джерела проблеми. Найчастіші причини:

1. Невдалий вибір базового образу

Використання повноцінних дистрибутивів:

  • ubuntu
  • debian
  • centos

замість мінімалістичних:

  • alpine
  • distroless
  • scratch

може додати кілька сотень мегабайт або навіть гігабайтів.

2. Зайві залежності та dev-інструменти

У контейнер часто потрапляють:

  • компілятори (gcc, make)
  • менеджери пакетів
  • тестові бібліотеки
  • кеші пакетів

3. Неконтрольовані layer-и

Кожна команда RUN, COPY, ADD створює новий layer. Якщо не очищати тимчасові файли, вони залишаються в історії образу.

4. Великі артефакти

Типові приклади:

  • ML-моделі (кілька ГБ)
  • лог-файли
  • тимчасові дампи
  • node_modules без оптимізації

5. Відсутність .dockerignore

Без цього файлу Docker копіює весь контекст, включно з:

  • .git
  • локальними build-артефактами
  • кешами IDE

Аналіз поточного образу

Перед оптимізацією важливо провести аудит.

Перегляд розміру

docker images

Аналіз layer-ів

docker history <image_name>

Деталізація через dive

Інструмент:

dive <image_name>

Він показує:

  • які файли займають місце
  • які layer-и неефективні
  • потенційні оптимізації

Базові стратегії оптимізації

Використання мінімалістичних базових образів

Було:

FROM ubuntu:22.04

Стало:

FROM alpine:3.19

Результат: зменшення базового шару з ~70 МБ до ~5 МБ.

Але важливо: Alpine використовує musl libc, що може викликати проблеми сумісності.

Multi-stage build

Один із найефективніших підходів.

Приклад для Go

# Stage 1: build
FROM golang:1.22 AS builder
WORKDIR /appCOPY . .
RUN go build -o app

# Stage 2: runtime
FROM alpine:3.19
WORKDIR /app
COPY --from=builder /app/app .
CMD ["./app"]

Результат:

  • видаляються всі build-залежності
  • фінальний образ містить лише binary

Очищення кешів

Поганий варіант:

RUN apt-get updateRUN apt-get install -y python3

Кращий варіант:

RUN apt-get update && \
    apt-get install -y python3 && \
    apt-get clean && \    
rm -rf /var/lib/apt/lists/*

Об'єднання команд RUN

Було:

RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git

Стало:

RUN apt-get update && \
    apt-get install -y curl git && \
    rm -rf /var/lib/apt/lists/*

Робота з .dockerignore

Файл .dockerignore критично важливий.

Приклад

.gitnode_modules*.logtmp/.cachedist/

Без нього контекст може збільшитися на десятки гігабайтів.

Оптимізація для Node.js

Проблема

node_modules часто займає 500 МБ–2 ГБ.

Рішення

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .CMD ["node", "app.js"]

Додатково

npm prune --production

Оптимізація Python-контейнерів

Типові проблеми

  • кеш pip
  • dev-залежності
  • великі бібліотеки (numpy, pandas)

Приклад

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Оптимізація для Data Science (реальний кейс)

Початковий стан

  • образ: 50 ГБ
  • включає:
    • Jupyter
    • datasets
    • checkpoints
    • logs

Кроки оптимізації

  1. Винесення даних у volume або object storage (S3, MinIO)
  2. Видалення логів:
find /app -name "*.log" -delete
  1. Використання multi-stage build
  2. Очищення pip cache:
pip cache purge
  1. Перехід на slim-образ

Результат

  • 50 ГБ → 3.2 ГБ

Використання distroless образів

Distroless містить тільки runtime.

FROM gcr.io/distroless/base
COPY app /app
CMD ["/app"]

Переваги:

  • мінімальний розмір
  • підвищена безпека
Недолік: складніше дебажити.

Видалення непотрібних файлів

Приклад

RUN rm -rf \
    /usr/share/doc \
    /usr/share/man \
    /var/cache/*

Стиснення та оптимізація артефактів

Для Java

jlink --strip-debug --no-man-pages --no-header-files

Для Python

  • використання pyinstaller
  • створення одного binary

Контроль шарів (layer caching)

Порядок команд має значення

Погано:

COPY . .
RUN npm install

Краще:

COPY package.json .
RUN npm install
COPY . .

Це дозволяє кешувати залежності.

Використання BuildKit

DOCKER_BUILDKIT=1 docker build .

Переваги:

  • кращий кеш
  • паралельні збірки
  • менші образи

Автоматичний аудит

Інструменти

  • dive
  • hadolint
  • docker-slim

Приклад docker-slim

docker-slim build myimage

Результат: автоматичне зменшення образу.

CI/CD оптимізація

Практики

  • кешування layer-ів
  • використання registry cache
  • автоматичне очищення старих образів

Типові помилки

  1. Зберігання даних у контейнері
  2. Використання latest-тегів
  3. Ігнорування кешів
  4. Відсутність multi-stage build
  5. Копіювання всього проєкту без фільтрації

Комплексний приклад оптимізації

До

FROM ubuntu:22.04WORKDIR /app
COPY . .
RUN apt-get update
RUN apt-get install -y python3 pip
RUN pip install -r requirements.txt
CMD ["python3", "app.py"]

Після

FROM python:3.11-slim AS builder

WORKDIR /app COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local COPY . .
ENV PATH=/root/.local/bin:$PATH CMD ["python", "app.py"]

Висновки

Оптимізація Docker-образів - це не одноразова дія, а постійний процес, який має бути інтегрований у життєвий цикл розробки. Контейнери розміром у десятки гігабайтів - це майже завжди результат накопичення технічного боргу, а не реальна необхідність.

Ключові принципи:

  • мінімізація базового образу
  • контроль залежностей
  • використання multi-stage build
  • очищення кешів і тимчасових файлів
  • винесення даних за межі контейнера

У більшості практичних сценаріїв реалістично зменшити образ з 50 ГБ до 1 - 5 ГБ без втрати функціональності. Це дає відчутний виграш у швидкості деплою, стабільності та вартості інфраструктури.

Related posts

Як знайти головну IP-адресу джерела DDoS у лог-файлі на 10 млн рядків у Linux

Вступ Коли сервер потрапляє під DDoS-атаку, одним із перших завдань адміністратора є швидке визначення джерел аномального трафіку. На практиці це означає аналіз великих лог-файлів вебсервера, балансувальника, firewall або reverse proxy. Якщо файл мі...

category System administration person iron_will event 25/04/2026

Kubernetes: сучасна платформа оркестрації контейнерів для production-середовищ

Вступ Kubernetes став де-факто стандартом для запуску контейнеризованих застосунків у production-середовищах. Якщо Docker вирішив проблему пакування застосунку разом із залежностями, то Kubernetes вирішує значно складніше завдання - як масштабувати,...

category DevOps person iron_will event 19/04/2026

Файлові системи ext4, XFS, Btrfs - що обрати для production

Вступ Вибір файлової системи в Linux-середовищі - це не просто технічна деталь, а стратегічне рішення, яке безпосередньо впливає на продуктивність, надійність і масштабованість інфраструктури. У production-системах, де критичними є стабільність і пе...

category DevOps person iron_will event 14/04/2026

Zero Trust архітектура на практиці: принципи, впровадження та технічні кейси

Вступ Класичні моделі кібербезпеки, що базуються на периметрі мережі, давно втратили ефективність. Сучасні ІТ-інфраструктури характеризуються гібридністю, розподіленістю та активним використанням хмарних сервісів. У таких умовах концепція «довіряй,...

category Security person iron_will event 05/04/2026

Керування користувачами та правами доступу в Linux на enterprise-рівні

Вступ У сучасних корпоративних ІТ-інфраструктурах системи на базі Linux є критично важливими компонентами - від веб-серверів і контейнерних платформ до систем зберігання даних і DevOps-інструментів. У цьому контексті керування користувачами та права...

category Security person iron_will event 30/03/2026

Nmap: що це таке та як з ним працювати

Вступ У сучасному світі інформаційної безпеки та адміністрування мереж важливо мати інструменти, які дозволяють швидко отримувати інформацію про інфраструктуру, виявляти відкриті порти, служби та потенційні вразливості. Одним із найпотужніших і найп...

category Security person iron_will event 19/03/2026
cookie
This website uses cookies to improve your experience. Learn more