لماذا نحتاج إلى دوكر؟ فهم المشكلة والحل

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

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

ملاحظة: للتوضيح، الخادم لا يختلف عن جهاز الحاسوب الشخصي الذي تستخدمه في المنزل؛ فهو يحتوي على ذاكرة (Memory)، وقرص صلب (Hard Disk)، ومعالج (Processor). الفارق يكمن في أن إمكانيات الخادم تكون أعلى بكثير ليتمكن من خدمة عدد كبير من المستخدمين، حسب حجم التطبيق.

كان يتم أخذ النسخة المترجمة (compiled) من التطبيق الذي بناه المطورون ووضعها على الخادم. لنأخذ لغة سي شارب كمثال، ينتج عنها ملفات DLL التي تعمل على بيئة التشغيل (Runtime) الخاصة بـ .NET. يتم تشغيل هذه الملفات على خادم IIS (Internet Information Services) الذي يتم تثبيته على نظام تشغيل ويندوز سيرفر.

المشكلة: “إنها تعمل على جهازي!”

تكمن المشكلة في أن المطور قد يعمل على جهازه الخاص بنفس الإعدادات ولكن على نطاق مصغر. على سبيل المثال، يتم تثبيت نسخة مصغرة من IIS مع Visual Studio لتمكين المطور من اختبار التطبيق أثناء العمل. من الوارد جدًا أن يكون إصدار الأدوات على جهاز المطور مختلفًا عن الإصدار الموجود على الخادم. في الواقع، كان هذا الاحتمال مرتفعًا جدًا، لأنه ليس من الطبيعي تحديث الخوادم فور صدور أي إصدار جديد، بينما قد يتحمس المطور ويقوم بالتحديث على جهازه بسرعة.

النتيجة كانت وجود اختلافات في إصدارات المكتبات (libraries)، أطر العمل (frameworks)، أو الأدوات التي يعتمد عليها الكود. قد تجد أن كل شيء يعمل بشكل مثالي على جهاز المطور، ولكن عند أخذ نفس الملفات المترجمة ووضعها لتعمل على بيئة التشغيل في الخادم، تتفاجأ بأنها لا تعمل.

“It runs on my machine” (إنها تعمل على جهازي الشخصي)

هذه الجملة أصبحت شهيرة جدًا وانتشرت حولها الكثير من الصور الساخرة (memes). وما أذكره هنا لا يقتصر على لغة برمجة أو إطار عمل معين، بل ينطبق على أي كود تقوم ببنائه لتشغيله على بيئة استضافة، وذلك لأن العوامل البيئية تختلف من جهاز لآخر ومن ثم تختلف عن بيئة الخادم نفسه. كانت هذه إحدى المشاكل الكبيرة التي تسبب أعطالاً وتكبد الشركات خسائر مالية كبيرة، حيث إن اكتشاف سبب المشكلة (هل هو مكون ناقص على الخادم أم موجود لدى المطور فقط) قد يستغرق يومًا كاملاً أو حتى عدة أيام، مما يؤثر على الإنتاجية.

مشكلة تكلفة وصيانة الخوادم

دعنا نضع المشكلة السابقة جانبًا للحظات، فهناك مشكلة أخرى أكثر أهمية. جهاز الخادم الذي تشتريه الشركة وتوصله بالشبكة وتثبت عليه نظام التشغيل هو جهاز مكلف للغاية. قد تصل تكلفة شراء خادم واحد بإمكانيات عالية إلى عشرات الآلاف من الدولارات. وإذا زاد عدد المستخدمين عن قدرة هذا الخادم، ستضطر الشركة لشراء جهاز آخر، وهكذا مع نمو التطبيق.

أضف إلى ذلك مشكلة صيانة هذه الخوادم، والتي تتطلب توظيف متخصصين للقيام بالتحديثات والإصلاحات وضبط أنظمة التشغيل. من بين هؤلاء المتخصصين نجد مسؤولي تقنية المعلومات (IT)، ومسؤولي قواعد البيانات (Database Administrators)، ومسؤولي الخوادم (Server Administrators). جميعهم مسؤولون عن تشغيل الأجهزة وصيانتها وحل مشاكل الشبكة.

قد تتساءل: “ما علاقتي أنا كمطور برمجيات بكل هذا؟”. العلاقة تكمن في أن البرنامج الذي تطوره سيعمل في النهاية على هذه الأجهزة. وبالتالي، فإن حل شراء الخوادم المادية (الذي يسمى On-Premises Server) ليس حلاً اقتصاديًا على الإطلاق.

لهذا السبب، اتجه الكثيرون للهروب من الخوادم المحلية (On-Premises) إلى الحوسبة السحابية (Cloud). توفر السحابة مرونة عالية (scalability)، حيث يمكنك الحصول على الموارد التي تحتاجها فقط. ولكن، تظل المشكلة الأساسية قائمة: عند وضع تطبيقك على أي جهاز، سواء كان محليًا أو سحابيًا، ستحتاج إلى تثبيت نظام تشغيل ومجموعة من الأدوات وأطر العمل وبيئات التشغيل التي تناسب لغة البرمجة التي استخدمتها. هذا يعيدك إلى نفس الكوارث التي كنت تواجهها محليًا.

المشكلة الإضافية في البيئة السحابية هي أنك تتعامل معها عن بعد (remote access)، على سبيل المثال عبر اتصال SSH. بينما لو كان الجهاز محليًا، يمكنك التدخل مباشرة لحل المشكلة، أما في السحابة، فأنت مقيد بقيود مختلفة وقد لا يكون لديك صلاحية الوصول الكاملة لتثبيت كل ما تحتاجه. لا أريد الخوض في تفاصيل تقنية معقدة، ولكن الهدف هو توضيح أنه كمطور برمجيات، لا يهمك أين سيوضع البرنامج، كل ما يهمك هو أن يكون متاحًا عبر الشبكة من خلال عنوان IP معين مرتبط بنطاق (domain).

