دليل عملي

النشر

Docker Compose في الإنتاج: قائمة التحقق من 10 نقاط

‏ملف ‎docker-compose‎‎.yml‎ الذي يعمل على حاسوبك لن ينجو من الإنتاج كما هو. إعادة التشغيل بعد الإقلاع، وحدود الموارد، والأسرار، وتدوير السجلات: كلها إعدادات غائبة افتراضيًا وتسبب أعطالًا صامتة بمجرد كشف الخدمة. تجمع قائمة التحقق هذه المعايير العشرة التي يجب فحصها قبل نشر حزمة ‎Compose‎ على خادم ‎VPS‎، ثم الفحوصات الصحية والأسرار والتراجع واستكشاف الأخطاء. وتغطي أيضًا الانتقال من `docker-compose` إلى `docker compose`، وهو أمر تفرض الترقية إلى ‎Ubuntu 26.04‎ حسمه.

12 دقيقةً للقراءةعدد الخطوات: 10
المحتويات· لماذا قائمة تحقق قبل الإنتاج1/13
  1. 01لماذا قائمة تحقق قبل الإنتاج
  2. 02النقاط العشر بلمحة
  3. 03المتطلبات المسبقة
  4. 04الخطوات العشر المفصَّلة
  5. 05إعدادات التطوير مقابل الإنتاج
  6. 06‎docker-compose‎ أم ‎docker compose‎: قطيعة ‎Ubuntu 26.04‎
  7. 07ترحيل السكربتات وإضافة ‎shim‎
  8. 08الفحوصات الصحية المتقدمة: مراقبة الحالة الفعلية للخدمة
  9. 09‎Docker secrets‎ بدون ‎Swarm‎: تحميل الملفات في ‎/run/secrets/
  10. 10التراجع: العودة إلى الوراء بعد نشر فاشل
  11. 11استكشاف الأخطاء: 6 أخطاء شائعة وحلولها
  12. 12نسخ الأحجام احتياطيًا دون تلف
  13. 13الخاتمة

لماذا قائمة تحقق قبل الإنتاج

‏صُمِّم ‎Docker Compose‎ للتطوير: قيمه الافتراضية تفضِّل البساطة على المتانة. في التطوير لا تشكِّل هذه الإعدادات أي مشكلة. في الإنتاج تتحول إلى حوادث: قرص ممتلئ الساعة الثالثة فجرًا، قاعدة بيانات ضائعة بعد docker compose down، خدمة غير متاحة بعد انقطاع الكهرباء. البشرى: تقوية حزمة ‎Compose‎ لا تتطلب إعادة كتابة، بل عشر إضافات مستهدفة فحسب. مرر كل نقطة في هذه القائمة قبل الإطلاق وستصمد خدمتك أمام الأحمال وعمليات إعادة التشغيل بلا مراقبة مستمرة.

النقاط العشر بلمحة

  • ‏restart: unless-stopped — تُعاد الحاوية بعد إقلاع المضيف أو انهيارها
  • ‏healthcheck — يكتشف ‎Docker‎ حاوية عالقة ويتيح إعادة التشغيل التدريجي
  • ‏حدود المعالج والذاكرة — خدمة جامحة لا يمكنها خنق جيرانها
  • ‏الأسرار عبر ‎.env‎ أو ‎Docker secrets‎ — لا كلمة مرور بنص صريح
  • ‏وحدات تخزين مُسمَّاة — تنجو البيانات من docker compose down
  • ‏تدوير السجلات — max-size وmax-file يمنعان امتلاء القرص
  • ‏عزل الشبكة — افصل frontend وbackend
  • ‏ربط المنافذ — 127.0.0.1:PORT خلف وكيل عكسي، لا 0.0.0.0
  • ‏وسوم صور مثبَّتة — نسخة أو بصمة، لا latest
  • ‏depends_on مع شرط — service_healthy يتجنب سباقات الإقلاع

المتطلبات المسبقة

‏تحتاج إلى خادم ‎VPS‎ عليه ‎Docker Engine‎ وإضافة ‎Compose v2‎. الأمر هو docker compose بلا شرطة: تحقق منه عبر docker compose version، لأن صيغة deploy.resources خارج ‎Swarm‎ تتطلب ‎Compose v2‎ (أما docker-compose القديم فنتناوله أدناه). افحص المحرك أيضًا عبر docker version. يصحِّح ‎Docker Engine 29.7.2‎ الثغرة ‎CVE-2026-17106‎ (‎CopyEscape‎)، وهي حالة تسابق في docker cp أُفصح عنها في 10 أغسطس 2026: تستطيع حاوية غير موثوقة عبرها الكتابة فوق ملف على المضيف، بما في ذلك الملف التنفيذي runc. على أجهزة العمل، وصل التصحيح في ‎Docker Desktop 4.86.0‎. وإلى أن تُحدِّث، لا تشغِّل docker cp من حاوية لا تتحكم في محتواها. ضع المشروع في مجلد مخصص (/opt/myapp) مع ملف .env بصلاحيات chmod 600. خطِّط لوكيل عكسي في المقدمة — ‎Traefik‎ أو ‎Caddy‎ أو ‎Nginx‎ — لأن ربط المنافذ يفترض ألا تصل الحركة العامة إلى حاوياتك مباشرة، واحفظ ملف ‎Compose‎ تحت إدارة الإصدارات.

