وداعًا لدليل التثبيت ذي الـ 30 خطوة: كيف أنقذنا Docker Compose من جحيم إعداد المشاريع؟

يا جماعة الخير، السلام عليكم ورحمة الله وبركاته. معكم أخوكم أبو عمر.

بتذكر قبل كم سنة، انضم لفريقنا شب جديد، خلينا نسميه “خالد”. خالد مبرمج شاطر وعين الله عليه، متحمس يبدأ يشتغل ويفرجينا إبداعه. أعطيناه الوصول للكود تبع المشروع الجديد، مشروع ضخم فيه خدمات مصغرة (microservices)، وقواعد بيانات من نوعين، ونظام كاش (caching)، وقصص طويلة عريضة.

قلتله: “يا خالد، هي الـ README، اقرأها وامشي مع الخطوات، ولو احتجت إشي أنا موجود”. ابتسم الشب ابتسامة الواثق، وأنا ابتسمت ابتسامة اللي عارف شو اللي جاي. بعد ساعتين، إجا خالد مكتبي، وجهه مقلوب، وقال لي الجملة اللي كل مدير فريق بكرهها: “يا أبو عمر، مش زابط معي… إشي بطلعلي error غريب!”.

قعدنا أنا وهو يومين كاملين! نعم، يومين ونحن بنحاول نثبّت نسخة PHP معينة، مع امتدادات (extensions) خاصة، ونسخة PostgreSQL محددة، و Redis، وكل واحد فيهم بده إعدادات معينة وملفات config لازم تتعدل. والمشكلة الكبرى كانت جملة “It works on my machine” أو “والله شغّال عندي!”، كل واحد فينا عنده إعدادات مختلفة شوي على جهازه، واللي بيشتغل عندي ما بيشتغل عنده.

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

ما هو Docker أصلًا؟ (ولماذا لم يكن كافيًا لوحده؟)

قبل ما نحكي عن المنقذ Docker Compose، لازم نفهم الأداة الأساسية: Docker. ببساطة شديدة، تخيل إنك بتقدر تحط تطبيقك وكل إشي بيحتاجه عشان يشتغل (المكتبات، الإعدادات، وحتى نظام التشغيل المصغّر) داخل “صندوق” أو “حاوية” (Container). هذا الصندوق معزول تمامًا عن جهازك الأصلي، وتقدر تشغّله على أي جهاز ثاني عليه Docker بدون أي مشاكل.

هذا الحل العبقري قضى على مشكلة “شغّال عندي!”. صار النقاش: “هل هو شغال جوا الحاوية؟”. إذا الجواب نعم، فالمشكلة انحلت.

لكن، واجهتنا مشكلة جديدة. مشروعنا ما كان تطبيق واحد، كان عبارة عن:

  • خدمة خلفية (Backend API) مكتوبة بلغة Node.js.
  • واجهة أمامية (Frontend) مكتوبة بـ React.
  • قاعدة بيانات PostgreSQL.
  • خدمة كاش باستخدام Redis.

صرنا محتاجين نشغّل 4 حاويات مختلفة، ونخليهم يتواصلوا مع بعض. كنا بنكتب أوامر طويلة ومعقدة في الـ terminal لكل حاوية، مثل docker run --name my-db -e POSTGRES_PASSWORD=... -v ... -p ... postgres. كان الموضوع متعب وعرضة للأخطاء، وفقدنا الفائدة الأساسية: البساطة.

وهنا يأتي المنقذ: Docker Compose

Docker Compose هو الأداة اللي بتخليك تدير التطبيقات متعددة الحاويات بسهولة. هو مثل “المُنسّق” أو “المايسترو” اللي بيقرأ ملف واحد، وبيفهم منه كل الخدمات اللي مشروعك بيحتاجها، وكيف لازم تشتغل مع بعضها.

القصة وما فيها، إنك بتكتب كل إعدادات خدماتك (الـ API، قاعدة البيانات، إلخ) في ملف واحد بصيغة YAML اسمه docker-compose.yml. بعدين، وبأمر واحد بسيط جدًا، بتخلّي Docker Compose يشغّل كل هاي الخدمات ويوصلها ببعضها.

ببساطة: Docker هو “الحاوية”، و Docker Compose هو “مدير الحاويات” اللي بينظمها وبيخليها تشتغل مع بعض بانسجام.

لنطبق عمليًا: بناء بيئة تطوير لمشروع ويب بسيط

خلينا نأخذ مثال عملي عشان الصورة توضح. تخيل عنا تطبيق ويب بسيط مكون من خدمة خلفية بـ Node.js وقاعدة بيانات PostgreSQL.

