Bugsy
كل الشروحات

Bugsy يشرح

ما هو Docker؟

لماذا لم تعد عبارة «يعمل على جهازي» عذرًا: الصور والحاويات، وكيف تختلف عن الآلات الافتراضية، ولماذا يجعل ترتيبُ ملف Dockerfile البناءَ سريعًا.

8 دقائق 3 ألعاب

  • الحاويات
  • DevOps
  • الأدوات

«يعمل على جهازي». سمع كل فريق هذه العبارة. التطبيق يعمل على حاسوبك، ثم ينهار على حاسوب زميلك أو على الخادم. الشيفرة نفسها والنتيجة مختلفة. كيف؟

لأن الشيفرة ليست إلا جزءًا مما يعمل. لحاسوبك نظام تشغيل خاص به، وإصدار خاص من Node.js، ومكتبات نظام (system libraries) خاصة به. وقد يكون على الخادم Node 18 بينما عندك Node 22، أو تنقصه مكتبة ثبّتّها قبل أشهر ونسيت أمرها.

يحلّ Docker هذه المشكلة بأن يشحن التطبيق مع كل ما يحتاجه ليعمل: بيئة التشغيل (runtime) والمكتبات والملفات وأمر البدء. فيعمل التطبيق على كل جهاز فيه Docker بالملفات والمكتبات نفسها تمامًا. ولا يبقى مختلفًا إلا إصدار النواة (kernel) في الجهاز المضيف ونوع المعالج (Apple Silicon أو Intel مثلًا)، ولهذا تأتي صور كثيرة بنسخة لكل نوع من المعالجات.

الصور والحاويات

اسم هذه الحزمة صورة (image). وهي قالب للقراءة فقط، مبني من طبقات (layers) فوق بعضها: نظام أساسي، ثم Node.js، ثم التبعيات (dependencies)، ثم شيفرتك.

أما الحاوية (container) فهي نسخة عاملة من الصورة. يضيف Docker فوقها طبقة رقيقة قابلة للكتابة، خاصة بتلك الحاوية وحدها. كل ما يكتبه التطبيق، مثل ملف سجلّ أو ملف رفعه مستخدم، يُحفظ في تلك الطبقة. والصورة تحتها لا تتغيّر أبدًا.

إذن يمكن لصورة واحدة أن تشغّل حاويات كثيرة، ولكل حاوية طبقتها الخاصة القابلة للكتابة. شغّل بضع حاويات، واكتب ملفًا في أحدثها، ثم أوقفها.

جرّب

اختبار سريع

أليست هذه مجرد آلة افتراضية؟

ليس تمامًا. الآلة الافتراضية (virtual machine أو VM) تتظاهر بأنها حاسوب كامل. برنامج اسمه مدير الآلات الافتراضية (hypervisor) يحاكي العتاد، وكل آلة افتراضية تُقلع نظام تشغيل ضيفًا (guest OS) كاملًا له نواته الخاصة (kernel)، والنواة هي قلب نظام التشغيل الذي يتعامل مع العتاد.

الحاويات تتخطى ذلك كله. إنها عمليات (processes) عادية على الجهاز المضيف (host)، وكلها تتشارك نواته. ويفصل Linux بينها بميزتين: مساحات الأسماء (namespaces) تحدد ما تراه العملية (ملفاتها وقائمة عملياتها وشبكتها الخاصة)، ومجموعات التحكم (cgroups) تحدّ مما تستهلكه من المعالج والذاكرة.

ولأنه لا يوجد نظام ضيف يُقلع، فحجم الحاوية ميغابايتات لا غيغابايتات، وتبدأ في ثانية أو أقل، بدل عشرات الثواني إلى دقيقة.

جرّب

ملف Dockerfile وذاكرة البناء المؤقتة

تصف الصورة في ملف اسمه Dockerfile، تعليمة واحدة في كل سطر. والأمر docker build ينفّذها من الأعلى إلى الأسفل. والتعليمات RUN وCOPY وADD تضيف كلٌّ منها طبقة من الملفات. أما غيرها، مثل WORKDIR وCMD، فتسجّل إعدادات فقط، لذا لا تكاد تكلّف شيئًا حين تُعاد.

يحفظ Docker كل خطوة في ذاكرة مؤقتة (cache). وفي البناء التالي يعيد استخدام الخطوات المحفوظة حتى يصل إلى أول خطوة تغيّرت مُدخلاتها: ملفات مختلفة في COPY، أو أمر مختلف في RUN. تلك الخطوة وكل خطوة بعدها تُنفَّذ من جديد.

لهذا ننسخ في ملف Dockerfile التالي package.json وملف القفل (lock file) ونشغّل npm ci قبل نسخ بقية الشيفرة. فأنت تغيّر الشيفرة طوال الوقت، والتبعيات نادرًا، فيأتي التثبيت البطيء غالبًا من الذاكرة المؤقتة مباشرة. جرّب كل تغيير.

جرّب

اختبار سريع

الأوامر التي ستكتبها

أربعة أوامر تكفيك في معظم الأيام: ابنِ صورة، وشغّلها، وانظر ما الذي يعمل، ثم أوقفه.

docker build -t bugsy-app:1.0 .docker run -d -p 8080:3000 bugsy-app:1.0docker psdocker stop <id>

الخيار -t يسمّي الصورة، والنقطة . في الآخر ترسل المجلد الحالي إلى البناء. والخيار -p 8080:3000 يربط المنفذ (port) 8080 على جهازك (الرقم الأيسر) بالمنفذ 3000 داخل الحاوية (الرقم الأيمن). والخيار -d يشغّل الحاوية في الخلفية، فيعمل docker ps في الطرفية (terminal) نفسها ويعرض الحاويات العاملة مع معرّفاتها.

للحاوية شبكتها الخاصة، فمن دون -p لا يصل شيء من خارج Docker إلى التطبيق. ومعه، حين تفتح localhost:8080 على جهازك تصل إلى التطبيق في الداخل على المنفذ 3000. ويجب أن يستمع التطبيق على 0.0.0.0 لا على localhost، وإلا فلن يقبل إلا الاتصالات القادمة من داخل حاويته.

تُتبادل الصور عبر مستودع صور (registry)، وهو خادم يخزّنها. وDocker Hub هو المستودع الافتراضي: الأمر docker pull node:22-slim ينزّل منه صورة. ولترفع صورتك، سمِّها باسم حسابك وسجّل الدخول بالأمر docker login، ثم نفّذ docker push yourname/bugsy-app:1.0، فيستطيع زميل أو خادم تشغيل الصورة نفسها التي بنيتها بالضبط.

سؤال الزعيم

اجمع كل ما تعلّمته.

اختبار سريع

انتهيت من القراءة؟

حلّ 3 اختبارات سريعة بعد لتنهي.