الحل الأول: الأجهزة الافتراضية (Virtual Machines)

لحل مشكلة “يعمل على جهازي ولا يعمل على الخادم”، ظهر مفهوم الأجهزة الافتراضية (Virtualization)، وهو أساس نجاح الحوسبة السحابية. الفكرة كالتالي:

  1. الجهاز المادي (Host): لديك جهاز خادم حقيقي.
  2. نظام التشغيل المضيف (Host OS): تقوم بتثبيت نظام تشغيل عليه.
  3. الهايبرفايزر (Hypervisor): فوق نظام التشغيل، تقوم بتثبيت طبقة برمجية تسمى “هايبرفايزر”.
  4. أنظمة التشغيل الضيف (Guest OS): باستخدام الهايبرفايزر، يمكنك تثبيت أنظمة تشغيل افتراضية ومنعزلة فوق نظام التشغيل الأصلي. يمكنك تشغيل نسخة لينكس بجانب نسخة ويندوز على نفس الجهاز المادي.

تتشارك هذه الأنظمة الافتراضية موارد الجهاز المادي مثل المعالج (CPU). لهذا السبب، ستجد أن خدمات السحابة تذكر “vCPU” أو “Virtual CPU”، لأنك لا تحصل على معالج مادي مخصص لك، بل حصة من استخدامه. أما بالنسبة للذاكرة (RAM)، فيتم حجزها بشكل صارم لكل جهاز افتراضي. فإذا كان الخادم يحتوي على 8 جيجابايت من الذاكرة، يمكنك تخصيص 2 جيجابايت لجهاز افتراضي و4 جيجابايت لآخر، وهكذا.

الميزة الكبرى التي قدمتها الأجهزة الافتراضية هي إمكانية إنشاء صورة (Image) منها. يمكنك على جهازك الشخصي إعداد جهاز افتراضي، وتثبيت كل ما يحتاجه التطبيق من بيئات تشغيل ومكتبات، ثم أخذ “صورة” من هذه الحالة الكاملة. هذه الصورة يمكن نقلها وتشغيلها على أي جهاز خادم آخر يحتوي على هايبرفايزر. بهذا نضمن أن البيئة التي عمل عليها التطبيق في جهاز المطور هي نفسها تمامًا التي سيعمل عليها في الخادم، لأنها معزولة داخل الجهاز الافتراضي (Sandbox).

قيود الأجهزة الافتراضية

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

الحل النهائي: دوكر (Docker)

من هنا جاءت فكرة إنشاء تطبيق يوفر مفهوم المحاكاة الافتراضية كمحرك (Engine)، وأنت تقوم بتشغيل ما تريده فوقه. هذا المحرك هو دوكر.

ما اختلف عن الأجهزة الافتراضية هو أنك بدلاً من التعامل مع هايبرفايزر، لديك الآن محرك دوكر (Docker Engine). هذا المحرك يتواصل مباشرة مع عتاد الجهاز ويوفر لك طبقة تشغيلية. فوق هذا المحرك، تقوم بتشغيل حاويات (Containers).

تأتي الحاوية من صورة دوكر (Docker Image). هذه الصورة تحتوي فقط على تطبيقك والحد الأدنى من البيئة التي يحتاجها ليعمل. على سبيل المثال، لتشغيل تطبيق Node.js، ستحتاج إلى:

  1. استخدام صورة أساسية (Base Image) لـ Node.js.
  2. إضافة الكود الخاص بك.
  3. تثبيت الاعتماديات عبر أوامر مثل npm install.

كل هذه الخطوات تُكتب في ملف يسمى Dockerfile. عند تشغيل هذا الملف، يتم بناء صورة دوكر (Docker Image). وعندما تقوم بتشغيل هذه الصورة، فإنك تنشئ حاوية (Container) يعمل بداخلها تطبيقك.

مزايا دوكر

اليوم، كل مزودي الخدمات السحابية الكبرى مثل AWS, Google Cloud, و Microsoft Azure يوفرون حلولاً ميسرة للتعامل مع دوكر. على سبيل المثال، خدمة Elastic Container Service (ECS) من AWS تتيح لك تسجيل صور دوكر وتشغيلها بسهولة، بل ويمكنك أتمتة العملية بالكامل بحيث يتم بناء ونشر صورة جديدة تلقائيًا مع كل تحديث لالكود على GitHub.

مثال عملي: Dockerfile لتطبيق Node.js

لأخذ فكرة عملية عن كيفية بناء صورة دوكر، إليك مثال لملف Dockerfile لتطبيق بسيط مبني بـ Express.js:

# 1. استخدم صورة نود الرسمية كصورة أساسية
FROM node:18-alpine

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

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

# 4. قم بتثبيت الاعتماديات
RUN npm install

# 5. انسخ باقي ملفات الكود الخاص بالتطبيق
COPY . .

# 6. عرّف المنفذ الذي سيعمل عليه التطبيق
EXPOSE 3000

# 7. الأمر الذي سيتم تنفيذه عند تشغيل الحاوية
CMD [ "node", "server.js" ]

باستخدام هذا الملف، يمكنك بناء صورة وتشغيل حاوية تضمن أن تطبيقك سيعمل في بيئة معزولة ومتطابقة في أي مكان.

الخلاصة

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

شارك المقال

أحدث المقالات

CONNECTED
ONLINE: ...
SECURE
00:00:00