🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

كيفية تحسين صور Docker: تقليل الحجم بنسبة 90% في عام 2026

⏱️3 min read  ·  652 words

تؤدي صور Bloated Docker إلى إبطاء عمليات النشر وتخزين النفايات وزيادة مساحة الهجوم وتكلفة عرض النطاق الترددي. يمكن أن يكون حجم صورة Node.js أو Python النموذجية غير المحسنة أكبر من 1 جيجابايت؛ باستخدام التقنيات الصحيحة، يصل حجم التطبيق نفسه إلى أقل من 100 ميجابايت. إليك كيفية تقليص صور Docker بشكل كبير.

لماذا يهم حجم الصورة

  • عمليات نشر أسرع: يتم سحب الصور الأصغر حجمًا وتبدأ بشكل أسرع، خاصة عند القياس
  • تكاليف أقل: تخزين أقل للتسجيل وعرض النطاق الترددي (مهم على نطاق واسع)
  • سطح الهجوم الأصغر: الحزم الأقل تعني ثغرات أقل
  • CI/CD أسرع: يؤدي إنشاء الصور الأصغر حجمًا ودفعها إلى تسريع خطوط الأنابيب

الأسلوب 1: البناء متعدد المراحل (الفوز الأكبر)

قم بالبناء في مرحلة واحدة باستخدام جميع أدوات البناء، ثم انسخ القطعة الأثرية النهائية فقط إلى صورة نظيفة ومبسطة:

# 🐛 Single-stage — includes build tools, dev deps, source (1.1GB)
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]

# ✅ Multi-stage — final image has only runtime + built output (150MB)
# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Runtime stage — clean slate
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev            # production deps only
COPY --from=builder /app/dist ./dist   # copy ONLY the built output
CMD ["node", "dist/index.js"]

الأسلوب 2: استخدام الحد الأدنى من الصور الأساسية

الصورة الأساسية الحجم التقريبي ملاحظات
العقدة:20 ~1.1 جيجابايت دبيان كامل — تجنب الإنتاج
العقدة: 20-سليم ~240 ميجا بايت ديبيان المشذّب — افتراضي جيد
العقدة:20-جبال الألب ~180 ميجا Alpine Linux — صغير، شائع
gcr.io/distroless/nodejs ~170 ميجا لا يوجد مدير شل/حزمة – الأكثر أمانًا
# Alpine — smallest common choice
FROM node:20-alpine

# Distroless — no shell, no package manager, minimal attack surface
FROM gcr.io/distroless/nodejs20-debian12
COPY --from=builder /app/dist /app/dist
CMD ["/app/dist/index.js"]

الأسلوب 3: تحسين التخزين المؤقت للطبقة

# 🐛 Copying everything first breaks caching — any code change
#    re-runs npm install
COPY . .
RUN npm ci

# ✅ Copy dependency files first, install, THEN copy source
COPY package*.json ./
RUN npm ci                # this layer is cached unless package.json changes
COPY . .                  # only this layer rebuilds on code changes
RUN npm run build

ترتيب تعليمات ملف Dockerfile من الأقل تغييرًا إلى الأكثر تكرارًا. نادرًا ما تتغير التبعيات، ويتغير المصدر باستمرار — لذا قم بتثبيت التبعيات قبل نسخ المصدر لزيادة عدد مرات الوصول إلى ذاكرة التخزين المؤقت.

التقنية الرابعة: استخدم .dockerignore

# .dockerignore — exclude files that bloat the build context
node_modules
npm-debug.log
.git
.gitignore
.env
.env.*
dist
coverage
.vscode
.idea
README.md
*.md
.DS_Store
tests
**/*.test.js

بدون.dockerignore, COPY . . يرسل دليلك بالكامل (بما في ذلكNode_modules و.git) إلى البناء – مما يؤدي إلى إبطاء عمليات البناء وربما تسريب الأسرار.

الأسلوب 5: دمج وتنظيف أوامر RUN

# 🐛 Each RUN creates a layer; cleanup in a separate layer doesn't shrink
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*   # too late — previous layers keep the data

# ✅ Combine into one layer with cleanup in the same RUN
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*   # cleanup in the SAME layer

مثال بايثون: متعدد المراحل + سليم

# Build stage — compile dependencies
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# Runtime stage — slim base + only installed packages
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]
# Result: ~150MB instead of ~1GB

قياس وتحليل حجم الصورة

# Check image size
docker images myapp

# Analyze layers to find what's taking space
docker history myapp:latest

# Use 'dive' for detailed layer analysis
dive myapp:latest
# Shows wasted space and what each layer adds

قائمة التحقق من التحسين

  • استخدم تصميمات متعددة المراحل – انسخ عناصر وقت التشغيل فقط إلى الصورة النهائية
  • استخدم الصور الأساسية لجبال الألب أو الرفيعة أو غير الموزعة
  • انسخ الملفات التابعة وقم بالتثبيت قبل نسخ المصدر (التخزين المؤقت للطبقة)
  • إضافة شاملة.dockerignore
  • تثبيت تبعيات الإنتاج فقط (npm ci --omit=dev, pip --no-cache-dir)
  • دمج أوامر RUN والتنظيف في نفس الطبقة
  • إصدارات الصور الأساسية للتكرار

الأسئلة المتداولة

س: هل Alpine هي أفضل صورة أساسية دائمًا؟
ج: عادةً ما تكون أصغر، لكن Alpine يستخدم musl libc الذي يسبب أحيانًا مشكلات مع الوحدات الأصلية أو DNS. إذا واجهت مشاكل في التوافق، استخدم Slim (المستند إلى Debian) – فهو لا يزال صغيرًا وأكثر توافقًا. Distroless is best for security.

Q: What is distroless and should I use it?
A: Distroless images contain only your app and its runtime — no shell, no package manager, minimal OS. This shrinks size and dramatically reduces attack surface. Great for production, but harder to debug (no shell to exec into).

Q: How much smaller can I realistically get?
A: Multi-stage builds plus a minimal base commonly reduce images by 70-90%. A 1GB Node.js image often becomes 100-150MB. Distroless can go smaller still.

Q: Does image size affect runtime performance?
A: Not directly at runtime, but smaller images pull and start faster (important for autoscaling and cold starts), use less registry storage, and have fewer vulnerabilities. The benefits are in deployment speed and security.

Q: Why does my image stay large despite cleanup commands?
A: Docker layers are immutable — if you add files in one layer and delete them in another, the deleted data still exists in the earlier layer. Clean up in the SAME RUN command, or use multi-stage builds to leave the bloat behind entirely.

Conclusion

Optimizing Docker images comes down to a few high-impact techniques: multi-stage builds (copy only what runtime needs), minimal base images (alpine, slim, or distroless), smart layer caching (dependencies before source), and a thorough .dockerignore. Together these commonly shrink images by 70-90% — from 1GB+ down to 100-150MB. Smaller images deploy faster, cost less, and expose a smaller attack surface. Apply the checklist to your Dockerfiles وقياس النتائج باستخدامdocker history or dive.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা