Skip to content

حاويات Docker

مقدمة

"يعمل على جهازي" هو عذر المطورين الكلاسيكي، وDocker يجعل هذا العذر يختفي تماماً. تقنية الحاويات تقوم بتغليف التطبيق وجميع تبعياته في وحدة موحدة، مما يضمن عمله بشكل متسق في أي بيئة. إنها حجر الأساس في تسليم البرمجيات الحديثة.

ماذا ستتعلم في هذا المقال؟

بعد إتمام هذا الفصل، ستحصل على:

  • المفاهيم الأساسية: فهم المفاهيم الثلاثة الجوهرية: الصورة (Image)، الحاوية (Container)، المستودع (Registry)
  • مقارنة البنى: فهم الفرق الجوهري بين الحاويات والآلات الافتراضية
  • المهارات العملية: إتقان كتابة Dockerfile والأوامر الشائعة
  • أساسيات التنسيق: تعلم إدارة التطبيقات متعددة الخدمات باستخدام Docker Compose
  • أفضل الممارسات: التعرف على تحسين الصور وتعزيز الأمان والممارسات على مستوى الإنتاج
الفصلالمحتوىالمفهوم الأساسي
الفصل 1لماذا نحتاج الحاوياتاتساق البيئة، كفاءة الموارد، التسليم الموحد
الفصل 2المفاهيم الأساسيةالصورة، الحاوية، المستودع، Dockerfile
الفصل 3دورة حياة Dockerكتابة، بناء، دفع، تشغيل، إدارة
الفصل 4Docker Composeتنسيق متعدد الخدمات، الشبكات، مجلدات البيانات
الفصل 5أفضل الممارساتتحسين الصور، الأمان، البناء متعدد المراحل

1. لماذا نحتاج الحاويات؟

قبل ظهور الحاويات، كان نشر تطبيق يتطلب التثبيت اليدوي لبيئة التشغيل على الخادم، وتكوين متغيرات البيئة، ومعالجة تعارضات التبعيات. الاختلافات بين البيئات (التطوير، الاختبار، الإنتاج) كانت بيئة خصبة للأخطاء.

Virtual Machines vs Containers
Switch between both virtualization models to compare their architecture
App A / App B / App C
App A + Bins/Libs
App B + Bins/Libs
App C + Bins/Libs
Docker Engine
Host OS
Physical hardware
Startup speedSeconds
Resource usageShared host OS kernel (MB scale)
IsolationProcess-level isolation
DensityHundreds of containers per host
Image sizeMB scale

ما هي المشاكل التي تحلها الحاويات؟

المشكلةالطريقة التقليديةطريقة الحاويات
عدم اتساق البيئة"يعمل على جهازي"تغليف جميع التبعيات، اتساق في كل مكان
تعارض التبعياتالتطبيق A يحتاج Node 14، التطبيق B يحتاج Node 18كل حاوية بيئة مستقلة
هدر المواردكل آلة افتراضية تحتاج نظام تشغيل كاملمشاركة النواة، استهلاك بمستوى الميغابايت
النشر البطيءتثبيت وتكوين يدويأمر واحد docker run
صعوبة التوسعإنشاء آلة افتراضية جديدة، تثبيت البيئة، النشربدء حاويات جديدة في ثوانٍ

جوهر الحاويات

الحاوية ليست آلة افتراضية خفيفة. جوهرها هو عملية معزولة. نواة Linux تنفذ الحاويات من خلال آليتين:

  • Namespace: عزل رؤية العمليات (PID، الشبكة، نظام الملفات، إلخ)
  • Cgroups: تقييد استخدام الموارد للعمليات (المعالج، الذاكرة، الإدخال/الإخراج)

العمليات داخل الحاوية لا تختلف جوهرياً عن العمليات العادية على المضيف، إنها فقط "محبوسة في غرفة لا تستطيع رؤية الخارج".


2. المفاهيم الأساسية

عالم Docker يدور حول ثلاثة مفاهيم جوهرية: الصورة (Image)، الحاوية (Container)، والمستودع (Registry).

المفهومالتشبيهالوصف
الصورة (Image)فئة / قالبقالب للقراءة فقط يحتوي على الكود وبيئة التشغيل والمكتبات والتكوين
الحاوية (Container)نسخة / كائننسخة تشغيل من الصورة، قابلة للقراءة والكتابة، لها دورة حياة مستقلة
المستودع (Registry)متجر تطبيقاتخدمة تخزين وتوزيع الصور (Docker Hub، ACR، ECR)
Dockerfileوصفة / مخططملف نصي يحدد كيفية بناء الصورة
مجلد البيانات (Volume)قرص صلب خارجياستمرارية البيانات، لا تُفقد عند حذف الحاوية

البنية الطبقية للصور

صور Docker تتكون من عدة طبقات للقراءة فقط (Layer)، كل تعليمة في Dockerfile تنشئ طبقة:

┌─────────────────────────┐
│  CMD ["node", "app.js"] │  ← طبقة أمر البدء
├─────────────────────────┤
│  COPY . /app            │  ← طبقة كود التطبيق (تتغير كثيراً)
├─────────────────────────┤
│  RUN npm install        │  ← طبقة تثبيت التبعيات (تتغير أحياناً)
├─────────────────────────┤
│  FROM node:18-alpine    │  ← طبقة الصورة الأساسية (نادراً ما تتغير)
└─────────────────────────┘

لماذا الطبقات مهمة؟

Docker يخزن كل طبقة مؤقتاً. إذا لم تتغير طبقة ما، يُعاد استخدام ذاكرة التخزين المؤقت أثناء البناء. لذلك في Dockerfile يجب وضع التعليمات الأقل تغييراً في البداية (مثل تثبيت التبعيات)، والأكثر تغييراً في النهاية (مثل نسخ الكود). هكذا معظم عمليات البناء ستستفيد من ذاكرة التخزين المؤقت وتكون أسرع بكثير.


