Quick Introduction to Docker & Containerization

فلنفترض انك تعمل كـ Back-end Engineer ومطالب منك إنهاء تطوير API خاص بتطبيق ما وأنتهيت من مرحلة الـdevelopment بها وبعد ذلك سيقوم أشخاص آخرون بالعمل على ذلك التطبيق
Quick Introduction to Docker & Containerization

في هذه الصفحة

فلنفترض انك تعمل كـ Back-end Engineer ومطالب منك إنهاء تطوير API خاص بتطبيق ما وأنتهيت من مرحلة الـdevelopment بها وبعد ذلك سيقوم أشخاص آخرون بالعمل على ذلك التطبيق، لذلك تقوم برفع الـكود الخاص للمشروع على Github سواء للتعديلات، إضافات أخرى للـ API، أو تجربته، أو ما شابه، من المفترض أن يقوموا بتشغيل الـAPI على الجهاز الخاص بهم، لكنهم تفاجأوا أنهم لا يستطيعون فعل ذلك. عندئذ، ستقوم بطرح تلك الأسئلة:

🟣هل أنت متأكد إن كل الملفات خاصة بالمشروع موجودة على جهازك

🟡بالتأكيد.

🟣ماذا عن الـLibraries والـdependencies، هل كلها متطابقة بنفس النسخ؟

🟡نعم.

🟣ماذا عن الـEnvironment variable، أهي بنفس القيم المتفق عليها؟

🟡بالطبع.

🟣ماذا عن نسخة Node (أو بايثون أو Java، أيًا كان 👀) التي تعمل بيها؟

🟡مطابقة للنسخة التي تعمل عندك.

🟣لا يمكن! كيف لا يعمل الـAPI عندك إذن!

سيظل ذلك الخلاف لوقت طويل حتى تجدوا حل لمشكلة لا تستحق إهدار الكثير من الوقت والجهد. تخيل أنك تعمل على تسليم مشروع حقيقي وعندها سيقوم فريق الـdevops (هو المسؤول عن اللجوء إلى الحلول السحابية (Cloud solutions) لتجهيز خادم (Server) وتجهيز البيئة الملائمة لجعل ذلك المشروع يعمل على نحو جيد)، ففعل كل ذلك سيستغرق وقتًا طويلًا، وقد تحدث أخطاء عند القيام بتلك الترتيبات 😥.

أصبحت تلك التقاليد للـ deployment قديمة الأزل، دعني أعرفكم بصديقنا الجديد، Docker 💪.

كيف يعمل Docker:

– عندما تقوم بعملية تحميل (Clone) أو تحديث (Push) للـ Codebase الخاص بك، فأنت تفعل ذلك علي GitHub من خلال جهازك، صحيح؟ سننفذ نفس الفكرة تقريبًا باستخدام Docker، لكن الفارق أننا سنأخذ جهازي وسنجعله يعمل علي جهازك حتى يعمل Application دون مشاكل بما أنه يعمل على جهازي بشكل مثالي.

🟣ولكن، هذه ليس منطقي بالمرة!

🟡أنا أعلم، دعني أخبرك كيف😌.

– الجهاز الخاص بك ما هو إلا عبارة عن مجموعة من المكونات الرئيسية (Hardware) مثل:

  1. معالج (CPU).
  2. ذاكرة عشوائية (RAM).
  3. قرص صلب (سواء HDD أو SSD).

وخلاف ذلك من المكونات، بالإضافة إلى نظام التشغيل (Operating System) أيًا كانت نسخته (MacOS أو Windows أو Linux وغيرهم) بالإضافة إلى الـkernel (هو عبارة عن Software مسؤول عن إدارة تلك الموارد التي تم ذكرها وتخصيصها بشكل مناسب لكل Process تعمل على جهازك، والـProcess بالمناسبة هي أي ملف يقوم جهازك بمعالجته Execution عن طريقة الـCPU ويقوم بعمل بتحميل بياناته في الذاكرة العشوائية مثل أي برنامج أنت تستخدمه مثل chrome, Spotify, MS word وغيره).

 الـDocker ما هو إلا وسيلة لتقوم بعملية تسمى الـContainerization لكل شئ له علاقة ب الـapplication الذي تعمل عليه مثل الـfiles, libraries, dependencies, config files وخلافها بحيث إن البيئة التي تقوم بتطوير الـApplication بها مطالبة للتي عنك بالضبط، ويبقى الـApplication عندك يعمل كأنه process مثل أي process معتادة، لكن الفارق أن تلك الـprocess ستكون منعزلة –نسبيًا- عن الباقي الـProcesses. سأخبرك لاحقًا من معنى منعزلة نسبيًا. لكن دعني أخبرك كيفية فعل ذلك.

