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

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

Вступ

Контейнери давно стали стандартом де-факто для доставки застосунків у 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

Robocopy: можливості та переваги перед звичайним Copy/Xcopy

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

category DevOps person iron_will event 28/05/2026

VPN, SSH та базова безпека інфраструктури

Вступ Сучасна IT-інфраструктура функціонує в умовах постійного зовнішнього впливу: сканування портів, автоматизовані брутфорс-атаки, експлуатація вразливостей сервісів та цільові кібератаки. Навіть невеликі системи без належного захисту можуть стати...

category Security person iron_will event 26/05/2026

Автоматизація деплою через GitHub Actions

Вступ Сучасна розробка програмного забезпечення неможлива без автоматизації процесів доставки коду. Ручний деплой давно став вузьким місцем у життєвому циклі продукту: він збільшує ризик помилок, уповільнює релізи та ускладнює масштабування командно...

category DevOps person iron_will event 26/05/2026

Kubernetes для новачків: базові концепції

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

category Kubernetes person iron_will event 17/05/2026

Що таке RAID: рівні RAID, принцип роботи та навіщо він потрібен

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

category System administration person iron_will event 10/05/2026

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

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

category System administration person iron_will event 25/04/2026
cookie
This website uses cookies to improve your experience. Learn more
dangerous
warning