السيناريو: تطبيق ويب بـ Node.js مع قاعدة بيانات PostgreSQL

المشروع يتكون من:

  1. خدمة `api`: تطبيق Express.js بسيط يتصل بقاعدة البيانات.
  2. خدمة `db`: قاعدة بيانات PostgreSQL لتخزين البيانات.

قبل Docker Compose: الكابوس

لإعداد هذا المشروع يدويًا، كنت ستحتاج إلى:

  • تثبيت Node.js (والتأكد من أنها النسخة الصحيحة).
  • تثبيت PostgreSQL على جهازك.
  • إنشاء قاعدة بيانات ومستخدم خاص بالتطبيق.
  • تذكر اسم المستخدم وكلمة المرور وتحديثها في ملف .env.
  • تشغيل PostgreSQL في الخلفية.
  • تشغيل تطبيق Node.js في الـ terminal.
  • وكل هذا قبل كتابة سطر كود واحد!

مع Docker Compose: السحر

الآن، انسَ كل ما سبق. كل ما نحتاجه هو ملفين: Dockerfile لتطبيقنا، و docker-compose.yml لتنسيق كل شيء.

1. ملف `Dockerfile` لخدمة الـ API (ضعه في مجلد الـ API):

# استخدم صورة Node.js رسمية
FROM node:18

# أنشئ مجلد العمل داخل الحاوية
WORKDIR /usr/src/app

# انسخ ملفات package.json و package-lock.json
COPY package*.json ./

# ثبّت الاعتماديات
RUN npm install

# انسخ باقي ملفات المشروع
COPY . .

# عرّض البورت الذي يعمل عليه التطبيق
EXPOSE 3000

# الأمر الافتراضي لتشغيل التطبيق
CMD [ "node", "server.js" ]

2. ملف docker-compose.yml (ضعه في جذر المشروع):

version: '3.8'

services:
  # خدمة قاعدة البيانات
  db:
    image: postgres:14-alpine  # استخدم صورة رسمية وخفيفة
    restart: always
    environment:
      - POSTGRES_USER=abu_omar
      - POSTGRES_PASSWORD=supersecretpassword
      - POSTGRES_DB=my_app_db
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432" # اختياري: لتمكين الوصول من خارج Docker

  # خدمة الـ API
  api:
    build: . # ابني الصورة من الـ Dockerfile في نفس المجلد
    restart: always
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://abu_omar:supersecretpassword@db:5432/my_app_db
    depends_on:
      - db # لا تشغل الـ API إلا بعد أن تبدأ قاعدة البيانات
    volumes:
      - .:/usr/src/app # مهم جدًا للتطوير: مزامنة الكود مباشرة

volumes:
  postgres_data: # هذا يضمن عدم فقدان بياناتك عند إيقاف الحاويات

الآن، كل ما على المبرمج الجديد “خالد” فعله هو:

  1. تثبيت Docker و Docker Compose على جهازه.
  2. تحميل الكود من Git.
  3. فتح الـ terminal وكتابة أمر واحد: docker-compose up.

وهذا كل شيء! خلال دقائق، سيتم بناء حاوية الـ API، وتشغيل حاوية قاعدة البيانات، وتوصيلهما معًا، وسيصبح المشروع جاهزًا للتطوير. لا مزيد من أدلة التثبيت الطويلة، ولا مزيد من “مش زابط معي!”.

نصائح من خبرة أبو عمر (شغلات ما بتلاقيها بالـ Docs)

