چطور حجم ایمیج داکر را نصف کردم

docker۲ خرداد ۱۴۰۴۸ دقیقه مطالعه

یک سرویس کوچک پایتون داشتم که ایمیجش ۹۴۰ مگابایت شده بود. برای کاری که در عمل چند فایل .py و چند کتابخانه بود، این حجم واقعاً زیاد بود. با چند تغییر ساده رساندمش به حدود ۴۲۰ مگابایت.

اول: ترتیب لایه‌ها را درست کن

داکر هر دستور Dockerfile را یک لایه می‌کند و لایه‌ها را کش می‌کند. اگر وابستگی‌ها را بعد از کپی کل سورس نصب کنی، هر تغییر کوچک در کد کل نصب را باطل می‌کند. ترتیب درست این است:

FROM python:3.12-slim

WORKDIR /app

# اول فقط فایل وابستگی‌ها — این لایه کش می‌شود
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# بعد بقیه‌ی سورس
COPY . .

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

آن --no-cache-dir به‌تنهایی چند ده مگابایت کش pip را حذف می‌کند.

دوم: از ایمیج پایه‌ی سبک‌تر استفاده کن

تفاوت python:3.12 و python:3.12-slim حدود ۷۰۰ مگابایت است. مگر اینکه واقعاً به ابزارهای build کامل نیاز داشته باشی، slim کافی است.

سوم: multi-stage build

بزرگ‌ترین جهش وقتی بود که مرحله‌ی build را از مرحله‌ی اجرا جدا کردم. چیزهایی مثل کامپایلر فقط موقع نصب لازم‌اند، نه موقع اجرا:

FROM python:3.12 AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
COPY --from=build /install /usr/local
COPY . .
CMD ["python", "main.py"]

ایمیج نهایی فقط چیزی را دارد که برای اجرا لازم است؛ ابزارهای build در ایمیج اول جا می‌مانند.

چهارم: یک .dockerignore بنویس

این فایل را خیلی‌ها جا می‌اندازند. بدون آن، کل .git و فایل‌های محیط محلی هم وارد context می‌شوند:

.git
__pycache__/
*.pyc
.venv/
.env
برای دیدن اینکه حجم کجا رفته، docker history <image> لایه‌به‌لایه نشان می‌دهد کدام دستور چقدر اضافه کرده.

→ بازگشت به یادداشت‌ها