في هذا الموضوع سوف نتحدث عن كيفية بناء ال Docker Image وكيف نقوم بوضع موقعنا ك Image ومن ثم نقوم بتشغيلها، وسوف نقوم بالتعامل مع Static Website مكون من ملفات جافا سكربت و HTML ونشغله ك docker container ومن ثم تصفحه بواسطة المتصفح. وأخيراً سوف نتحدث عن ال Dockerfile وكيف يسهل بناء ال Images بسهولة.
المواضيع في السلسلة:
- مقدمة حول دوكر Docker
- البداية مع دوكر Docker
- مشاركة المجلدات في دوكر Docker
- بناء ال Docker Images (الموضوع الحالي)
- تشغيل قواعد البيانات في دوكر Database in Docker
- تشغيل البرامج باستخدام ال Docker Compose
ولكي نقوم بتشغيل الموقع في دوكر، يجب أن يتم تطوير الموقع اولاً، وفي حالتنا هذه فالموقع جاهز وهو Angular Web Site، بعد ذلك هناك العديد من الخيارات:
- تنزيل nginx image ومن ثم وضع ملفات الموقع في مجلد ما وعمل mount لهذا المجلد ومن ثم تشغيل ال container بهذا الملفات.
- تنزيل nginx image ومن ثم نسخ ملفات الموقع الى داخل ال Container File system.
- بناء Image بها الملفات الخاصة بالموقع ومن ثم تشغيل ال Container منها ولن تحتاج لنسخ او أي ملفات لأن كل شيء متواجد بداخلها
الصورة التالية تبين الخطوات الثلاثة التي يمكن القيام بها لتشغيل الموقع بداخل دوكر:
قبل أن نبدأ في شرح الطرق الثلاثة هذه، قم بتحميل الموقع من هذا الرابط وبعد التحميل قم بفك الضغط وانسخ المجلد solitaire الى أي مسار تريده، وليكن ال C:\ ، وبالتالي سوف يكون المجلد متواجد على القرص السي مباشرة.
تشغيل الموقع عن طريق ال Mounting
لقد تناولنا هذه الطريقة في الموضوع السابق وهي بسيطة، حيث يتم تشغيل البرنامج المطلوب وهو في حالتنا أي ويب سيرفر مثل nginx ويتم تحديد ال –v بمسار الملفات في النظام الأساسي ومن ثم : ومن ثم المسار بداخل ال container ويكون بصيغة ذلك النظام الذي يعمل عليه. الصورة التالية تبين الامر لتشغيل ال container وتم استخدام ال –p لكي يتم تحديد البورت في الجهاز الأساسي والبورت الذي يعمل به الموقع في ال container.
لاحظ المسار بداخل ال container وغالباً لكل ويب سيرفر مسار خاص به، ويجب الرجوع للتوثيق الخاص بال nginx في ال docker hub لكي تعرف المسار المناسب لكي يعمل الموقع.
الآن قم بفتح ال localhost:8081 وسوف تجد أن اللعبة تعمل لديك:
تشغيل الموقع عن طريق نسخ الملفات لل Container
كما ذكرنا أن الدوكر يعطي Isolation لنظام الملفات، فلن تستطيع ال Container الوصول لنظام ملفات النظام الأساسي، الا في حال ال Mounting/Volume فقط ويكون بحسب ما تم تحديده بها، والطريقة الثانية هي بنسخ الملفات من النظام الأساسي الى ال Container كما هو الحال عندما يتم نقل الملفات من جهاز لجهاز أخر.
سوف نقوم اولاً بتشغيل ال nginx container في الخلفية –d وقمنا بوضع اسم لها –name، وبعدها قمنا بطباعة docker ps لكي تتأكد من أنها تعمل ولها الاسم الذي تم إعطائه لها، يمكنك الان الذهاب للمتصفح وسوف تجد ان الموقع الرئيسية بصفحة ال nginx الافتراضية تعمل.
سوف نقوم الآن بالدخول لهذه ال container التي تعمل، وسوف نستخدم الأمر docker exec الذي تناولناه سابقاً وهو لتشغيل برنامج اخر بداخل نفس ال container، وهذا الأمر يأخذ اسم ال container أو ال ID ولذلك قمنا بتسمية ال container باي اسم (واخترنا nginx) وسوف نحدده الان عند الأمر exec.
بعد الدخول على الشل قمنا بعرض الملفات وكما هو واضح فنظام الملفات مختلف تماماً عن النظام الأساسي، ويمكن الدخول على المسار /usr/share/nginx/html وسوف تجد المسار فارغاً ونحن نريد تعبئته بالملفات من النظام الأساسي، بعد ذلك يمكنك الخروج من الشل باستخدام الأمر exit. اذاً هذه الخطوة فقط للمشاهدة والتأكد من ان المسار فارغاً، والخطوة الضرورية هي النسخ وذلك من خلال الأمر docker cp وهذا الأمر يأخذ معاملين الأول هو المسار من النظام الأساسي، ومن ثم اسم او معرف ال container التي تعمل ومن ثم : ومن ثم المسار الذي تريد النسخ عليه، الصورة التالية تبين كيفية النسخ بهذا الأمر:
الآن يمكنك الدخول بالشل مجدداً كما في الخطوة قبل السابقة والتأكد من وجود الملفات، أو يمكنك الذهاب للمتصفح والدخول ومشاهدة الموقع الآن.
تشغيل الموقع عن طريق وضع كامل الملفات على شكل Image
والطريقة لذلك هي نفس خطوات الطريقة الثانية، حيث نقوم أولاً بتشغيل ال container ومن ثم بنسخ الملفات بداخلها، وبعد الانتهاء وكل شيء نقوم بأخذ صورة Snapshot للحالة الحالية وهي سوف تعتبر Image ويمكن تشغيل ال Image مباشرة فيما بعد ويكون بداخلها كل الملفات.
اذاّ يتم تشغيل ال Container من خلال ال Image، ويتم عمل ال Image من خلال صورة أو commit لل Container التي تعمل، وسوف نستخدم الأمر commit ويتم تحديد اسم او معرف ال Container ومن ثم ال Image الجديدة، وايضاً يمكن تحديد ال Tag الذي تريدها.
الآن سوف نقوم بتشغيل Container جديدة من ال Image الجديدة والتي بها كل شيء بدون ان نحتاج لنسخ أي ملفات أخرى، كما يلي:
ولاحظ أنه في هذه المرة حددنا اسم ال Image التي قمنا بعملها وليس ال nginx فقط، وتستطيع الان زيارة الموقع localhost:8090 وسوف تجده يعمل ايضاً.
للتذكير، فقد بدئنا أولاً بأخذ ال nginx Image والتي تحتوي على ملفات نظام التشغيل الأساسية، وبها برنامج nginx نفسه، وبعد ذلك عندما نقوم بتشغيل ال Container فسوف يتم إضافة layer جديدة قابلة للقراءة والكتابة وهي التي نضع بها الملفات الخاصة بنا.
ولأن كل Layer بها ملفات خاصة فسوف يتم عمل دمج بين كل هذه الملفات حتى تكون في نظام الملفات وذلك باستخدام عملية ال Union File System، مثلاً الصورة التالية تعرض ال Container مكون من عدة طبقات واخيراً الطبقة الأولى التي يمكن الكتابة عليها، ومن ثم حصل الدمج Union بين الملفات في تلك الطبقات لنحصل على نظام ملفات واحد.
هنا العديد من الأشياء التي تحدث أثناء دمج الملفات:
- إذا كان هناك ملف اسمه txt في طبقة سفلية، ومن ثم حصل تغيير في ذلك الملف في الطبقة الأعلى فسوف يتم اجراء ما في الطبقة العليا، أو حتى في حال الحذف فسوف يتم الحذف ايضاً، لذلك الطبقة العليا تفوز دائماً.
- الطبقة العليا تحتوي على التغييرات للطبقة السفلى فقط، سواءً إضافة ملفات، تحديث ملفات، أو حتى حذف ملفات. وهذا ما يجعلها صغيرة ولن تحتاج لوضع كل الملفات الموجودة في طبقة أسفل منها.
وهكذا عندما قمنا بنسخ ملفات الموقع في ال container التي بدئت بال nginx image وقمنا بعمل Image جديدة فسوف تكون ال Image الجديدة مكونة من كل الطبقات في ال nginx image بالإضافة الى طبقة واحدة جديدة بها الملفات، وذلك من خلال الأمر docker commit.
الصورة التالية توضح ذلك حيث يوضح حجم ال image الجديدة ذلك التغيير:
وبعد أن قمنا بتشغيل ال container من ال image الجديدة سوف يعمل وتضاف الطبقة الأولى الخاصة بالكتابة والقراءة لذلك ال container حتى يستطيع إضافة أي تعديلات يريدها ويمكن بعد ذلك حفظ image أخرى وهكذا.
يمكنك أن تقوم بعمل export لل image وتقوم بفك ضغطها ومشاهدة الملفات الخاصة بالموقع في أحد المجلدات كما قمنا بذلك في الموضوع السابق.
استخدام ال Dockerfile بدلاً من إعادة كتابة الأوامر
لقد قمنا بالعديد من الخطوات حتى نقوم بعمل Image خاصة بنا:
- تشغيل container يعتمد على nginx image من خلال الأمر docker run –d –p 8080:80 –name nginx وهذا الأمر سيقوم بتنزيل nginx image وتشغيل container في الخلفية ويعطيه اسم nginx
- نسخ الملفات من النظام الأساسي الى مجلد بداخل الويب سيرفر في ال nginx container التي تعمل الأن من خلال الأمر docker cp .\app\. nginx:/usr/share/nginx/html
- أخذ صورة من ال nginx container من خلال الأمر: docker commit nginx solitaire:nginx وتم تسميتها بالاسم solitaire ووضع تاق بها ايضاً nginx.
- وقد تحتاج لأوامر نسخ أخرى او حذف لملفات معينة وسوف تكون موجود هنا، مثلاً تريد وضع اعدادات خاصة لل nginx او حذف الكاش او غيرها من الأمور، وكلها تكون قبل ال committing لل container حتى تخرج ال image الجديدة
كل هذه الخطوات حتى تنشئ ال image التي تريدها، وبدل من أن تكتبها في كل مرة فيمكنك وضعها في ملف سكربت اسمه Dockerfile وسوف يقوم دوكر بتشغيلها واحداً تلو الأخر، وسوف نقوم الآن بتحويل الأوامر أعلاه الى Dockerfile
- بدلاً من تشغيل Container ونسخ ملفات فيه، فسوف نقوم بتحديد ال Image وذلك من خلال الأمر FROM nginx
- نسخ الملفات وذلك من خلال الأمر COPY app /usr/share/nginx/html
- انتهينا من الملف ونقوم بحفظه، وسوف نقوم ببناء ال image وذلك من خلال الأمر docker build ويتم تمرير ملف ال Dockerfile لها، ويتم تمرير اسم ال image الجديدة لها ايضاً، وذلك من خلال الأمر docker build –f Dockerfile –t solitaire:nginx . ويمكن اختصار الأمر الى docker build –t solitaire:nginx . في حال تم تسمية ال Dockerfile بالاسم الافتراضي. المعامل الأخير هو مسار التي يتواجد عليه الملف وهو . وتعني المسار الحالي.
الصورة التالية توضح الخطوات فقمنا بإنشاء الملف في نفس المسار solitaire folder وقمنا بوضع محتوى ال Dockerfile وقمنا ببنائه كما يلي:
لكل أمر سيتم تطبيقه على حدة، وأول أمر FROM nginx سوف يقوم فعلياً بتنزيل ال image إذا لم تكن موجودة، ومن ثم بتشغيلها، وبعد ذلك ينتقل للخطوة التالية وهي نسخ الملفات بداخلها، وبعد ذلك تم حذف ال container التي استخدمت اثناء عملية نقل الملفات، واخيراً تم حفظ ال image الجديدة، وظهر تحذير بأنه تم بناء Linux container في ويندوز ولكنه عادي أثناء التطوير، لكن في ال production فيفضل البناء على لينوكس إذا كنت تستخدم ال Linux Container.
يمكنك الآن ان تستعرض ال images الموجودة وسوف ترى ال image الجديدة:
وسوف تكون بنفس الحجم لل image التي قمنا بإنشائها يدوياً، وهذا يعني أن النتيجة هي واحدة سواءً بكتابة كافة الأوامر، أو من خلال الاستفادة من ال Dockerfile وبنائه وهو الأسهل بالتأكيد.
يمكنك كتدريب أن تقوم بالتحويل الى Windows Container ومن ثم استضافة وتشغيل الموقع على ال iis بدلاً من ال nginx وذلك بتغيير ال nginx في Dockerfile الى iis:nanoserver وايضاً تغيير مسار الملفات على الويب سيرفر الى مسار ال iis وهو C:\inetpub\www وسيعمل الموقع بلا مشاكل على ال Windows Container.
رفع ال Image على ال Docker hub
بعد أن قمنا بعمل ال Images بعدة طرق فقد تريد مشاركتها سواءً لمطور اخر او لسيرفر اخر يقوم بتنزيلها وتشغيل النسخة مباشرة، وسوف نقوم برفعها على ال Docker Hub، وللقيام بذلك يجب تسجيل حساب في ال Docker Hub وبعد ذلك سوف ترفعها على اسم المستخدم الخاص بك، ويجب أن نقوم بتسمية ال image بما بتناسب مع الحساب حتى يتم رفعها بشكل صحيحاً.
سوف نظهر الآن جميع ال images الموجودة:
وبعد ذلك نقوم بتسمية ال Image وسوف نستخدم الأمر docker tag ويتم تمرير اسم ال image الموجودة، والمعامل الثاني هو الاسم الجديد التي نريد رفعها باسم الحساب، فمثلاً اسم حسابي هو wajdyessam فسوف يكون اسمها wajdyessam/new_name، كما يلي:
بعد ذلك سوف نستخدم الأمر docker push ويتم تمرير اسم ال Image التي نريد رفعها وسوف يتم رفعها مباشرة في الحساب:
هذه الخطوة تستوجب أنك قمت من قبل بالدخول على حسابك في الدوكر Hub، فاذا حصلت على رسالة خطأ Authentication Required فيجب عليك الدخول لحسابك أولاً قبل رفعك لل Image وذلك من خلال الأمر docker login ومن ثم سوف يطلب منك اسم المستخدم وكلمة المرور وسوف تحصل على رسالة بأنه تم تسجيل الدخول بنجاح.
الآن تستطيع الدخول لحسابك وسوف تجد ال Image مرفوعة، وكما يمكنك تشغيلها مباشرة بالأمر docker run –d wajdyessam/solitaire من أي جهاز تريده.
وصلنا لنهاية الموضوع، وتعرفنا على ال Dockerfile وانه سهل الكثير من الخطوات لبناء ال Image والتي يتم اخذ صورة من ال Container الذي يعمل حتى يتم بنائها، الموضوع القادم سوف نتحدث عن تشغيل قواعد البيانات في ال Containers.
جزاكم الله تعالى كل خير