لكن أولًا، عليك بتحميل Docker engine قبل أي شئ ومن خلاله ذلك سيساعدك في عمل Pull أو Build لأي Image تريدها، والـImage هنا عبارة عن Snapshot تحتوي على كل الملفات والـpackages وباقي الأشياء الخاصة بأي Application، حينها يمكنك رفع تلك الـImage على منصة خاصة برفع تلك الـDocker images مثل Docker Hub أو بإمكانك إنشاء Dockerfile في الـCodebase وستطلب من الذي سيستخدم ذلك الـCode لبناء تلك الـImage (الـDockerfile يعتبر ملف تصف فيه التعليمات التي يلتزم بها Docker engine عند بنائه الـImage الخاصة بذلك الـCode)، ومثال على ذلك هو الملف الآتي:

  1. سنستخدم تلك النسخة من Linux ليعمل عليها ذلك الـِApplication.
  2. الفولدر التى سنضع فيه ملفات الـCodebase هو /app.
  3. سنقوم بنسخ الملف Package.json داخل الـapp.
  4. سنقوم بتحميل جميع الـPackages التي يستخدمها ذلك الـApplication.
  5. سنقوم بنسخ جميع الملفات إلى app.
  6. سننفذ ذلك الـCommand وهو Node index.js حتى يعمل الكود
  7. سيعمل ذلك الكود على الـPort 8081.

حسنًا، لكن كيف يعمل الـApplication عند الانتهاء من بناء تلك الـImage؟

ما وراء الكواليس:

بعد ذلك، سنفعل الـApplication داخل ما يسمى Docker containers. فكرتها شبيهة بأي Instance تقوم بإنشائها من Classes بالضبط. على سبيل المثال، Person class عنده بعض البيانات مثل الاسم، العنوان، العمر وما إلي ذلك، وبإمكانك عمل عدة نسخ من تلك الـclass تحت مسمى Object. 

الـContainers في تلك الحالة تندرج تحت مسمى Objects، وكل Container سنقوم بتشغيله يحدث فيه عملية تدعى namespacing، وتعني أن جميع الـContainers من أي Image سيكون لها جزء مخصوص من الموارد (Hardware) التي سيتم إدارتها تحت نفس الـKernel. علي عكس الـVirtualization. فأنت تقوم بتحميل نظام تشغيل كامل بالإضافة إلى Kernel خاص بيه بالإضافة إلى تحديد الموارد المخصصة له (Hardware) عن طريق برامج تسمى بالـ Hypervisors وحرفيًا كل VM منعزلة عن غيرها وهذا هو الفرق الجوهري بين الـContainers وVMs وهذا هو السبب الذي يجعل الـContainers سرعتها رهيبة أو أخف بكثير مقارنة ب الـVMs. والـKernel الوحيد الذي يسمح بتخصيص جزء معين من الموارد الخاصة بجهازك هو الـKernel الخاص بـ Linux.

 عندما تقوم بتنصيب Docker Server. سيقوم بتنصيب أيضًا Virtual Machine وسيعمل عليها Linux التي ستقوم بدورها باستضافة جميع الـContainers دي بجانب نظام التشغيل الأساسي الذي تعمل به، وجميع الـcontainers يمكنها أن ترى بيانات بعضها البعض لأنها تعمل تحت نفس نظام التشغيل، والتواصل يحدث بينهم من خلال عملية تعدى Inter-process communication، لذلك فقد ذكرت مسبقًا أن الـContainers تكون“منعزلة نسبيا”، وليس كليًا مثل الـVM لإنها لن تسمح بحدوث ذلك من الأساس وتلك واحدة من مميزات الـVM وهي الأمان.

هذا شئ ممتاز، لكن ماذا إذًا أردنا القيام بعملية الـContainaziation لعدة Codebases مختلفة؟ فلنقل أنه في Repository واحدة لدي عدة تطبيقات بالداخل، مثل Front-end والـBack-end. عندها، سأقوم بالدخول لكل واحدة من تلك الأجزاء والقيام ببناء Image خاصة بها وبعدها سأقوم بعمل Container لكل Image وسيعمل التطبيق بشكل مثالي، لكن ماذا إذًا كان لدينا أيضًا قاعدة بيانات؟ ماذا إذا كان لدينا أيضّا نوع مخصص من قواعد البيانات التي ستقوم بعمل Cache (اقصد هنا Redis) التي سنستخدمها في نفس التطبيق؟ سيستغرق وقتًا طويلًا للغاية للقيام ببناء Image لكل مكون من مكونات ذلك التطبيق 😥، حتى جاء لنا ذلك الوحش الكاسح 🙋، وهو

 الـDocker compose:

وهو يأتي بالفعل مع Docker Engine؛ وظيفته هو إدارة العديد من الـContainers مع بعضها دون الحاجة إلى الذهاب إلى كل مكون من مكونات التطبيق وعمل Containerization على حدة. حيث أنه يقوم بذلك على مرة واحدة عن طريق ملف تقوم بإنشائه ويسمى docker-compose.yml، وهنا الملفات من نوع yml (أو yaml) وظيفتها أن تكون من نوع الملفات التي تقوم بوصف نوع من التعريفات التي ستقوم بها لأيًا كانت الخدمة التي ستقوم باستخدامها (Github action مثًلا على سبيل المقال). وهي مشابهة للغاية مع ملفات الـjson لكن استخدامها مفضل عن الـjson  في التعامل مع البيانات في الـAPIs لأنها أخف وأسهل في النقل الـRequests القادمة من أي API أخر أو من العميل (Client).

ويكون بهذا الشكل الآتي:

  1. نقوم الأول بتحديد نسخة الـdocker compose التي سنستخدمها.
  2. سنقوم بتعريف مجموعة من الـservices، وهي الـimages التي تريد بنائها في هذه الحالة مثل api و mongo (قاعدة البيانات).
  3. ما هي الـimages التي قد نحتاجها هنا، عندئذ سنقوم بتحميل Images من dockerhub وهي آخر نسخة من Node.js بالإضافة إلى mongo engine .
  4. إسم الـContainer الذي ستطلقه من كل Image.
  5. ما هو الأمر الذي ستقوم بتنفيذه هنا إطلاق تلك الـContainers .
  6. ما هو الـport الذي ستستخدمه؟ لدينا 2 ports مكررين وذلك لأن الـContainer الذي سيعمل بداخل الـLinux Kernel سيعمل على port 8000، في نظام التشغيل الذي يعمل به جهازك، سيقوم يجهز أيضًا Port 8000 ويقوم بعملية ربط بينهم.
  7. ما هي الـEnvironment variables اللازمة في تلك الحالة؟ سواء API keys لأي خدمة أنت تستخدمها في الـAPI أو كلمة السر للـ Database الخاصة بالتطبيق.
  8. بالإضافة إلى volumes وهي أين ستخزن تلك البيانات.

في الختام

 أصبح تجهيز الخادم الخاص بك للقيام بعملية الـ Deployment للتطبيق الخاص بك أمر بسيط للغاية باستخدام Docker و Docker Compose ويستطيع الآن مهندس البرمجيات القيام بذلك بكل سهولة عن طريق كتاب ملف واحد بمسمى Dockerfile به عدة أوامر ستسهل علىه الكثير في تلك الحالة بدلًا من القيام بكل ذلك بشكل بدائي أو الاستعانة بشخص مختص للقيام بذلك (وهو الـ devops Engineer) في تلك الحالة. تعلم تلك الأداة بالطبع ستزيد من إنتاجيتك كثيرًا وستجعلك مبرمج محترف يمكنه القيام بعملية الـ deployment بكل سلاسة.

إذا كنت ستسألني عن واحدة من أعظم الأدوات التي وجدت في عالم صناعة البرمجيات في القرن الواحد والعشرين، فبالتأكيد Docker سيكون واحدة من تلك الأدوات، أصبح أي مبرمج يمكنه رفع التطبيق الخاص به دون التوجه إلى مختص بذلك، والذي بدوره يؤدي لتوفير الكثير من الوقت للقيام بعملية كتجهيز للخادم الذي سيقوم باستضافة الكود الخاص بك بشكل يدوي للقيام بذلك بعدة أوامر بسيطة للغاية ❤️‍🔥.

اشترك الآن بنشرة اقرأ-تِك الإخبارية

لا تدع أي شيء يفوتك. واحصل على أحدث المقالات المميزة مباشرة إلى بريدك الإلكتروني وبشكل مجاني!
رائع! تحقق من بريدك الإلكتروني واضغط على الرابط لإكمال تسجيل الدخول.
حدث خطأ! من فضلك قم بادخال بريد إلكتروني صحيح!