الخطوات العشر المفصَّلة

  1. 1. سياسة إعادة التشغيل

    ‏أضف restart: unless-stopped إلى كل خدمة. تُعاد الحاوية بعد انهيار أو إقلاع المضيف، لكنها تبقى موقوفة إذا أوقفتها بإرادتك. تجنَّب restart: always الذي يُعيد تشغيل حتى حاوية أردتَ إيقافها، وفضِّل unless-stopped للخدمات التطبيقية وon-failure للمهام الوقتية.

  2. 2. الفحص الصحي

    ‏أعلن كتلة healthcheck: مع test وinterval (مثلاً 30s) وtimeout (مثلاً 10s) وretries (مثلاً 3). أضف start_period: 40s للخدمات البطيئة في الإقلاع حتى لا تُعدَّ unhealthy أثناء التهيئة. يُعلِّم ‎Docker‎ الحاوية بـhealthy أو unhealthy مما يتيح لـdepends_on: condition: service_healthy انتظار الجاهزية الفعلية.

  3. 3. حدود الموارد

    ‏تحت deploy.resources.limits، حدِّد cpus وmemory (مثلاً memory: 512M). بلا حد تستطيع خدمة نازفة استهلاك كل الذاكرة وتُفعِّل قاتل OOM. أضف reservations لضمان حد أدنى عند الإقلاع.

  4. 4. الأسرار خارج الملف

    ‏لا تضع أبدًا كلمة مرور بنص صريح في YAML. أرجع إليها عبر env_file أو secrets: الذي يُحمِّل الأسرار كملفات تحت /run/secrets/ داخل الحاوية، بعيدًا عن docker inspect. أضف .env إلى .gitignore.

  5. 5. وحدات التخزين المُسمَّاة

    ‏أعلن بياناتك في وحدات تخزين مُسمَّاة بمشغِّل صريح. وحدة التخزين المسمَّاة تنجو من docker compose down؛ يمحوها فقط down -v. وثِّق كل وحدة تخزين واربطها باستراتيجية استرداد مختبَرة.

  6. 6. تدوير السجلات

    ‏أضف logging: مع driver: json-file وخياريَّي max-size وmax-file. بلا هذا تملأ سجلات حاوية ثرثارة القرص حتى العطل. طبِّقه على كل خدمة.

  7. 7. عزل الشبكة

    ‏أنشئ شبكات مُسمَّاة frontend وbackend وأرفق كل خدمة فقط بما تحتاجه. أضف internal: true على شبكة backend لمنع أي وصول من المضيف أو الإنترنت.

  8. 8. ربط المنافذ

    ‏انشر على 127.0.0.1:8080:8080 لا 8080:8080 خلف وكيل عكسي. Docker يعدِّل قواعد iptables مباشرة وقد يتجاوز UFW — ربط 127.0.0.1 هو الضمان الوحيد الموثوق.

  9. 9. وسوم الصور المثبَّتة

    ‏استبدل latest بنسخة محددة أو بصمة. استخدم pull_policy: missing لسلوك متوقع: لا يسحب Compose صورة جديدة إلا إذا كانت غائبة محليًا.

  10. 10. ترتيب الإقلاع

    ‏استخدم depends_on مع condition: service_healthy. للخدمات التي لا تدعم فحصًا صحيًا أصليًا، استخدم condition: service_started مع سكريبت انتظار مثل wait-for-it.sh.

إعدادات التطوير مقابل الإنتاج

مرّر الجدول أفقيًا

الإعدادافتراضي التطويرموصى به للإنتاج
restartnounless-stopped
healthcheckغائبمُعرَّف بفترة ومحاولات
الذاكرةبلا حدحد محدد
الأسرارنص صريح ممكن‎.env أو Docker secrets
وحدات التخزينمجهولةمُسمَّاة
السجلاتبلا حدmax-size + max-file
الشبكةالجسر الافتراضيfrontend / backend
المنافذ0.0.0.0127.0.0.1 خلف وكيل
الصورةlatestنسخة أو بصمة
depends_onالإطلاق فقطcondition: service_healthy

‎docker-compose‎ أم ‎docker compose‎: قطيعة ‎Ubuntu 26.04‎