على مدار السنين، تعلمت كم شغلة مهمة في التعامل مع Docker Compose، بحب أشاركها معكم:

  • لا تعيد اختراع العجلة: استخدم دائمًا الصور الرسمية (Official Images) من Docker Hub قدر الإمكان (مثل `postgres`, `node`, `redis`). فهي مُحسّنة وآمنة وموثوقة.
  • حافظ على بياناتك يا غالي: لاحظت في المثال كيف استخدمنا `volumes` مع `postgres_data`؟ هذا يُسمى “Named Volume”. هذا يضمن أن بيانات قاعدة بياناتك ستبقى محفوظة حتى لو حذفت الحاويات وأعدت بناءها. لا تخزن بيانات قاعدة البيانات داخل الحاوية مباشرة أبدًا!
  • استخدم `depends_on` بحكمة: `depends_on` تضمن ترتيب بدء تشغيل الحاويات، لكنها لا تضمن أن الخدمة داخل الحاوية (مثل قاعدة البيانات) أصبحت جاهزة لاستقبال الاتصالات. في المشاريع المعقدة، قد تحتاج إلى استخدام سكربتات “wait-for-it” للتأكد من جاهزية الخدمات قبل المتابعة.
  • افصل بين بيئة التطوير والإنتاج: يمكنك استخدام ملف `docker-compose.override.yml` لتعديل إعدادات التطوير. مثلًا، في التطوير، نستخدم `volumes` لمزامنة الكود مباشرة (live reload)، لكن في الإنتاج، ننسخ الكود داخل الصورة مرة واحدة عند البناء.
  • تعلم الأوامر الأساسية:
    • docker-compose up -d: لتشغيل كل شيء في الخلفية.
    • docker-compose down: لإيقاف وحذف الحاويات والشبكات.
    • docker-compose logs -f api: لمشاهدة سجلات (logs) خدمة معينة بشكل مباشر.
    • docker-compose exec api bash: للدخول إلى حاوية وتشغيل الأوامر بداخلها (مفيدة جدًا لتصحيح الأخطاء).

الخلاصة: استثمر في بيئتك، تربح وقتك وجهدك ✅

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

نصيحتي لك: لا تنظر إلى Docker Compose على أنه مجرد “أداة DevOps”. هو أداة أساسية لكل مطور. استثمار يوم أو يومين في تعلم أساسياته سيوفر عليك وعلى فريقك أسابيع من الصداع والإحباط على المدى الطويل. ابدأ اليوم، ولو بمشروع شخصي صغير، وستشكرني لاحقًا. 🚀

والله ولي التوفيق.

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

برمجة وقواعد بيانات

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من جحيم التوقفات المجدولة؟

هل سئمت من إيقاف الخدمة مع كل تحديث لهيكلة قاعدة البيانات؟ أشارككم قصة حقيقية وكيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من ليالي النشر الطويلة والمُجهدة،...

4 يونيو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت إعادة المحاولة كارثة: كيف أنقذتنا مفاتيح عدم تكرار العمليات (Idempotency Keys) من جحيم الفواتير المزدوجة؟

أشارككم قصة حقيقية من الخنادق البرمجية، يوم كاد خطأ بسيط في إعادة محاولة طلبات الدفع أن يكلفنا سمعتنا وأموال عملائنا. اكتشفوا معنا كيف كانت مفاتيح...

4 يونيو، 2026 قراءة المزيد
الحوسبة السحابية

من التوقف التام إلى النجاة: كيف أنقذتنا استراتيجية “الضوء المرشد” (Pilot Light) يوم انقطعت السحابة؟

أتذكر ذلك اليوم جيدًا، فنجان القهوة الصباحي، وصوت تنبيهات المراقبة يصرخ كأنه يوم القيامة. كانت منطقة سحابية كاملة قد توقفت عن العمل، لكن بفضل استراتيجية...

4 يونيو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كانت مهمتي البرمجية للاختبار مجرد كود: كيف أنقذني توثيق القرارات من جحيم الصمت بعد المقابلة؟

أشارككم قصة حقيقية من بداياتي، وكيف تعلمت بالطريقة الصعبة أن المهمة البرمجية ليست مجرد كتابة كود، بل هي فرصة لإظهار طريقة تفكيرك. اكتشف كيف يمكن...

4 يونيو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

من الانتظار لأيام إلى الدفع في ثوانٍ: كيف أنقذتنا شبكات الدفع الفوري من جحيم التحويلات البنكية؟

أسرد لكم من واقع تجربتي كـ "أبو عمر"، كيف عانينا من بطء وتكلفة التحويلات البنكية الدولية، وكيف جاءت شبكات الدفع الفوري ومعيار ISO 20022 لتكون...

4 يونيو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

كان كل خادم لدينا ‘ندفة ثلج’ فريدة: كيف أنقذنا ‘الكود كبنية تحتية’ (IaC) من جحيم الانجراف اليدوي؟

في هذه المقالة، أشارككم قصة حقيقية من قلب المعركة التقنية مع "خوادم ندفات الثلج" الفوضوية. سنغوص في مفهوم "الكود كبنية تحتية" (IaC) وكيف أن أدوات...

4 يونيو، 2026 قراءة المزيد
اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

كنا نظن أن تغطية الاختبار بنسبة 100% هي درعنا الواقي، لكن الأخطاء كانت تتسلل إلى الإنتاج كاللصوص في ليل بهيم. اكتشف كيف أنقذنا "الاختبار الطفري"...

4 يونيو، 2026 قراءة المزيد
البودكاست