3. دورة حياة Docker

من كتابة Dockerfile إلى تشغيل الحاوية، سير عمل Docker هو خط إنتاج واضح.

Docker Lifecycle
Click each stage to inspect the details
📝
Write a Dockerfile
🔨
Build the image
☁️
Push to registry
▶️
Run the container
⚙️
Manage containers
Write a Dockerfile
A Dockerfile is the recipe for building an image. It starts from a base image and defines how to assemble the application environment step by step. Each instruction creates an image layer that Docker can cache for later builds.
Common commands
FROM node:18-alpineChoose the base image
WORKDIR /appSet the working directory
COPY package*.json ./Copy dependency files for cache reuse
RUN npm installInstall dependencies
COPY . .Copy application code
EXPOSE 3000Declare the port
CMD ["node", "server.js"]Start command

مرجع سريع لتعليمات Dockerfile

التعليمةالوظيفةمثال
FROMتحديد الصورة الأساسيةFROM node:18-alpine
WORKDIRتعيين دليل العملWORKDIR /app
COPYنسخ ملفات إلى الصورةCOPY package.json ./
RUNتنفيذ أوامر أثناء البناءRUN npm install
ENVتعيين متغيرات البيئةENV NODE_ENV=production
EXPOSEتعريف منفذ (للتوثيق فقط)EXPOSE 3000
CMDأمر بدء الحاويةCMD ["node", "app.js"]
ENTRYPOINTنقطة دخول الحاوية (صعب الكتابة فوقها)ENTRYPOINT ["nginx"]

4. Docker Compose: تنسيق متعدد الخدمات

المشاريع الحقيقية عادة تحتاج أكثر من حاوية واحدة. تطبيق ويب قد يحتاج: خادم تطبيقات + قاعدة بيانات + Redis + Nginx. Docker Compose يُعرّف ويدير حاويات متعددة بملف YAML واحد.

مثال docker-compose.yml

yaml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
      - REDIS_HOST=redis
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret

  redis:
    image: redis:7-alpine

volumes:
  db-data:

المفاهيم الأساسية لـ Compose

المفهومالوصفمثال
servicesتعريف خدمات الحاوياتapp، db، redis
volumesمجلدات البيانات المستمرةdb-data يحفظ ملفات قاعدة البيانات
networksشبكة مخصصة (تُنشأ تلقائياً افتراضياً)الخدمات تتواصل عبر اسم الخدمة
depends_onتبعية ترتيب البدءapp يعتمد على db وredis
environmentمتغيرات البيئةكلمة مرور قاعدة البيانات، عنوان الاتصال

اكتشاف الخدمات

في Docker Compose، اسم الخدمة هو اسم المضيف. حاوية app يمكنها الوصول مباشرة إلى قاعدة البيانات عبر db:5432 وإلى Redis عبر redis:6379، دون الحاجة لمعرفة عنوان IP. هذا بفضل DNS المدمج في Docker.


5. أفضل الممارسات

5.1 البناء متعدد المراحل (Multi-stage Build)

البناء متعدد المراحل أداة قوية لتحسين حجم الصور. مرحلة البناء تثبت جميع الأدوات والتبعيات، بينما المرحلة النهائية تحتفظ فقط بالملفات اللازمة وقت التشغيل.

dockerfile
# مرحلة البناء
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# مرحلة التشغيل
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

5.2 قائمة تحسين الصور

عنصر التحسينما يجب فعلهالتأثير
اختيار صورة أساسية صغيرةاستخدام alpine بدلاً من ubuntuالصورة من ~200MB إلى ~50MB
دمج تعليمات RUNربط أوامر متعددة بـ &&تقليل طبقات الصورة
استخدام .dockerignoreاستبعاد node_modules و.git وغيرهاتسريع البناء، تقليل السياق
البناء متعدد المراحلفصل بيئتي البناء والتشغيلالصورة النهائية لا تحتوي أدوات البناء
تثبيت رقم الإصدارnode:18.17-alpine بدلاً من node:latestبناء قابل للتكرار

5.3 ممارسات الأمان

الممارسةالوصف
عدم التشغيل كـ rootUSER node يحدد مستخدم غير root
فحص الثغراتdocker scout أو Trivy لفحص الصور
الامتيازات الدنياتثبيت الحزم الضرورية فقط، بدون أدوات التصحيح
عدم تضمين الأسراراستخدام متغيرات البيئة أو Docker Secrets
تحديث الصورة الأساسية بانتظامإصلاح الثغرات الأمنية في الوقت المناسب

الخلاصة

حاويات Docker هي البنية التحتية لتسليم البرمجيات الحديثة، وفهمها ضروري لكل مطور.

مراجعة النقاط الرئيسية في هذا الفصل:

  1. الحاويات مقابل الآلات الافتراضية: الحاويات تشارك نواة المضيف، أخف وأسرع، لكن العزل أقل بقليل من VM
  2. الثلاثي الأساسي: الصورة (قالب)، الحاوية (نسخة)، المستودع (التوزيع)
  3. Dockerfile: بناء طبقي، استفد من التخزين المؤقت، التعليمات الأقل تغييراً في البداية
  4. Docker Compose: تعريف تطبيقات متعددة الخدمات بـ YAML، اسم الخدمة هو اسم المضيف
  5. ممارسات الإنتاج: بناء متعدد المراحل لتقليل الحجم، صورة أساسية alpine، التشغيل كمستخدم غير root

قراءة إضافية