‏أداتان تحملان الاسم نفسه تقريبًا. docker-compose بالشرطة هي ‎Compose v1‎ المكتوبة بلغة ‎Python‎: يعلن مستودعها انتهاء عمرها منذ الإتاحة العامة لـ‎Compose v2‎ التي أعلنتها ‎Docker‎ في 26 أبريل 2022. وdocker compose بمسافة هي ‎Compose v2‎ المكتوبة بلغة ‎Go‎ والمدمجة في واجهة ‎Docker‎ كإضافة. يُكمل ‎Ubuntu 26.04‎ هذا الانتقال: الحزمة docker-compose لم تعد في الأرشيف منذ ‎Ubuntu 25.10‎، والحزمة docker-compose-v2 لا تثبِّت سوى الإضافة في /usr/libexec/docker/cli-plugins/. بعد الترقية، يتوقف كل سكربت ما زال يستدعي الاسم القديم عند الرسالة docker-compose: command not found. وفي التكامل المستمر، أخرجت ‎GitHub‎ إصدار ‎Compose v1‎ من مشغلاتها المستضافة في 9 يوليو 2024، وتنقل ubuntu-latest إلى ‎Ubuntu 26.04‎ بين 19 أكتوبر و19 نوفمبر 2026: سير العمل الذي كان يثبِّت docker-compose يدويًا يحتاج إلى مراجعة. هناك فرقان موثَّقان في السلوك. أسماء الحاويات تستعمل الشرطة بدل الشرطة السفلية (myapp-web-1 مقابل myapp_web_1)، إلا مع --compatibility. والمفتاح version: يُتجاهَل مع التحذير «‎the attribute‎ version ‎is obsolete, it will be ignored‎».

ترحيل السكربتات وإضافة ‎shim‎

  • ‏الجرد — الأمر grep -rnE 'docker-compose( |$)' /opt /etc/cron* /etc/systemd ~/.bashrc يسرد الاستدعاءات التي يجب تصحيحها.
  • ‏السكربتات و‎Makefile‎ — استبدل الشرطة بمسافة (docker compose up -d)؛ الأوامر الفرعية المعتادة لا تتغير.
  • ‏‎cron‎ و‎systemd‎ — استدعِ /usr/bin/docker compose بمسار مطلق، لأن ‎cron‎ يعمل بمتغير PATH مختصر.
  • ‏‎GitHub Actions‎ — اختبر سير العمل عبر runs-on: ubuntu-26.04 قبل التحويل، أو ثبِّت ubuntu-24.04 ريثما تصحِّحه، كما توصي ‎GitHub‎.
  • ‏‎Shim‎ مؤقت — ملف تنفيذي /usr/local/bin/docker-compose من سطرين، #!/bin/sh ثم exec docker compose "$@"، يلتقط الاستدعاءات المنسية. وتصون ‎Docker‎ أيضًا الأداة compose-switch التي تترجم صيغة ‎v1‎ إلى ‎v2‎.
  • ‏أسماء الحاويات — استبدل docker exec myapp_web_1 المكتوب يدويًا بـdocker compose exec web الذي لا يعتمد على الفاصل.
  • ‏التحقق — docker compose version يجيب، وdocker compose config يمر بلا تحذير، وcommand -v docker-compose لا يشير إلا إلى الـ‎shim‎.

الفحوصات الصحية المتقدمة: مراقبة الحالة الفعلية للخدمة

‏فحص صحي جيد التهيئة يتجاوز curl البسيط: يقيس الحالة الوظيفية للخدمة لا مجرد التوافر الشبكي. لواجهة برمجية HTTP اختبر نقطة نهاية خفيفة (/health أو /ready) تُعيد 200 فقط إذا كان اتصال قاعدة البيانات قائمًا. لـ‎PostgreSQL‎ استخدم pg_isready -U postgres. لـ‎Redis‎ يكفي redis-cli ping. تحقق من حالة حاوياتك بـdocker compose ps: العمود STATUS يعرض healthy أو unhealthy أو starting. حاوية عالقة في starting لأطول من start_period تشير إلى مشكلة تهيئة — راجع docker compose logs service لمعرفة السبب. المعامل start_period مستقل عن interval: يحدد نافذة سماح لا تُحسب فيها الإخفاقات ضمن retries، وهو ضروري للخدمات التي تحتاج وقتًا للترحيل أو التعبئة.

‎Docker secrets‎ بدون ‎Swarm‎: تحميل الملفات في ‎/run/secrets/

