مقدمة عن الـ Docker
السلام عليكم ورحمة الله وبركاته
يمكنك متابعة السلسلة بالترتيب أو الانتقال مباشرة إلى أي مقال:
المقدمة
لنبدأ رحلة جديدة في المحيط ونرسي سفينتنا المليئة بالحاويات في ميناء مدونة الطبراني الجميلة
حسنًا لنبدأ سلسلة جديدة من المقالات عن الـ Docker، الأداة التي غيرت العالم وسهلت عمليات التطوير بشتى أنواعها
في هذه السلسلة سنبدأ من الأساسيات، نشرح ما هو الـ Docker، وكيف كان العالم قبل وجوده، وما المشاكل التي يحلها، ثم ننتقل إلى شرح عملي لكيفية استخدامه في مشاريعنا اليومية، مع أمثلة عملية بسيطة ومفهومة للجميع
بالطبع هذه المقالة ستكون مقدمة تعريفية عن الـ Docker
لذا لنبدأ بأول سؤال لدينا وهو كيف كان العالم قبل وجود الـ Docker؟
العالم قبل الـ Docker
قبل أي شيء عليك أن تعلم أن الـ Docker لم تخترع الذرة وما تفعله ليس جديدًا كليًا، بل هي فقط سهلت وبسطت عملية كانت معقدة وصعبة في السابق
المشكلة الأساسية التي كان يواجهها المطورون هي تجهيز البيئة التي سينفذ فيها التطبيق
بمعنى أنه لو لديك تطبيق لموقع معين
والموقع يقوم باستخدام PHP إصدار 8.2، و MySQL إصدار 8.0، و Redis إصدار 7.0 وبعض المكتبات الأخرى
هنا تحتاج من كل شخص يريد تشغيل هذا التطبيق أن يقوم بتجهيز بيئة مشابهة على جهازه الشخصي
وأيضًا في حالة الـ Deployment وتشغيل التطبيق على Server تحتاج إلى تجهيز نفس البيئة هناك أيضًا
أي شخص يريد تشغيل التطبيق عليه أن يقوم بتثبيت نفس الإصدارات من البرامج والمكتبات التي يعتمد عليها التطبيق
بدون أي خطأ في التثبيت أو اختلاف في الإصدارات لكي يعمل التطبيق بشكل صحيح
نفس الأمر الـ Server
الأمر قديمًا كان يتم بشكل يدوي
وكل شخص قد يواجه مشاكل مختلفة في التثبيت أو الإعدادات بسبب اختلافات في أنظمة التشغيل سواء كانت Windows، MacOS، أو Linux
أو حتى اختلافات في توزيعات Linux نفسها
مثل Ubuntu، Debian، CentOS، وغيرها
كل هذه الاختلافات كانت تسبب مشاكل كبيرة جدًا في تجهيز بيئة لكي نستطيع تشغيل تطبيقنا بشكل صحيح
المشكلة الأخرى هي في حالة أننا قررنا تحديث إصدار أحد البرامج التي يعتمد عليها التطبيق
مثلًا تحديث MySQL من إصدار 8.0 إلى 8.1
أو تحديث PHP من إصدار 8.2 إلى 8.3
هنا علينا التأكد أن جميع الذين يعملون على التطبيق قاموا بتحديث بيئاتهم أيضًا بنفس الطريقة
وعلينا أن نحدث الـ Server أيضًا بنفس الطريقة
وكل هذا كان يتم يدويًا وبصعوبة بالغة بحسب كل نظام تشغيل وكل شخص
وتخيل لو لدينا أكثر من Server بحيث لدينا Server للـ Development وآخر للـ Testing وآخر للـ Production
علينا تجهيز نفس البيئة على كل هذه الـ Servers
وأي تعديل على الإصدارات وأننا اعتمدنا على مكتبة جديدة أو أداة جديدة
علينا تحديث كل هذه الـ Servers بنفس الطريقة يدويًا
لاحظ أن مشكلتنا الأساسية هنا هي في تجهيز البيئة التي سيعمل فيها التطبيق
والتجهيز يكون بشكل يدوي دون خطأ
وقد يختلف تجهيز وتثبيت البرامج والمكتبات بين جهاز وآخر وبين نظام تشغيل وآخر
كل هذه العوامل تجعل من عملية تشغيل التطبيقات أمرًا صعبًا ومعقدًا جدًا
وقد يأخذ وقتًا طويلًا جدًا في التجهيز والتثبيت
بمجرد أننا نريد فقط تشغيل التطبيق لا أكثر حتى ولو على جهازنا الشخصي
المشكلة الأخرى في حالة أنني لدي تطبيق طورته بـ PHP إصدار 7.4
وصديقي أرسل لي تطبيق طوره بـ PHP إصدار 8.2
هنا لا يمكنني تشغيل تطبيقه على جهازي الذي يحتوي على PHP إصدار 7.4
وحتى لو قمت بتثبيت PHP إصدار 8.2 على جهازي
قد يؤثر ذلك على تطبيقاتي الأخرى التي تعتمد على PHP إصدار 7.4
وهنا تبدأ المشاكل في تعارض الإصدارات بين التطبيقات المختلفة على نفس الجهاز
الحل باستخدام الـ Virtual Machine
الآن بعد أن فهمنا المشاكل التي كانت تواجهنا قبل وجود الـ Docker
دعنا نوضح نقطة أن هذه المشاكل التي عرضناها كانت تُحل في السابق باستخدام الـ Virtual Machines
وهي عن طريق أننا نقوم بإنشاء جهاز وهمي كامل على جهازنا الشخصي
ونثبت عليه نظام تشغيل كامل مثل Linux أو Windows
ثم نقوم بتثبيت جميع البرامج والمكتبات التي يحتاجها التطبيق على هذا الجهاز الوهمي
وبهذا نضمن أن التطبيق سيعمل في بيئة معزولة تمامًا عن جهازنا الشخصي
هذا الحل جيد جدًا ويقدم عزلًا كاملًا للتطبيق عن جهازنا الشخصي
لكنه كان يعاني من عدة مشاكل
أولها أننا ما زلنا نعاني من مشكلة تجهيز البيئة بشكل يدوي
لأننا عندما ننشئ Virtual Machine جديدة نحتاج إلى القيام بنفس الخطوات يدويًا لكي نجهز البيئة ونثبت البرامج والمكتبات التي يحتاجها التطبيق
المشكلة الثانية كانت في الأداء والموارد التي يحتاجها الـ Virtual Machine
بحيث أن الـ Virtual Machines تأخذ مساحة وموارد كبيرة من جهازنا الشخصي
لأننا عندما ننشئ Virtual Machine داخل جهازنا الشخصي
فنحن نقوم بتثبيت نظام تشغيل كامل سواء كان Linux أو Windows بكل ما فيه من برامج وخدمات سواء
- خدمات الـ
GUIأوDesktop Environment - خدمات الـ
USBوالـAudio/VideoوالـBluetoothوPower Managementوغيرها من الخدمات التي تكون موجودة في الـOperating System - تطبيقات افتراضية تأتي مع الـ
Operating SystemمثلFile Manager،Web Browser،Calculator، وغيرها - ... والعديد من البرامج والخدمات الأخرى
كل هذا يتم تثبيته على الـ Virtual Machine
بمجرد أننا نريد فقط تشغيل تطبيق معين
وتطبيقنا لا يحتاج إلى كل هذه البرامج والخدمات التي تكون موجودة في الـ Operating System
بمعنى تخيل لو كانت مساحة جهازك الشخصي هي 500GB
ولدينا ثلاث تطبيقات نريد تشغيلها وكل تطبيق يحتاج إلى Virtual Machine خاصة به
لنفترض أن كل تطبيق يحتاج إلى 5GB
هنا سننشئ ثلاث Virtual Machines على جهازنا الشخصي
تخيل أن مساحة كل Virtual Machine قد تصل من 50GB إلى 100GB بحسب نوع الـ Operating System الذي سنثبت عليه
ولأن كل Virtual Machine تحتاج إلى نظام تشغيل كامل عليه بكل ما فيه من برامج وخدمات
كأنك تنسخ الـ Operating System الخاص بجهازك الشخصي ثلاث مرات فكل Virtual Machine ستكون نسخة كاملة من الـ Operating System وتأخذ مساحة وموارد كبيرة من جهازك الشخصي
الآن فرضنا أن مساحة كل تطبيق هي 5GB ومساحة كل Virtual Machine هي 50GB
هكذا كل تطبيق سيحتاج إلى 55GB من المساحة على جهازنا الشخصي
بالتالي فإن تشغيل الثلاث تطبيقات سيكلفنا 165GB من المساحة على جهازنا الشخصي
ونحن في الأصل نحتاج فقط إلى 15GB لتشغيل التطبيقات الثلاثة
ولوافترضنا أننا نحتاج لمساحة احتياطية تقدر بـ 10GB لكل تطبيق
فهذا يعني أن الناتج النهائي سيكون 195GB من المساحة على جهازنا الشخصي
وهو رقم كبير جدًا مقارنة بالمساحة التي نحتاجها في الأصل لتشغيل التطبيقات وهي 15GB فقط
بالتالي لقد ضاع منا حوالي 180GB من المساحة على جهازنا الشخصي فقط بسبب أننا نستخدم الـ Virtual Machines كحل لتشغيل التطبيقات بشكل معزول
بالطبع هذه الأرقام تقريبية فقط لنحاول توضيح وتقريب الفكرة لا أكثر
المشكلة الأساسية ليست في الـ Virtual Machine كمفهوم بحد ذاته
بل المشكلة تكمن في أننا نقوم بتشغيل نظام تشغيل كامل على جهازنا الشخصي
بكل ما فيه من برامج وخدمات سواء GUI أو خدمات الـ USB والـ Audio/Video وغيرها من الخدمات والتطبيقات التي ذكرناها سابقًا
والتي لا نحتاجها لكي نشغل ونجهز بيئة التطبيق الذي نريد تشغيله
وكل هذا بمجرد أننا نريد فقط تشغيل تطبيق معين حجم قد لا يتجاوز الـ 5GB أو 10GB في بعض الأحيان
بالتالي لو وجدنا طريقة للتخلص من هذه البرامج والخدمات غير الضرورية التي تكون موجودة في الـ Operating System
بمعنى أننا نريد تثبيت فقط الـ Operating System بدون أي برامج أو خدمات إضافية
وكل هذا فقط حتى نستطيع أن نوفر بيئة تشغيل للتطبيق وبشكل معزول عن جهازنا الأساسي
مفهوم الـ Containerization
هنا ظهر مفهوم الـ Containerization كحل لهذه المشكلة
مفهوم الـ Containerization يعتمد على فكرة الـ Containers
والـ Container هو بيئة تشغيل معزولة للتطبيق يشبه الـ Virtual Machine
لكن الفرق الأساسي هو أن الـ Container لا يحتاج إلى تثبيت نظام تشغيل كامل عليه
هو فقط يحتاج لتثبيت الـ Operating System الأساسي كبرنامج خام بدون أي برامج أو خدمات إضافية
بمعنى أن الـ Container يستخدم نواة نظام التشغيل Kernel الموجودة على جهازك الأساسي
ولا يحتاج إلى تثبيت نواة جديدة أو نظام تشغيل كامل مثل الـ Virtual Machine
والـ Kernel هو الجزء الأساسي في نظام التشغيل الذي يتعامل مع الـ Hardware ويقوم بإدارة الموارد مثل الـ RAM، الـ CPU، والـ Storage بغض النظر عن نوع نظام التشغيل
بمعنى لو كنت تستخدم Windows أو MacOS أو Linux على جهازك الشخصي
فالـ Container سيستخدم نفس الـ Kernel الخاص بجهازك الشخصي
ويقوم بتشغيل التطبيق داخل بيئة معزولة باستخدام هذا الـ Kernel كأنه برنامج مثل أي برنامج آخر يعمل على جهازك الشخصي
هذا يعني أن الـ Container يأخذ مساحة أقل بكثير من الـ Virtual Machine
ويستهلك موارد أقل من حيث الـ RAM والـ CPU
لأنه لا يحتاج إلى تشغيل نظام تشغيل كامل بكل خدماته وبرامجه بل هو يعتمد على الـ Kernel الخاص بجهازك الشخصي
بالعودة إلى المثال السابق حيث لدينا ثلاث تطبيقات نريد تشغيلها
كل تطبيق يحتاج إلى 5GB من المساحة
باستخدام الـ Containers لن نحتاج إلى تخصيص 50GB لكل تطبيق كما في حالة الـ Virtual Machine
لأننا لن نقوم بتثبيت نظام تشغيل كامل على كل Container
نحن فقط سنثبت الـ Operating System الأساسي كبرنامج خام بدون أي برامج أو خدمات إضافية
والذي يصل حجمه من 1MB إلى أقل من 1GB بحسب نوع الـ Operating System الذي سنستخدمه
فعلى سبيل المثال لو استخدمنا Alpine Linux كنظام تشغيل أساسي للـ Container
فإن حجمه سيكون حوالي 10MB فقط
بالتالي لو لدينا ثلاث تطبيقات كل تطبيق يحتاج إلى 5GB من المساحة
باستخدام الـ Containers سنحتاج فقط إلى حوالي 15GB لتشغيل التطبيقات الثلاثة
ولن نحتاج إلى تخصيص 150GB كما في حالة الـ Virtual Machines
هذه أحد الفوائد الكبيرة للـ Containers مقارنة بالـ Virtual Machines
أنه يأخذ مساحة وموارد أقل بكثير
ومثل الـ Virtual Machines، الـ Containers توفر عزل كامل للتطبيق عن جهازنا الشخصي
بالتالي ما يحدث في الـ Container لن يؤثر على جهازنا الشخصي
والـ Container لا يهتم بنوع الـ Operating System الذي يعمل عليه جهازنا الشخصي
سواء كان Windows، MacOS، أو Linux
تخيله كبرنامج مستقل بذاته يعمل على جهازك الشخصي
وهذا البرنامج المنعزل قام بتشغيل Linux كنظام تشغيل أساسي بدون أي برامج أو خدمات إضافية
ثم قام بتشغيل تطبيقك داخل هذا النظام المعزول
وكل هذا في مساحة وموارد أقل بكثير من الـ Virtual Machine
تلخيص للمشاكل قبل وجود الـ Docker
نستطيع تلخيص كل المشاكل التي كنا نواجهها قبل وجود الـ Docker في النقاط التالية:
- تجهيز البيئة التي سيعمل فيها التطبيق بشكل يدوي
- اختلاف الـ
Operating Systemبين المطورين وأجهزة الـServerوأنواع توزيعاتها وإصداراتها المختلفة - تحديث وتغير الإصدارات والمكتبات التي يعتمد عليها التطبيق بشكل يدوي
- تعارض الإصدارات بين التطبيقات المختلفة على نفس الجهاز، في حالة وجود أكثر من تطبيق يستخدم إصدارات مختلفة من نفس البرنامج
- استهلاك موارد كبيرة من الجهاز عند استخدام الـ
Virtual Machinesكحل لهذه المشاكل - صعوبة في عملية الـ
Deploymentوالتشغيل على أكثر منServerلأنها تحتاج إلى تجهيز يدوي لكلServerحيث أنه قد يختلف منServerلآخر - ... ومشاكل أخرى
وقلنا أن الـ Container استطاع أن يحل مشكلة استهلاك الموارد والمساحة بشكل كبير مقارنة بالـ Virtual Machines
لكن يظل هناك العديد من المشاكل التي لم تُحل بعد مثل تجهيز البيئة بشكل يدوي، واختلاف أنظمة التشغيل، وتحديث الإصدارات بشكل يدوي، وتعارض الإصدارات، وصعوبة عملية الـ Deployment
الآن السؤال هو كيف يمكننا إنشاء وإدارة الـ Container بسهولة؟
هنا يأتي دور الـ Docker التي سهلت وبسطت عملية إنشاء وإدارة الـ Containers بشكل كبير جدًا
والعمليات والتجهيزات التي كنا نقوم بها يدويًا أصبحت الآن تتم بشكل آلي وسهل جدًا باستخدام الـ Docker
ما هو الـ Docker ؟
الآن بعد أن فهمنا مفهوم الـ Container
دعنا نتعرف على الـ Docker
الـ Docker هو برنامج مفتوح المصدر لإنشاء وإدارة وتشغيل الـ Containers
بمعنى أن الـ Docker يوفر لنا مجموعة من الأدوات والتقنيات التي تسهل علينا إنشاء Containers وإدارتها وتشغيلها
بمعنى أنها لم تخترع مفهوم الـ Containerization بل هي استطاعت أتمتة وتبسيط عملية إنشاء وإدارة الـ Containers
وجعلها في متناول الجميع
قبل الـ Docker كان استخدام الـ Containers معقدًا جدًا ويحتاج إلى معرفة عميقة بنظام التشغيل وكانت مخصصة لأشخاص معينين فقط لديهم خبرة كبيرة في هذا المجال
لكن الـ Docker قدم واجهة بسيطة وسهلة الاستخدام لإنشاء وإدارة الـ Containers وجعلها متاحة لجميع المطورين بغض النظر عن خبرتهم في هذا المجال
ملحوظة: كلمةDockerتعني عامل الميناء الذي يقوم بتحميل وتفريغ البضائع من السفن
وكلمةDockتعني رصيف الميناء الذي ترسو عليه السفن
والـContainerتعني الحاوية التي تستخدم لنقل البضائع
يمكننا استخدام هذا التشبيه لفهم دور الـ Docker في عالم البرمجة
بحيث أن الحاويات تكون معزولة تمامًا عن بعضها البعض
ونحن نستطيع أن نرسل الحاويات من مكان إلى آخر بسهولة
ونستطيع أن ندير هذه الحاويات بسهولة باستخدام الـ Docker، الشخص الذي يقوم بتحميل وتفريغ هذه الحاويات من وإلى السفن
كل Container يحتوي على كل ما يحتاجه التطبيق لكي يعمل بشكل صحيح
ولا يهتم أين يعمل هذا الـ Container هل سيذهب إلى القطب الشمالي أو إلى جبال الهيمالايا أو إلى صحراء الربع الخالي
أو إلى مخبأ كنز اللحية السوداء في أحد الجزر النائية في البحار والمحيطات السبع العميقة
أي مكان أو جهاز أو Server يعمل عليه الـ Docker يستطيع تشغيل الـ Container بكل سهولة
بغض النظر عن نظام التشغيل أو البيئة التي يعمل عليها هذا الجهاز أو الـ Server
الفرق بين الـ Docker والـ Virtual Machine
الآن بعد أن فهمنا مفهوم الـ Container والـ Docker
دعنا نوضح الفرق الجوهري بين الـ Docker Containers والـ Virtual Machines
في الـ Virtual Machine فنحن نقوم بإنشاء جهاز وهمي كامل على جهازنا الشخصي به نظام تشغيل كامل بداية من طبقات متعددة تبدأ من الـ Hardware وصولًا إلى التطبيقات
ويحتاج إلى Hypervisor وهو برنامج وسيط بين الـ Virtual Machine ونظام التشغيل المضيف
لكي يساعدك في تشغيل الـ Virtual Machine على جهازك الشخصي
وهذا يعني أن كل Virtual Machine تحتاج إلى نظام تشغيل كامل خاص بها
مما يستهلك مساحة وموارد كبيرة من الجهاز كما شرحنا سابقًا
+----------------+ +----------------+ +----------------+
| App 1 | | App 2 | | App 3 |
| 5GB | | 5GB | | 5GB |
+----------------+ +----------------+ +----------------+
| Libraries | | Libraries | | Libraries |
+----------------+ +----------------+ +----------------+
| Guest OS | | Guest OS | | Guest OS |
| (Ubuntu) | | (CentOS) | | (Debian) |
| 20GB | | 15GB | | 10GB |
+----------------+ +----------------+ +----------------+
| Hypervisor |
+-------------------------------------------------------+
| Host OS (Windows) |
+-------------------------------------------------------+
| Hardware |
+-------------------------------------------------------+
لاحظ أن كل تطبيق حجمه 5GB لكن كل تطبيق احتاج إلى نظام تشغيل كامل بكل برامجه وخدماته وكل ما فيه من إضافات بحجم يتراوح بين 10GB إلى 20GB
عندما نقول أن Ubuntu يأخذ 20GB فهذا يشمل كل البرامج والخدمات التي تأتي مع نظام التشغيل Ubuntu بشكل افتراضي
نفس الأمر مع CentOS و Debian وكل أنظمة التشغيل الأخرى
بالتالي تشغيل الثلاث تطبيقات باستخدام الـ Virtual Machines كلفنا حوالي 60GB من المساحة على جهازنا الشخصي
أما مع الـ Docker فالأمر مختلف تمامًا
لأن الـ Containers تشترك في نفس الـ Kernel الخاص بنظام التشغيل الخاص بجهازك الشخصي
ولا يحتاج إلى Hypervisor كما في حالة الـ Virtual Machines
بل يعتمد على Docker Engine وهو مجرد برنامج مثله مثل أي برنامج آخر يعمل على جهازك الشخصي
ويقوم الـ Docker Engine بإدارة وتشغيل الـ Containers على جهازك الشخصي
والـ Docker Engine يستخدم الـ Kernel الخاص بجهازك بالتالي لا يحتاج إلى تثبيت نظام تشغيل كامل له
+----------------+ +----------------+ +----------------+
| App 1 | | App 2 | | App 3 |
+----------------+ +----------------+ +----------------+
| Libraries | | Libraries | | Libraries |
+----------------+ +----------------+ +----------------+
| Base OS | | Base OS | | Base OS |
| (Alpine Linux) | | (Alpine Linux) | | (Alpine Linux) |
| 10MB | | 10MB | | 10MB |
+----------------+ +----------------+ +----------------+
| Docker Engine |
+-------------------------------------------------------+
| Host OS (Windows) |
+-------------------------------------------------------+
| Hardware |
+-------------------------------------------------------+
لاحظ أن كل تطبيق حجمه 5GB لكن كل تطبيق احتاج إلى نظام تشغيل أساسي فقط كبرنامج خام بحجم 10MB فقط
عندما نقول أن Alpine Linux يأخذ 10MB فهذا يشمل الـ Operating System الأساسي فقط بدون أي برامج أو خدمات إضافية
بالتالي تشغيل الثلاث تطبيقات باستخدام الـ Docker Containers كلفنا حوالي 15GB من المساحة على جهازنا الشخصي
بالمناسبة لو بدلنا Alpine Linux بنظام تشغيل آخر مثل Ubuntu أو Debian أو CentOS
تجد أن حجم الـ Base OS الخاص بـ Ubuntu قد يصل إلى 100MB و Debian إلى 150MB و CentOS إلى 200MB
وهذا أقل بكثير من حجم نظام التشغيل الكامل الذي نحتاجه في حالة الـ Virtual Machines
المفاهيم الأساسية في الـ Docker
لكي نفهم الـ Docker بشكل جيد علينا أن نفهم بعض المفاهيم الأساسية:
Docker Image
الـ Docker Image هو قالب أو نموذج يحتوي على كل ما يحتاجه التطبيق لكي يعمل
مثل:
- نظام التشغيل الأساسي (مثل
UbuntuأوAlpine Linux) - البرامج والمكتبات المطلوبة (مثل
PHP،MySQL،Redis) - كود التطبيق نفسه
- ملفات الإعدادات
Docker Container
الـ Docker Container هو نسخة من الـ Docker Image
فلو افترضنا أن لدينا Docker Image هو Class أو Interface
فالـ Docker Container هو الـ Object أو الـ Instance الذي يتم إنشاؤه من هذا الـ Image
بمعنى أن الـ Image هو القالب أو النموذج
والـ Container هو التطبيق الذي يعمل فعليًا بناءً على هذا القالب
يمكنك إنشاء عدة Containers من نفس الـ Image
كل Container سيكون معزولًا عن الآخر
ويمكنك تشغيلهم جميعًا في نفس الوقت
مثل فكرة إنشاء أكثر من Object من نفس الـ Class في الـ OOP
وكل Object يعمل بشكل مستقل عن الآخر
Dockerfile
الـ Dockerfile هو ملف نصي يحتوي على مجموعة من التعليمات لإنشاء Docker Image
في هذا الملف نكتب خطوات بناء الـ Image خطوة بخطوة
مثل:
- ما هو نظام التشغيل الأساسي الذي سنستخدمه
- ما هي البرامج التي سنثبتها
- ما هي المكتبات التي سنحتاجها
- كيف سننسخ كود التطبيق إلى الـ
Image - ما هي الأوامر التي سنشغلها عند بدء تشغيل الـ
Container
بمجرد أن نكتب الـ Dockerfile يمكننا بناء Image منه بأمر واحد بسيط
وهذا يضمن أن أي شخص يستخدم نفس الـ Dockerfile سيحصل على نفس الـ Image بالضبط
بغض النظر عن نظام التشغيل الذي يستخدمه
بالتالي مهما كان الجهاز الذي يستخدمه المطور أو الـ Server الذي سيشغل التطبيق عليه
ومهما كان الـ Operating System الخاص به
طالما أنه يستخدم نفس الـ Dockerfile سيحصل على نفس الـ Image والبيئة التي يحتاجها التطبيق
ويستطيع إنشاء Container منها وتشغيل التطبيق بدون أي مشاكل
وشكل ملف الـ Dockerfile يكون بسيط جدًا وسهل الفهم
FROM php:8.2.30-cli
WORKDIR /app
COPY . .
CMD ["php", "index.php"]
في هذا المثال البسيط، نقوم بإنشاء Docker Image يحتوي على PHP إصدار 8.2.30
ثم نقوم بتحديد مجلد العمل داخل الـ Container ليكون /app
ثم نقوم بنسخ كل ملفات التطبيق إلى داخل الـ Container
وأخيرًا نحدد الأمر الذي سيتم تشغيله عند بدء تشغيل الـ Container وهو تشغيل ملف index.php باستخدام PHP
الآن أي شخص يستخدم هذا الـ Dockerfile سيحصل على نفس الـ Image والبيئة التي يحتاجها التطبيق
لاحظ أن في هذا المثال استخدمنا PHP فقط ولم نحدد أي Operating System
بمعنى أننا لم نحتج إلى تثبيت أي Operating System من الأساس
كل ما ثبتناه هو PHP فقط داخل الـ Container وشغلنا التطبيق به دون الحاجة إلى أي Operating System على الإطلاق
بالطبع هذا مثال بسيط جدًا لم نحتج فيه إلى الكثير من البرامج أو المكتبات ولم نحتاج إلى Operating System
لكن في التطبيقات الحقيقية قد نحتاج إلى تثبيت برامج ومكتبات أخرى
مثل MySQL، Redis، Nginx، وغيرها من البرامج التي يحتاجها التطبيق لكي يعمل بشكل صحيح
وقد نحتاج إلى استخدام Operating System أساسي مثل Ubuntu أو Alpine Linux
كل هذا يتم تحديده في ملف الـ Dockerfile بكل سهولة
وأي شخص يستخدم نفس الـ Dockerfile سيحصل على نفس الـ Image والبيئة التي يحتاجها التطبيق
يمكننا القيام بأمور كثيرة جدًا باستخدام الـ Dockerfile
وفي أمور تحتاج إلى شرح عملي مفصل سنراها في المقالات القادمة
Docker Hub
الـ Docker Hub هو مستودع عام لحفظ ومشاركة الـ Docker Images
يمكنك أن تتخيله كأنها GitHub ولكن للـ Docker Images
أو أنه Package Manager للـ Docker Images
ولديه موقع إلكتروني يمكنك زيارته على الرابط التالي: https://hub.docker.com/
يمكنك رفع الـ Images التي أنشأتها على الـ Docker Hub ومشاركتها مع الآخرين
أو يمكنك تنزيل Images جاهزة أنشأها آخرون واستخدامها في مشاريعك
هناك آلاف الـ Images الجاهزة على الـ Docker Hub
مثل Images لـ MySQL، Redis، PostgreSQL، Nginx، PHP، Python وغيرها الكثير
هذا يوفر عليك الوقت والجهد في إنشاء Images من الصفر
يمكنك ببساطة استخدام Image جاهزة وتخصيصها حسب احتياجاتك
وغالبًا ما تكون هذه الـ Images محدثة بأحدث الإصدارات من البرامج والمكتبات ومدعومة من الشركات المطورة لها
كيف يحل الـ Docker المشاكل التي ذكرناها؟
الآن بعد أن فهمنا المفاهيم الأساسية
دعنا نرى كيف يحل الـ Docker المشاكل التي كنا نواجهها
قلنا أنه يوفر لنا Dockerfile وهو ملف نصي يحتوي على تعليمات لإنشاء Docker Image
وبالتالي يمكننا استخدام هذا الـ Dockerfile لحل المشاكل التي ذكرناها سابقًا
فبدلًا من أن يقوم كل شخص بتجهيز البيئة يدويًا على جهازه
يمكننا إنشاء Dockerfile واحد يحتوي على جميع التعليمات لتجهيز البيئة
ثم نعطيه لجميع أعضاء الفريق أو نرفعه على الـ Server
ثم نبني Docker Image من هذا الـ Dockerfile
ونقوم بإنشاء Container من هذا الـ Image لتشغيل التطبيق في بيئة جاهزة تمامًا في بضع ثوانٍ
وسيحصل الجميع على بيئة جاهزة تمامًا بكل ما تحتاجه من برامج ومكتبات
بدون الحاجة إلى تثبيت أي شيء يدويًا
هذا يضمن أن الجميع يعملون في نفس البيئة بالضبط
ولن يكون هناك اختلافات بسبب أنظمة التشغيل المختلفة
وأيضًا عندما نريد تحديث إصدار أحد البرامج
مثل تحديث PHP من 8.2 إلى 8.3
نقوم فقط بتعديل الـ Dockerfile وتغيير رقم الإصدار
ثم سيقوم كل شخص بإعادة بناء الـ Image من الـ Dockerfile الجديد
وإعادة تشغيل الـ Container من الـ Image الجديد
وهكذا نكون قد حدثنا البيئة بكل سهولة وسرعة
بدون الحاجة إلى تحديث أي شيء يدويًا على جهازه
نفس الأمر في حالة الـ Server
وفي حالة أن هناك شخص لديه تطبيقات تعمل بإصدارات مختلفة من نفس البرنامج
فمثلًا لديك تطبيق يعمل بـ PHP 7.4 على جهازك الشخصي
والتطبيق الآخر يعمل بـ PHP 8.2
هنا ببساطة باستخدام الـ Docker سنقوم بإنشاء Dockerfile لكل تطبيق
وكل Dockerfile سيحدد الإصدار المطلوب من PHP
ثم نبني Docker Image من كل Dockerfile
كل Image ستحتوي على الإصدار المطلوب من PHP لكل تطبيق بشكل معزول
وعندما تشغل Container من كل Image سيعمل كل تطبيق في بيئته الخاصة
دون أن يؤثر أحدهما على الآخر
لأن كل Container معزول تمامًا عن الآخر
لأن الـ Container كما قلنا كأنه برنامج مستقل بذاته يعمل على جهازك الشخصي
وكل ما فيه من برامج ومكتبات يتم تثبيتها داخل الـ Container نفسه
ولا يؤثر على جهازك الشخصي أو على الـ Containers الأخرى
الخلاصة
أعرف أن هناك الكثير من المعلومات التي قدمناها في هذه المقالة
والتي تحتاج إلى تفصيل أكثر في الشرح، وخصوصًا الجزء العملي منها
لكن الهدف من هذه المقالة كان تقديم مقدمة شاملة عن الـ Docker
وفي المقالات القادمة سنتعمق أكثر في الشرح العملي لكل جزء من هذه المفاهيم
وكما قلنا في البداية، الـ Docker غيرت العالم وجعلت من السهل جدًا إنشاء وإدارة وتشغيل الـ Containers
والتي كانت معقدة جدًا في السابق
وتحتاج لأشخاص متخصصين في هذا المجال
والآن باستخدام الـ Docker أصبح بإمكان أي مطور مهما كانت خبرته في هذا المجال
أن يقوم بإنشاء وإدارة وتشغيل الـ Containers بكل سهولة
الـ Docker يقدم لنا العديد من الفوائد مثل:
- تبسيط عملية تجهيز البيئة: لا حاجة للتثبيت اليدوي للبرامج
- تحقيق مبدأ الـ
Consistency: الجميع يعمل في نفس البيئة بالضبط - تحقيق مبدأ الـ
Isolation: كل تطبيق يعمل في بيئته الخاصة دون تداخل - توفير الموارد: استهلاك أقل للمساحة والذاكرة مقارنة بالـ
Virtual Machines - سرعة التشغيل: تشغيل
Containerيأخذ ثوان معدودة فقط - سهولة النشر: يمكن نشر نفس الـ
Imageعلى أيServerبكل سهولة ولأكثر من شخص
في المقالات القادمة سنتعمق أكثر في استخدام الـ Docker
وسنتعلم كيف نكتب Dockerfile وننشئ Docker Image ونديرها وننشيء منها Container
مع أمثلة عملية خطوة بخطوة