مقدمه
السلام عليكم ورحمة الله وبركاته، أنرت مدونتي المتواضعه مُجدداً عزيزي القارىء الجميل!! مقالُنا اليوم سيكون عن تقنيه جداً مهمه وأرى انه من الضروري على كل مبرمج ان يتعلمها لأنه صدقني! ستُسهلُ عليك حياتك للغايه.. حسناً وبدون اي مقدماتٍ إضافيه، سوف نتحدث اليوم عن “Docker” وما أدراك ما “Docker” من أجمل وأفضل التقنيات التي سهلت حياتي، لذا في هذا المقال سوف أُلخص التقنيه بشكلٍ مبسط وأُريكم كيف تبدأون بها وفي نهاية المقال سوف أُريكم مثالاً عملياً عليها. هيا بنا نبدأ بسم الله..
مامعنى Virtualization؟
أولاً وقبل كل شيء ماذا يعني مصطلح الحاويه؟ قبل ان نتحدث عن ماذا يعني دعونا نشرح مصطلحاً آخر ألا وهو الـ"Virtualization" ماهو وماعلاقته بمصطلح الحاويات؟ الـ"Virtualization" ياعزيزي القارىء الجميل هو مصطلح يُشير إلى تشغيل نظام إفتراضي على نظامك الموجود مسبقاً، كيف ذلك؟ حسناً لتبسيط الأمور نحن نبدأ بجهاز المضيف “يمكن ان يكون اي جهاز مثل: حاسوبك المحلي الذي تستخدمه، سيرفر، إلخ…” اي هو شيء به عتاد تقني كمعالج ورامات وتخزين.. وماتفعله تقنية الـ"Virtualization" هو انها تأخذ جزء من العتاد الخاص بالجهاز وتقوم بفصله إلى آلةٍ إفتراضيه وفي هذه الآله نقوم بتشغيل نظام تشغيل كامل “ويندوز، ماك، لينكس”.. والأجهزه الوهميه تعتمد على برامج مخصص لتشغيل وإدارة دورة حياة هذه الأجهزه الوهميه، مثل: “VMware, VirtualBox, VirtManager”.
مامعنى مصطلح Containerization؟
والآن وبعد ان شرحنا ماذا يعني مصطلح الـ"Virtualization" دعونا نشرح ماذا يعني مصطلح الإحتواء او الحاويات “Containerization” : بكل إختصار وبساطه في نظام الحاويات لديك الحاسوب المضيف “تماماً كما في النظام الإفتراضي”. والآن فلنفترض اننا نريدُ تشغيل مجموعه من العمليات، ولكننا نريدها ان تعمل في بيئةٍ معزوله عن بقية النظام.. يمكننا تحقيق ذلك عبر عدة أساليب منها :
- أمر
chroot
وهو أمر يقوم بإنشاء “root” جديد للعمليات حتى تعيش بداخله ولايمكنها ان تلمس اي شيء خارجه. - ميزه من مزايا النواه
rlimit
والذي تقوم بتقليل مقدار الموارد الذي تأخذها هذه العمليات. بإستخدام هذه التقنيات يمكننا تحقيق مايُدعى بالـ"Containerization" ولكنها عمليه معقده وصعبه للغايه. لهذا!! وجدت برامج تقوم بتأدية هذا العمل وتسهيله علينا حيث انها تُدير دورة حياة الحاويات الخاصه بك “هُنا حيثُ يأتي Docker لينقذ الموقف 💪”.
ماهو Docker؟ كيفية تثبيته والبدء معه
إذاً بعد كل هذا الحديث عن الإحتواء والآلآت الإفتراضيه لم تقم بإخبارنا ماهو “Docker”؟ حسناً ياعزيزي القارىء.. بكل إختصار “Docker” هو كما قُلنا سابقاً عباره عن برنامج لإدارة دورات حياة الحاويات الخاصه بك “تعديلها، تشغيلها، والتفاعل معها”. والآن دعونا نبدأ مع “Docker” : لتثبيته في جهازك قم بالذهاب إلى هذا الرابط : https://docs.docker.com/get-started/get-docker/
وقم بإختيار المنصه التي انت عليها وإتبع تعليمات التنصيب حسب المذكور، بعد الإنتهاء من التنزيل والتثبيت قُم بتشغيل أول امر بإستخدام “Docker” للتأكد من تثبيته بشكلٍ صحيح :
docker run hello-world
ملحوظه قد لايعمل الأمر لديك إلا بصلاحيات root
والآن سترى العديد من الأمور التي تحدُث، لاتقلق سوف أشرحُها لك بالترتيب، إصبر معي..
-
أولاً سترى السطر التالي : Unable to find image ‘hello-world:latest’ locally ماذا يعني كُل هذا؟؟ بكُل بساطه هذا يعني ان “Docker” لم يستطع العثور على الـ"image" المسماة “hello-world” ومابعد الـ":" هو الـ"tag" الخاص بهذه الـ"image" ألا وهو “latest” لذا سوف يذهب ويقوم بإحضارها من المستودع “repository” الخاص بـ"Docker" الذي يتم تخزين الـ"images" بداخله (مشابه إلى حدٍ كبير لموقع Github)، انا أعلم انك تُفكرُ بداخلك “مامعنى هذا المصطلح الجديد image”؟ الـ"image" هو الشيء الذي نقوم بتشغيل حاويات “Docker” من خلاله “سوف أقوم بالتوسع في شرحه لاحقاً لاتقلق..
-
ثانياً سترى هذا السطر : latest: Pulling from library/hello-world هُنا سوف يقوم " Docker” بسحب (تحميل) الـ"image" من موقع: https://hub.docker.com وكما قُلنا هو مثل “Github” ولكن خاص بالـ"Docker images" ويمكنك العثور على العديد من الـ"images" الرائعه والمفيده بداخله مثل (…ubuntu, archlinux, postgreSQL, etc).
الـDockerfile ماهو؟ ولماذا احتاجه؟
أولاً وقبل كل شي.. ماهي الـimage؟ وكيف “Docker” بالأساس يعلم كيف يبني هذه الـimages ويقوم بتشغيل الحاويات عن طريقها؟… إذا حزرت الإجابه بأنه بواسطة الـDockerfile فأنت محق!!! كُل شيءٍ هُنا متمحورٌ حول الـDockerfile!!.
- الـDockerfile بإختصار هو ملف إعدادات للحاويه الخاصه بك، حيث تقوم بتعريف نوع الـimage المُستخدمه، خصائص الحاويه والأوامر التي ستُنفذها هذه الحاويه.
هيكل مجلد المشروع
أي شيء تُريد عمل “image” منه سوف تحتاج إلى ان يكون هيكل المُجلد الخاص بِك كالتالي :
DIR
|__ Dockerfile
|__ /project
|__ /project/print-message.sh
مثال عملي بسيط
إليك ملف “Dockerfile” بسيط كمثال :
FROM ubuntu:latest
RUN apt update && apt install -y figlet
COPY print-message.sh /print-message.sh
RUN chmod +x /print-message.sh
CMD ["/print-message.sh"]
والآن دعونا نقوم بتفصيل الملف سطراً سطراً وتناول محتوياته :
- السطر الأول يُقصد بِه اننا نُريد ان نستخدم الـimage الخاصه بـubuntu المُحدده بالـ"tag: latest" كالصوره الخاصه بالحاويه.
- السطر الثاني يُخبر “Docker” اننا نُريد تشغيل أمرٍ ما على الحاويه الخاصه بنا “التي في هذه الحاله تعمل على ubuntu بما اننا حددنا ذلك كالصوره الرئيسيه في السطر الأول” والذي في هذه الحاله الأمر هو أمر تحديث وتثبيت “أولاً سوف نقوم بتنفيذ أمر update لتحديث مستودع ubuntu بمعلومات الإصدارات الأحدث من الحزم ولكن لن نقوم بترقية النظام، بعد ذلك سنقوم بتنزيل حزمة figlet التي يتطلبها الـscript الذي سنقوم بتنفيذه”.
- السطر الثالث يُخبر “Docker” بنسخ السكربت “print-message.sh” من المُجلد المحلي إلى داخل الحاويه.
- السطر الرابع يُخبر “Docker” بتنفيذ الأمر الذي يقوم بإعطاء صلاحيات التنفيذ للسكربت “حتى يُمكننا تشغيله”.
- السطر الخامس والأخير يُستخدم لتحديد الأمر الإفتراضي الذي سيتم تنفيذه عند تشغيل الحاويه، في هذه الحاله هو السكربت الخاص بنا.
ملف السكربت المذكور في المثال السابق لمن يُريده :
#!/bin/bash
# Define an array of some words
PHRASES=("Hello There!" "I'm Watching YOU" "You're using LINUX!!!")
# Randomly select a word
RANDOM_INDEX=$(( RANDOM % ${#PHRASES[@]} ))
SELECTED_PHRASE=${PHRASES[$RANDOM_INDEX]}
# Print the message with figlet
figlet -w 200 "$SELECTED_PHRASE"
بناء الـImage
والآن سوف نقوم بأخذ الـDockerfile السابق وسوف نقوم ببناء “image” بواسطته، يمكنك تسمية الـ"image" بأي اسم تُريده ولكنني سأُسميها “print-ascii”.
يُمكنك إعطاء اي اسم “tag” تريده ولكن “Docker” بشكلٍ إفتراضي يقوم بإعطاء “tag: latest” لكل صوره إذا لم تحدد واحداً.
ضع بعين الإعتبار أن الـimage تقريباً هي مثل الـfilesystem للحاويه ﻷنها تحتاجها حتى تعمل، ولا يُمكنك إعادة بناء نفس الصوره، اذا كنت تريد التعديل على الملف سوف تحتاج لبناء صوره جديده بنفس الاسم ولكن بـtag مختلف.
لبناء الصوره نحتاج لتنفيذ الأمر التالي :
docker build -t "print-ascii" .
والآن دعونا نقوم بتفصيل الملف سطراً سطراً وتناول محتوياته :
- الـ"flag -t": يُشير إلى الهدف “target” اسم الصوره.
- الـ"." تعني المسار الحالي. وهذا الأمر بكل إختصار ياعزيزي المتابع معناه اننا سوف نقوم ببناء الصوره التي اسمها “print-ascii” من الملفات الموجوده في المسار الحالي.
تشغيل الـImage
- يُمكنك تشغيل الـimage التي قُمت ببنائها عبر الأمر التالي :
docker run print-ascii
أوامر إضافيه ذو فائده
- لعرض جميع الـimage المتواجده لديك في النظام :
docker images
- كما قُلنا سابقاً إذا احتجت تغيير اي شيءٍ في الصوره فسيتعين عليك إعادة بناء الصوره من جديد بـtag مُختلف كالتالي :
docker build -t "print-ascii:new"
الخاتمه
وفي الختام اشكرك جزيل الشُكر ياعزيزي القارئ العسل على وصولك إلى نهاية المدونه بالرغم من طولها فهذا يعني لي الكثير، وأتمنى ان تكون حازت على إعجابك ومن هُنا وحتى لقائنا القادم اتمنى ان تبقى على خيرِ حالٍ وبصحةٍ جيده! وداعاً أتمنى لك يوماً سعيداً 🖤.