‏خارج ‎Swarm‎، يقبل ‎Compose‎ الأسرار من نوع الملف. أعلن السر في قسم secrets: بمستوى الجذر مشيرًا إلى ملف محلي (file: ./secrets/db_password.txt)، ثم أشر إليه في الخدمة عبر secrets: [db_password]. يُحمِّل ‎Docker‎ هذا الملف للقراءة فقط في /run/secrets/db_password: يقرؤه التطبيق كملف عادي، ولا تظهر قيمته في متغيرات البيئة التي يعرضها docker inspect ولا في السجلات. للتدوير، أعطِ السر رقم إصدار: أنشئ db_password_v2 بجانب db_password_v1، واجعل الخدمة تقرأ v2، وأعد نشرها وحدها عبر docker compose up -d --no-deps service، ثم احذف v1 بعد التحقق من النشر. يقتصر الانقطاع على إعادة إنشاء هذه الحاوية، ويبقى السر القديم متاحًا للتراجع.

التراجع: العودة إلى الوراء بعد نشر فاشل

‏التراجع عن حزمة ‎Compose‎ يُجهَّز قبل النشر لا بعد الحادثة. احتفظ بالصورة السابقة موسومة ومتاحة محليًا: أضف وسمًا صريحًا myapp:stable قبل كل تحديث. للتراجع، أعد الوسم القديم في ملف ‎Compose‎ (أو في ملف .env إن كان الإصدار متغيرًا)، ثم أعد تشغيل docker compose up -d. لا تتأثر وحدات التخزين بتغيير الصورة، مما يجعل التراجع التطبيقي سريعًا؛ أما ترحيل المخطط فيحتاج إلى ترحيل عكسي جاهز قبل النشر. للإصدارات الحرجة، افصل بين docker-compose.yml (النسخة المستقرة) وdocker-compose.override.yml (النسخة المرشحة): الأمر docker compose -f docker-compose.yml up -d يتجاهل ملف التجاوز ويعود إلى الحالة المستقرة.

‏اختبر دائمًا حزمتك المقوَّاة محليًا: docker compose config للتحقق من البنية، ثم محاكاة الإقلاع بـdocker compose restart. تأكد أن الحاويات تعود healthy وأن البيانات تستمر بعد down يعقبه up.

استكشاف الأخطاء: 6 أخطاء شائعة وحلولها

‏docker: unknown command: docker compose: إضافة ‎Compose‎ غير مثبتة. على ‎Ubuntu‎، ثبِّت docker-compose-v2 من الأرشيف، أو docker-compose-plugin إن كان ‎Docker‎ مثبتًا من المستودع الرسمي لـ‎Docker‎، ثم تحقق عبر docker compose version. network not found: بعد docker compose down تُحذف الشبكات المسمَّاة. الحل: أعلن الشبكات المشتركة بـexternal: true أو زامن إعادة تشغيل الحزم التابعة. port is already in use: عملية أخرى تشغل المنفذ. حدِّدها بـss -tlnp | grep :PORT ثم أوقفها. OOM: النواة تقتل حاوية بلا إنذار — ابحث عن OOMKilled: true في docker inspect container_id. ارفع حد الذاكرة أو حدِّد التسريب بـdocker stats. permission denied on volume: العملية تعمل بـUID لا يملك صلاحية الوصول. تحقق من UID بـdocker compose exec service id ثم عدِّل الأذونات. حاوية تُعاد في حلقة: docker compose logs --tail=50 service يكشف خطأ الإقلاع. الأسباب الشائعة: متغير بيئة مفقود، ملف إعداد غير موجود، أو تبعية غير جاهزة.

نسخ الأحجام احتياطيًا دون تلف

‏نسخ ملفات حجم ‎PostgreSQL‎ أو ‎MySQL‎ أثناء تشغيلها بـrsync أو tar ينتج نسخة تالفة. القاعدة: دائمًا pg_dump أو mysqldump قبل لقطة الحجم. أدوات مثل ‎Restic‎ و‎Offen Docker Backup‎ تُنظِّم هذا تلقائيًا.

الخاتمة

‏تحوِّل هذه الإعدادات العشرة ملف ‎Compose‎ تطويريًا إلى حزمة تصمد أمام إعادة التشغيل وذروات الحمل والليالي بلا مراقبة. الفحوصات الصحية، والأسرار المحمَّلة كملفات، والتراجع المجهَّز مسبقًا، والانتقال الكامل إلى docker compose تُكمل هذا الأساس. لا يتطلب شيء من ذلك أداة إضافية: كل شيء في ملفات ‎YAML‎ والسكربتات التي لديك بالفعل. راجع القائمة قبل كل إطلاق، مثلًا عبر مراجعة docker compose config مدمجة في النشر. يمكنك بعدها إضافة وكيل عكسي مثل ‎Traefik‎ أو ‎Caddy‎، أو طبقة تنسيق مثل ‎Coolify‎.

انشر حزمة Compose الخاصة بك في الإنتاج

‏يمنحك خادم ‎VPS ServOrbit‎ صلاحية الجذر والذاكرة والتحكم بالشبكة اللازمة لتشغيل حزمة ‎Docker Compose‎ مقوّاة.