افهم لماذا يساعد Docker الفرق على تشغيل نفس التطبيق بشكل متسق من الحاسوب المحمول إلى السحابة، تبسيط النشر، تحسين قابلية النقل، وتقليل مشاكل البيئة.

معظم مشاكل النشر السحابي تبدأ بمفاجأة مألوفة: التطبيق يعمل على الحاسوب المحمول ثم يفشل عند تشغيله على خادم سحابي. قد يكون الخادم يحتوي على إصدار مختلف من Python أو Node، أو مكتبة نظام مفقودة، أو ملف إعداد مختلف قليلًا، أو خدمة خلفية غير مفعلة. هذه الاختلافات الصغيرة تتراكم، وتنتهي الفرق بقضاء وقت في تصحيح بيئة التشغيل بدلًا من تحسين المنتج.
يساعد Docker عبر تغليف تطبيقك مع وقت التشغيل والاعتمادات التي يحتاجها لتشغيله. بدلًا من إرسال قائمة خطوات مثل "نصّب الإصدار X ثم أضف المكتبة Y ثم اضبط هذا الإعداد"، ترسل صورة حاوية تحتوي بالفعل على هذه القطع.
نموذج ذهني مفيد:
عندما تُشغّل نفس الصورة في السحابة التي اختبرتها محليًا، تقل كثيرًا مشاكل "الخادم مختلف".
Docker يفيد أدوارًا مختلفة لأسباب مختلفة:
Docker مفيد جدًا، لكنه ليس الأداة الوحيدة التي ستحتاجها. لا يزال عليك إدارة التكوين، الأسرار، تخزين البيانات، الشبكات، المراقبة، والقدرة على التوسّع. للعديد من الفرق، Docker هو لبنة بنائية تعمل جنبًا إلى جنب مع أدوات مثل Docker Compose لبيئات التطوير المحلية ومنصات التنسيق في الإنتاج.
فكر في Docker كحاوية شحن لتطبيقك: تجعل عملية التسليم متوقعة. ما يحدث في الميناء (إعداد السحابة وبيئة التشغيل) لا يزال مهمًا — لكن يصبح أسهل بكثير عندما تُعبأ كل الشحنات بنفس الطريقة.
قد تبدو مصطلحات Docker كثيرة، لكن الفكرة الأساسية بسيطة: عبّئ تطبيقك كي يعمل بنفس الطريقة في أي مكان.
الآلة الافتراضية تُجَمِّع نظام تشغيل ضيف كامل بالإضافة إلى تطبيقك. هذا مرن لكن أَثقل في التشغيل وأبطأ في البدء.
الحاوية تُجمّع تطبيقك واعتماده، لكنها تشارك نواة نظام المضيف بدلًا من شحن نظام تشغيل كامل. لذلك، الحاويات عادةً أخف، تبدأ في ثوانٍ، ويمكنك تشغيل الكثير منها على نفس الخادم.
الصورة (Image): قالب للقراءة فقط لتطبيقك. فكر به كأداة مُعبّأة تشمل الكود، وقت التشغيل، مكتبات النظام، والإعدادات الافتراضية.
الحاوية (Container): نسخة تشغيلية من الصورة. إذا كانت الصورة مخططًا، فالحاوية هي البيت الذي تسكنه الآن.
Dockerfile: التعليمات خطوة بخطوة التي يستخدمها Docker لبناء صورة (تثبيت الاعتمادات، نسخ الملفات، تعيين أمر البدء).
السجل (Registry): خدمة تخزين وتوزيع للصور. تُدفع (push) الصور إلى سجل وتُسحب (pull) من الخوادم لاحقًا (سجلات عامة أو خاصة داخل شركتك).
بمجرد تعريف تطبيقك كصورة تُبنى من Dockerfile، تحصل على وحدة توصيل موحّدة. هذا التوحيد يجعل الإصدارات قابلة للتكرار: نفس الصورة التي اختبرتها هي التي تنشرها.
كما يبسط تسليم العمل بين الأشخاص. بدلًا من "يعمل على جهازي"، يمكنك الإشارة إلى وسم صورة محدد في السجل وقول: شغّل هذه الحاوية مع متغيرات البيئة هذه وعلى هذا المنفذ. هذا أساس لبيئات تطوير وإنتاج متناسقة.
أكبر سبب لأهمية Docker في النشر السحابي هو الاتساق. بدلًا من الاعتماد على ما هو مثبت على الحاسوب المحمول، أو على جهاز CI، أو على VM سحابي، تعرف البيئة مرة واحدة (في Dockerfile) وتعيد استخدامها عبر المراحل.
في الممارسة، يظهر الاتساق كالتالي:
هذا الاتساق يوفّر قيمته بسرعة. يمكن إعادة إنتاج خطأ ظهر في الإنتاج محليًا بتشغيل نفس وسم الصورة. وفشل نشر بسبب مكتبة مفقودة يصبح أقل احتمالًا لأن تلك المكتبة ستكون مفقودة في حاوية الاختبار أيضًا.
تحاول الفرق كثيرًا التوحيد عبر مستندات إعداد أو نصوص تهيئة. المشكلة هي الانحراف: الآلات تتغير بمرور الوقت مع التحديثات، وتتكاثر الفروقات تدريجيًا.
مع Docker، تُعامل البيئة كأثر. إذا احتجت لتحديثها، تعيد بناء صورة جديدة وتنشرها — مما يجعل التغييرات صريحة وقابلة للمراجعة. إذا أدت التغييرات لمشاكل، غالبًا ما يكفي نشر الوسم السابق للعودة إلى الوضع المعروف الجيد.
الفائدة الكبرى الأخرى لـ Docker هي قابلية النقل. صورة الحاوية تحول تطبيقك إلى أثر محمول: ابنِه مرة، ثم شغّله في أي مكان يتوفر فيه وقت تشغيل حاويات متوافق.
تُجمّع صورة Docker كود تطبيقك بالإضافة إلى اعتماده (مثلاً Node.js، حزم Python، مكتبات النظام). هذا يعني أن الصورة التي تشغّلها على حاسوبك المحمول يمكن أن تُشغّل أيضًا على:
هذا يقلل القفل لدى البائع على مستوى وقت تشغيل التطبيق. لا تزال قد تستخدم خدمات سحابية أصلية (قواعد بيانات، طوابير، تخزين)، لكن تطبيقك الأساسي لا يضطر لإعادة البناء لمجرّد تغيير المضيف.
تعمل القابلية للنقل بشكل أفضل عندما تُخزن الصور وتُؤرّخ في سجل—عام أو خاص. سير عمل نموذجي:
myapp:1.4.2).السجلات تُسهل أيضًا إعادة الإنتاج وتدقيق النشرات: إذا كان الإنتاج يشغّل 1.4.2، يمكنك سحب نفس الأثر لاحقًا والحصول على نفس البتات.
ترحيل المضيفين: إذا انتقلت من مزود VM إلى آخر، لا تعيد تثبيت البنية. أشِر الخادم الجديد إلى السجل، اسحب الصورة، وابدأ الحاوية بنفس التكوين.
التوسيع: بحاجة لسعة أكبر؟ ابدأ حاويات إضافية من نفس الصورة على خوادم أكثر. لأن كل نسخة متطابقة، يصبح التوسيع عملية قابلة للتكرار بدلًا من مهمة إعداد يدوية.
صورة Docker جيدة ليست مجرد "شيء يعمل". إنها أثر معبأ ومؤرخ يمكنك إعادة بنائه لاحقًا وتثق به. هذا ما يجعل النشرات السحابية متوقعة.
Dockerfile يشرح كيف تُجمع صورة تطبيقك خطوة بخطوة—مثل وصفة بمقادير وتعليمات دقيقة. كل سطر يخلق طبقة، ومعًا يحددون:
حافظ على هذا الملف واضحًا ومقصودًا ليصبح من الأسهل تصحيح الصورة، ومراجعتها، وصيانتها.
الصور الصغيرة تُسحب أسرع، وتبدأ أسرع، وفيها "أشياء" أقل يمكن أن تنهار أو تحتوي ثغرات.
alpine أو نسخ slim) عندما يكون ذلك متوافقًا مع تطبيقك.العديد من التطبيقات تحتاج أدوات ترجمة للبناء، لكنها لا تحتاجها للتشغيل. البناء متعدد المراحل يتيح استخدام مرحلة للبناء وأخرى صغيرة للإنتاج.
# build stage
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# runtime stage
FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
النتيجة صورة إنتاج أصغر وباعتماديات أقل تحتاج للتصحيح.
الوسوم هي كيفية تعريف ما نشرته بالضبط.
latest في الإنتاج؛ إنه غامض.1.4.2) لإصدارات الإطلاق.1.4.2-<sha> أو فقط <sha>) حتى يمكنك دائمًا ربط الصورة بالكود الذي أنتجها.هذا يدعم تراجعات نظيفة وتدقيق واضح عند حدوث تغيّر في السحابة.
التطبيق السحابي "الحقيقي" عادةً ليس عملية واحدة فقط. إنه نظام صغير: واجهة ويب، API، ربما عامل خلفي، بالإضافة إلى قاعدة بيانات أو كاش. Docker يدعم إعدادات بسيطة ومتعددة الخدمات—فقط عليك فهم كيفية تواصل الحاويات، أين يعيش التكوين، وكيف تبقى البيانات بعد إعادة التشغيل.
التطبيق الأحادي قد يكون موقعًا ثابتًا أو API واحدًا لا يعتمد على شيء آخر. تعرض منفذًا واحدًا (مثلاً 8080) وتشغّله.
التطبيقات متعددة الخدمات أكثر شيوعًا: web يعتمد على api، وapi يعتمد على db، وworker يستهلك مهام من قائمة انتظار. بدلًا من تحديد عناوين IP ثابتة، عادةً ما تتواصل الحاويات بأسماء الخدمات على شبكة مشتركة (مثال: db:5432).
Docker Compose خيار عملي للتطوير المحلي والاختبار لأنه يتيح بدء الكومة كاملة بأمر واحد. كما أنه يوثّق "شكل" تطبيقك (الخدمات، المنافذ، الاعتمادات) في ملف يستطيع الفريق مشاركته.
تدرّج نموذجي:
يجب أن تكون الصور قابلة لإعادة الاستخدام وآمنة للمشاركة. احتفظ خارج الصورة بكل ما يخص البيئة:
مرّر هذه عبر متغيرات البيئة، ملف .env (بحذر: لا تدخله في Git)، أو مدير أسرار السحابة.
الحاويات قابلة للاستبدال؛ بياناتك لا يجب أن تكون كذلك. استخدم الـ volumes لأي شيء يجب أن يبقى بعد إعادة التشغيل:
في النشر السحابي، النظير هو التخزين المدار (قواعد بيانات مُدارة، أقراص شبكية، تخزين كائنات). الفكرة الأساسية تبقى: الحاويات تشغّل التطبيق؛ التخزين المستديم يحتفظ بالحالة.
سير النشر الصحي بسيط عن قصد: ابنِ صورة مرة، ثم شغّل تلك الصورة ذاتها في كل مكان. بدلًا من نسخ الملفات إلى الخوادم أو إعادة تشغيل المُثبّتين، تحوّل النشر إلى روتين قابل للتكرار: اسحب الصورة، شغّل الحاوية.
تتبع معظم الفرق خط أنابيب مثل هذا:
myapp:1.8.3).الخطوة الأخيرة هي ما يجعل Docker "مملًا" بطريقة جيدة:
# build locally or in CI
docker build -t registry.example.com/myapp:1.8.3 .
docker push registry.example.com/myapp:1.8.3
# on the server / cloud runner
docker pull registry.example.com/myapp:1.8.3
docker run -d --name myapp -p 80:8080 registry.example.com/myapp:1.8.3
طريقتان شائعتان لتشغيل التطبيقات المحتوية في السحابة:
لتقليل الانقطاعات أثناء النشر، تضيف النشرات عادةً ثلاث ركائز:
السجل أكثر من مجرد مخزن—إنه كيف تحافظ على اتساق البيئات. ممارسة شائعة هي ترقية نفس الصورة من dev → staging → prod (غالبًا عبر إعادة وسمها)، بدلًا من إعادة بنائها في كل مرة. بهذه الطريقة، يعمل الإنتاج على نفس الأثر الذي اختبرته، مما يقلل مفاجآت "عمل في الاختبار".
CI/CD هو خط التجميع لشحن البرمجيات. يجعل Docker خط التجميع أكثر توقعًا لأن كل خطوة تعمل في بيئة معروفة.
خط أنابيب صديق لـ Docker عادةً ما يتضمن ثلاث مراحل:
myapp:1.8.3).هذا التدفق سهل أيضًا شرحه لغير الفنيين: "نبني صندوقًا مؤمنًا واحدًا، نختبر الصندوق، ثم نرسل نفس الصندوق لكل بيئة."
غالبًا ما تنجح الاختبارات محليًا وتفشل في الإنتاج بسبب اختلاف وقت التشغيل، مكتبات نظام مفقودة، أو متغيرات بيئة مختلفة. تشغيل الاختبارات داخل الحاويات يقلل هذه الفجوات. مشغّل CI لا يحتاج آلة مضبوطة بعناية—يكفي Docker.
يدعم Docker مبدأ "رُقِّ ولا تُعد بناؤه":
myapp:1.8.3 مرة واحدة.فقط التكوين يتغير بين البيئات (كالروابط أو بيانات الاعتماد)، وليس أثر التطبيق. هذا يقلل عدم اليقين يوم النشر ويجعل التراجع بسيطًا: أعد نشر وسم الصورة السابق.
إذا كنتم تتقدّمون بسرعة وتريدون فوائد Docker دون قضاء أيام على الإعداد، يمكن أن يساعدكم Koder.ai في توليد تطبيق مهيأ للإنتاج من تدفق عمل محادثي ثم حزمته في حاوية نظيفة.
فرق تستخدم Koder.ai عادةً لـ:
docker-compose.yml مبكرًا (حتى يبقى سلوك التطوير والإنتاج متسقًا),الميزة الأساسية هي أن Docker يبقى عنصر النشر الأساسي، بينما Koder.ai يسرّع المسار من الفكرة إلى قاعدة كود جاهزة للحاوية.
Docker يسهل تجميع وتشغيل خدمة على جهاز واحد. لكن عند وجود خدمات متعددة وعدد نسخ لكل خدمة وخوادم متعددة، تحتاج نظامًا لإبقاء كل شيء منسقًا. هذا ما يفعله التنسيق: يقرر أين تُشغّل الحاويات، يحافظ على صحتها، ويضبط السعة حسب الطلب.
مع عدد صغير من الحاويات يمكنك تشغيلها يدويًا وإعادة تشغيلها عند تعطلها. عند نطاق أكبر، هذا يصبح غير عملي:
Kubernetes (غالبًا "K8s") هو المنسق الأكثر شيوعًا. نموذج ذهني بسيط:
Kubernetes لا يبني الحاويات؛ هو يشغّلها. ما زلت تبني صورة Docker، تدفعها إلى سجل، ثم يسحبها Kubernetes على العقد ويشغّل الحاويات منها. تظل صورتك الأثر المحمول والمؤرخ المستخدم في كل مكان.
إذا كنت على خادم واحد مع عدد قليل من الخدمات، قد يكفي Docker Compose. يبدأ فائدة التنسيق عندما تحتاج توافرًا عاليًا، نشرات متكررة، موازنة تلقائية، أو خوادم متعددة للسعة والمرونة.
الحاويات لا تجعل التطبيق آمنًا تلقائيًا—لكنها تجعل من السهل توحيد وأتمتة أعمال الأمن التي يجب أن تقوم بها مسبقًا. الجانب الإيجابي هو أن Docker يوفر نقاطًا قابلة للتكرار لإضافة ضوابط تهم المراجعين وفرق الأمن.
صورة الحاوية هي حزمة لتطبيقك بالإضافة إلى اعتماده، لذلك غالبًا ما تأتي الثغرات من الصور الأساسية أو حزم النظام التي لم تكتبها. فحص الصور يبحث عن CVE معروفة قبل النشر.
اجعل الفحص بوابة في خط الأنابيب: إذا وُجدت ثغرة حرجة، افشل البناء وأعد بناء الصورة بصورة أساسية مُلَحَّقة. احتفظ بنتائج الفحص كآثار لتستطيع عرض ما شحنته لمراجعات الامتثال.
شغّل الحاوية بمستخدم غير جذر كلما أمكن. تعتمد العديد من الهجمات على الوصول كجذر داخل الحاوية للخروج أو العبث بنظام الملفات.
فكّر أيضًا في نظام ملفات قابل للقراءة فقط للحاوية وتركيب مسارات قابلة للكتابة فقط للمسارات الضرورية (سجلات أو رفعات). هذا يقلل ما يمكن للمهاجم تغييره إذا نجح في الوصول.
لا تنسخ مفاتيح API أو كلمات المرور أو الشهادات الخاصة إلى صورتك أو تلتزم بها في Git. الصور تُخزن مؤقتًا وتُشارك وتُدفع إلى سجلات — الأسرار قد تتسرب على نطاق واسع.
بدلًا من ذلك، أدخل الأسرار وقت التشغيل باستخدام مخزن أسرار المنصة (مثل Kubernetes Secrets أو مدير أسرار السحابة)، وقيّد الوصول فقط إلى الخدمات التي تحتاجها.
على عكس الخوادم التقليدية، الحاويات لا تُصحَّح ذاتيًا أثناء التشغيل. النهج المعياري هو: أعد بناء الصورة مع الاعتمادات المحدثة ثم أعد النشر.
حدّد وتيرة (أسبوعية أو شهرية) لإعادة البناء حتى عندما لم يتغير كود التطبيق، وأعد البناء فورًا عند ظهور CVE شديدة التأثير في الصورة الأساسية. هذه العادة تُبقي النشرات أسهل للمراجعة وأقل خطورة مع الوقت.
حتى الفرق التي "تستخدم Docker" قد تُطلق نشرات سحابية غير موثوقة إذا تسللت بعض العادات السيئة. هذه الأخطاء تسبب أكبر قدر من الألم—وصُنع حلول عملية لتجنبها.
نمط معاكس شائع هو "SSH إلى الخادم وعدّل شيئًا"، أو exec إلى حاوية قيد التشغيل لإصلاح إعداد سريع. يعمل ذلك لمرة واحدة، ثم يفشل لاحقًا لأن لا أحد يستطيع إعادة إنشاء الحالة بالضبط.
بدلًا من ذلك، عامل الحاويات كقطع ماشية: قابلة للاستبدال. اجعل كل تغيير يمر عبر بناء الصورة وأنابيب النشر. إذا احتجت للتصحيح، افعل ذلك في بيئة مؤقتة ثم صِف الإصلاح في Dockerfile أو التكوين أو الإعدادات البنية التحتية.
الصور الضخمة تبطئ CI/CD، تزيد تكاليف التخزين، وتوسّع سطح الهجوم الأمني.
تجنّب ذلك عبر تحسين هيكل Dockerfile:
.dockerignore حتى لا تُشحن node_modules أو آثار البناء أو الأسرار المحلية.الهدف هو بناء قابل للتكرار وسريع—حتى على آلة نظيفة.
الحاويات لا تلغي الحاجة لفهم ما يفعله تطبيقك. بدون سجلات ومقاييس وتتبع، لن تلاحظ المشاكل إلا عندما يشكو المستخدمون.
على الأقل، اجعل التطبيق يكتب السجلات إلى stdout/stderr (لا إلى ملفات محلية)، أضف نقاط صحة أساسية، وانشر بعض المقاييس الرئيسية (معدل الأخطاء، الكمون، عمق قوائم الانتظار). ثم اربط هذه الإشارات بأدوات المراقبة في الستاك السحابي لديك.
الحاويات عديمة الحالة سهلة الاستبدال؛ البيانات الحالة لا. كثيرًا ما تكتشف الفرق متأخرًا أن قاعدة بيانات داخل حاوية "عملت جيدًا" حتى مسح إعادة التشغيل البيانات.
قرِّر مبكرًا أين تعيش الحالة:
Docker ممتاز لتغليف التطبيقات—لكن الاعتمادية تأتي من التفكير المتعمد في كيفية بناء تلك الحاويات ومراقبتها وربطها بتخزين دائم.
إذا كنت جديدًا على Docker، أسرع طريقة للحصول على قيمة هي تغليف خدمة حقيقية واحدة من البداية للنهاية: ابنِها، شغّلها محليًا، ادفعها إلى سجل، وانشرها. استخدم هذه القائمة للحفاظ على نطاق صغير ونتائج قابلة للاستخدام.
اختر خدمة بسيطة وعديمة الحالة أولًا (API، عامل، أو تطبيق ويب بسيط). حدّد ما تحتاجه للبدء: المنفذ الذي يستمع عليه، متغيرات البيئة المطلوبة، وأية اعتمادات خارجية (مثل قاعدة بيانات يمكنك تشغيلها بشكل منفصل).
احتفظ بالهدف واضحًا: "أستطيع تشغيل نفس التطبيق محليًا وفي السحابة من نفس الصورة."
اكتب أصغر Dockerfile يمكنه بناء وتشغيل تطبيقك بثبات. فضّل:
ثم أضف docker-compose.yml للتطوير المحلي الذي يوصل متغيرات البيئة والاعتمادات دون تثبيت أي شيء على حاسوبك الشخصي ما عدا Docker.
يمكنك توسيع هذا لاحقًا—ابدأ بسيطًا.
قرّر أين ستعيش الصور (Docker Hub، GHCR، ECR، GCR، إلخ). ثم اعتمد وسومًا تجعل النشر متوقعًا:
:dev للاختبار المحلي (اختياري):git-sha (غير قابل للتغيير، الأفضل للنشر):v1.2.3 للإصداراتتجنّب الاعتماد على :latest للإنتاج.
أضف CI بحيث كل دمج إلى الفرع الرئيسي يبني الصورة ويدفعها إلى السجل تلقائيًا. يجب أن يقوم خط الأنابيب ب:
بعد عمل ذلك، ستكون جاهزًا لربط الصورة المنشورة بخطوة نشر السحابة والتكرار من هناك.
Docker يقلل مشاكل «يعمل على جهازي» عن طريق تغليف تطبيقك مع وقت التشغيل والاعتمادات التي يحتاجها داخل صورة. ثم تقوم بتشغيل نفس الصورة محليًا، في CI، وفي السحابة، فيصبح اختلاف إصدارات النظام، وإصدارات اللغات، والمكتبات المثبتة لا يغيّر سلوك التطبيق بصمت.
عادةً ما تبني الصورة مرة واحدة (مثل myapp:1.8.3) وتشغّل عدة حاويات منها عبر البيئات.
الآلة الافتراضية (VM) تتضمّن نظام تشغيل ضيف كامل، لذا تكون أثقل وعادةً أبطأ في البدء. الحاوية تشارك نواة نظام المضيف وتشتمل فقط ما يحتاجه التطبيق (وقت التشغيل + المكتبات)، فبالتالي تكون عادةً:
السجل (Registry) هو المكان الذي تُخزن فيه الصور وتُؤرّخ حتى تتمكّن الآلات الأخرى من سحبها.
سير العمل الشائع:
docker build -t myapp:1.8.3 .docker push <registry>/myapp:1.8.3هذا يسهل أيضًا عمليات التراجع: أعد نشر وسم سابق.
استخدم وسومًا غير قابلة للتغيير وسهلة التتبع حتى تعرف دائمًا ما الذي يعمل.
النهج العملي:
:1.8.3:<git-sha>:latest في الإنتاج (غامض)هذا يدعم تراجعات واضحة وسجلات تدقيق مرتبة.
احتفظ بالإعدادات الخاصة بالبيئة خارج الصورة. لا تدمج مفاتيح API أو كلمات المرور أو الشهادات الخاصة في Dockerfile.
بدائل آمنة:
.env إلى Gitهذا يجعل الصور قابلة لإعادة الاستخدام ويقلل من تسرب الأسرار.
الحاويات قابلة للاستبدال؛ نظام الملفات بداخلها قد يُستبدل عند إعادة التشغيل أو النشر.
استخدم:
قاعدة عامة: شغّل التطبيقات في حاويات، وخزن الحالة في مخازن مخصّصة.
Compose مناسب عندما تريد تعريفًا بسيطًا ومتشاركًا لعدة خدمات على مضيف واحد أو للتطوير المحلي:
db:5432)للحاجة إلى توافر عالي، autoscaling، أو تشغيل عبر عدة خوادم في الإنتاج، عادةً ما تضيف مُنسّقًا مثل Kubernetes.
أنابيب عملية مبسطة هي build → test → publish → deploy:
فضّل «الترقية عبر الترويج وليس إعادة البناء» (dev → staging → prod) حتى يبقى الأثر واحدًا.
الأسباب الشائعة لفشل حاوية في السحابة رغم عملها محليًا:
-p 80:8080).للتصحيح، شغّل الوسم الإنتاجي نفسه محليًا وقارن الإعدادات أولًا.