العودة إلى المدونة

كيفية نشر تطبيق Node.js (Express.js) باستخدام Docker على Ubuntu 20.04

كيفية نشر تطبيق Node.js (Express.js) باستخدام Docker على Ubuntu 20.04

مقدمة

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

تبدأ عملية بناء تطبيق باستخدام Docker بقيام المطور بإنشاء صورة لتطبيقه. بعد ذلك، سيتم نشر الصورة داخل حاوية. تحتوي الصورة على المكونات المحددة للتطبيق مثل كود التطبيق، والمكتبات، وملفات التكوين، ومتغيرات البيئة، وبيئة التشغيل. تعمل الصورة على توحيد البيئة داخل الحاوية مما يمنح تقنية الحاويات خصائص قابلية النقل. Node.js هي بيئة تشغيل جافا سكريبت خلفية مفتوحة المصدر ومتعددة المنصات يمكنها تنفيذ كود جافا سكريبت خارج متصفح الويب. تم بناؤها فوق محرك V8 JavaScript Engine. Express.js هو إطار عمل جافا سكريبت خلفي بسيط يعمل فوق Node.js.

في هذا البرنامج التعليمي، سنقوم بإنشاء صورة لموقع ويب يعمل على إطار عمل Express. سنستخدم Bootstrap، وهي مكتبة واجهة أمامية، لجعل الواجهة الأمامية تبدو أفضل. بمجرد إنشاء الصورة، سنقوم ببناء حاوية ودفعها إلى Docker Hub. يتيح Docker Hub للمطورين استضافة التطبيقات المعبأة في حاويات لسهولة نشرها في أي بيئة Docker. بمجرد استضافة حاويتك على Docker Hub، سنقوم بسحبها وبناء صورة أخرى تخدم موقعنا بالفعل.

المتطلبات الأساسية

سيكون هذا برنامجًا تعليميًا عمليًا. يجب عليك إنشاء بيئة تمكنك من المتابعة.

الخطوة 1: تكوين تبعيات التطبيق

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

بعد ذلك، انتقل إلى هذا الدليل:

سيكون هذا هو الدليل الجذري لتطبيقك. يتوقع تطبيق node.js وجود ملف package.json في المجلد الجذري. Npm يستخدم هذا الملف لتحديد التبعيات التي يحتاجها تطبيقك. أدخل الأمر التالي لإنشاء هذا الملف:

بعد ذلك، أضف مقتطف الكود التالي إلى الملف. يمكنك تحديث الاسم والمؤلف والوصف وملف نقطة الدخول كما تريد:

كما ترى، يحدد هذا الملف اسم المشروع وإصداره ومؤلفه والترخيص الذي سيتم بموجبه مشاركة كود التطبيق. يوصى باستخدام اسم قصير ووصفي لمشروعك لتجنب التكرار في npm registry. لقد حددنا ISC license للمشروع والذي يسمح بنسخ كود التطبيق أو تعديله أو توزيعه مجانًا.

الأهم من ذلك، يجب عليك ملاحظة التوجيهات التالية في الملف:

  • main”: يحدد هذا التوجيه نقطة الدخول للتطبيق، والتي قمنا بتعيينها كـ index.js. سنقوم بإنشاء هذا الملف قريبًا.
  • dependencies”: يحدد هذا التوجيه تبعيات التطبيق التي سيتم سحبها من سجل npm عندما نقوم بتشغيل الأمر npm، في حالتنا، نريد إصدار Express 4.17.1 وما فوق.

يمكنك الآن حفظ الملف بالضغط على Ctrl + O. ثم إغلاق الملف بالضغط على Ctrl + X. بعد ذلك، سنقوم بتثبيت التبعيات عن طريق تشغيل الأمر التالي:

يقوم الأمر بتثبيت تبعيات التطبيق المحددة في ملف package.json داخل مجلدات node_modules. لقد تم إنشاؤها تلقائيًا عند تشغيل الأمر لأول مرة. مع تثبيت تبعيات تطبيقنا، يمكنك الآن البدء في إضافة كود التطبيق.

الخطوة 2: إضافة ملفات كود التطبيق الخاص بك

سنقوم بإنشاء موقع ويب أساسي للوصفات، مقدم من allrecipes. نقطة الدخول الرئيسية للتطبيق هي ملف index.js. سنقوم بإضافة مجلد views الذي سيحتوي على الصفحات المختلفة والأصول الثابتة للمشروع. سيحتوي موقع الويب على صفحة هبوط تحتوي على معلومات تمهيدية وروابط لبعض الوصفات.

سيتم وضع كود صفحة الهبوط الخاصة بنا في ملف home.html. أولاً، قم بإنشاء ملف index.js عن طريق إدخال الأمر التالي:

أضف الكود التالي، الذي يستورد وينشئ تطبيق Express. كما يحدد كائن Router، والدليل الأساسي، والمنفذ الذي سيتم تقديم هذا التطبيق عليه:

require هي وظيفة JavaScript تقوم بتحميل وحدة (module). في هذه الحالة، نقوم بتحميل وحدة express. بعد ذلك، سنستخدم الوحدة المستوردة لإنشاء كائني express و router. يقوم كائن router بوظائف التوجيه للتطبيق من خلال الاستجابة لاستدعاءات أساليب HTTP التي ستتم إضافتها إلى هذا الكائن مع تقدمنا في البرنامج التعليمي.

لقد قمنا أيضًا بتعيين path و port. يحدد الثابت path الدليل الأساسي للكود. في حالتنا، هو الدليل الفرعي views داخل الدليل الجذري للمشروع. يحدد port المنفذ الذي يجب أن يستمع إليه تطبيق express، في مثالنا، قمنا بتعيينه إلى 8090.

بمجرد حصولنا على الثوابت، يمكننا تحديد بعض المسارات للتطبيق باستخدام كائن router. أضف الكود التالي إلى ملف index.js لتحديد المسارات:

يمكنك إضافة برمجيات وسيطة إلى المسارات باستخدام وظيفة router.use. في هذه الحالة، نضيف وظيفة تقوم بتسجيل طلبات الموجه قبل تمريرها إلى مسارات التطبيق. سيؤدي طلب GET إلى قاعدة التطبيق إلى إرجاع home.html الصفحة. بعد ذلك، قمنا بإضافة صفحات لثلاث وصفات سيتم استردادها أيضًا باستخدام طلب GET لصفحة الوصفة المحددة.

أخيرًا، أضف الكود التالي لتركيب router البرمجية الوسيطة والأصول الثابتة للتطبيق. بالإضافة إلى ذلك، اطلب من تطبيق express الاستماع على المنفذ 8090:

ملف index.js الكامل يجب أن يبدو كالتالي:

يمكنك حفظ الملف وإغلاقه الآن. الخطوة التالية هي إضافة صفحات الويب الثابتة إلى دليل views. ابدأ بإدخال الأمر التالي لإنشاء الدليل:

أدخل الأمر التالي لفتح home.html الخاص بصفحة الهبوط:

أضف الكود التالي إلى الملف. يستورد الكود Bootstrap ويقدم لزوار الموقع بعض المعلومات حول موضوع الموقع:

بالإضافة إلى استيراد Bootstrap، تضيف الصفحة أيضًا قائمة تنقل أساسية لمساعدتنا في التنقل عبر الصفحات والعودة إلى الصفحة الرئيسية. أضفنا أيضًا سطرًا لاستيراد ملف CSS المخصص لدينا:

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

في الملف المفتوح، أضف الكود التالي. سيقوم هذا الملف باستيراد Bootstrap، وملف custom.css ، وتحديد قائمة تنقل وتقديم بعض المعلومات عن وصفة اللازانيا:

دعونا نتبع نفس العملية لإنشاء ملف لصفحة وصفة غواكامولي . افتح الملف باستخدام nano عن طريق تشغيل الأمر التالي:

ثم أضف هذا الكود إلى الملف:

أخيرًا، لنقم بإنشاء ملف banana_bread.html عن طريق إدخال الأمر:

ثم، أضف كود HTML التالي إلى الملف:

الآن، قمنا بإنشاء جميع الصفحات. إذا كنت تتذكر، يتعين علينا إضافة ملف css/custom.css . أدخل الأمر التالي لإنشاء الدليل:

ثم قم بإنشاء الملف وفتحه في محرر nano باستخدام الأمر:

يمكنك إضافة المزيد من أكواد CSS لتنسيق موقع الويب الخاص بك كما تشاء. للإيجاز، دعنا نضيف مقتطف الكود التالي إلى الملف:

احفظ الملف وأغلقه عند الانتهاء.

يمكنك بدء تشغيل التطبيق بما أننا نملك الآن كود مصدر التطبيق والتبعيات الخاصة بالمشروع مثبتة.

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

الآن، يمكنك بدء تشغيل التطبيق. ولكن أولاً، تأكد فقط من أنك في الدليل الجذري للمشروع عن طريق تشغيل الأمر التالي:

ابدأ تشغيل التطبيق باستخدام node index.js. إذا قمت بتحديد نقطة إدخال مختلفة، فاستبدلها بنقطة الإدخال الخاصة بك:

إذا قمت بالانتقال بمتصفحك إلى http://your_public_server_ip:8090، فسترى الصفحة الرئيسية للوصفات كما هي محددة:

Recipes

 

يمكنك رؤية الروابط المؤدية إلى الوصفات المختلفة في شريط التنقل. دعنا ننقر على بعضها. أدناه لدينا صفحة وصفة Lasagna:

Node.js app install on Ubuntu 1

وهنا لدينا صفحة وصفة Guacamole:

Guacamole

حتى هذه النقطة، قمت بإنشاء تطبيقك واختبرت أنه يعمل كما هو متوقع. يمكنك الخروج من الخادم بالضغط على Ctrl + C والانتقال إلى إنشاء ملف Dockerfile. تساعد ملفات Dockerfile في قابلية التوسع من خلال إمكانية إعادة إنشاء نسخة من التطبيق عند الحاجة.

الخطوة 3: إنشاء ملف Dockerfile

يقرأ Docker التعليمات المحددة في Dockerfile عند بناء الصور. وهو يحدد بيئة تشغيل التطبيق. وبالتالي، فإنه يساعد المطورين على تجنب التعارضات مع الاعتماديات أو تغيير إصدارات بيئة التشغيل. أدخل الأمر التالي لإنشاء Dockerfile:

يتم إنشاء صورة Docker باستخدام طبقات متعددة من الصور التي تبنى فوق بعضها البعض. تبدأ بإضافة صورة أساسية لتشكل نقطة البداية للتطبيق.

بما أن التطبيق يتوقع التشغيل في بيئة node.js، سنبدأ بإضافة صورة node:10-alpine لـ node.js. حاليًا، أثناء كتابة هذا البرنامج التعليمي، هذا هو إصدار LTS الموصى به لـ Node.js. لقد اخترنا هذه الصورة المحددة لأنها مشتقة من مشروع Alpine Linux. وبالتالي، ستساعد في إبقاء حجم صورتنا عند الحد الأدنى. هناك عدة متغيرات للصور تحت صفحة صور Node على Docker Hub التي يمكنك الاختيار من بينها بناءً على احتياجاتك.

أضف الكود التالي لتعيين الصورة الأساسية للتطبيق باستخدام توجيه FROM:

تتضمن هذه الصورة Node.js و npm. يجب أن يبدأ كل Dockerfile بتوجيه FROM. تأتي صورة Docker لـ node مع مستخدم node غير جذري افتراضيًا والذي يمكنك استخدامه لتشغيل حاوية تطبيقك كجذر. توصي معايير أمان Docker بعدم تشغيل الحاويات كجذر وتقييد الصلاحيات لتقتصر فقط على تلك المطلوبة لتشغيل مواردها.

في هذه الحالة، سنستخدم الدليل الرئيسي للمستخدم node كدليل عمل للتطبيق بالإضافة إلى المستخدم داخل الحاوية. يمكنك مراجعة دليل أفضل الممارسات لصورة Docker Node لمزيد من المعلومات.

سنقوم بإنشاء الدليل الفرعي node_modules داخل /home/node إلى جانب دليل التطبيق للمساعدة في تبسيط الأذونات الخاصة بكود التطبيق. يضمن إنشاء هذه الأدلة حصولها على الأذونات الصحيحة عندما نقوم بتشغيل الأمر npm install محليًا داخل الحاويات. بمجرد إنشاء الأدلة، يجب عليك تعيين ملكيتها للمستخدم node. سنقوم بذلك داخل Dockerfile عن طريق إضافة السطر التالي:

ثم ستقوم بتعيين دليل العمل عن طريق إضافة السطر التالي:

من الجيد دائمًا تعيين WORKDIR حتى لا يضطر Docker إلى إنشاء واحد افتراضيًا.

أضف السطر التالي لنسخ ملفات package.json و package-lock.json :

يوصى بإضافة تعليمة COPY قبل تشغيل npm install أو نسخ كود مصدر التطبيق. يتيح لك ذلك الاستفادة من آلية التخزين المؤقت لـ Docker. أثناء عملية البناء، يتحقق Docker مما إذا كان لديه طبقة مخزنة مؤقتًا لكل تعليمة. هذا يعني أنه إذا لم تقم بتغيير ملف package.json، فسيستخدم Docker طبقة الصورة الحالية ويتجنب إعادة تثبيت node modules، وبالتالي تسريع عمليات البناء.

قبل تشغيل npm install، أضف السطر التالي لتبديل المستخدم إلى node لضمان أن جميع ملفات التطبيق ودليل node_modules مملوكة لمستخدم node غير الجذري:

حاويتنا الآن جاهزة لتشغيل الأمر npm install. أضف السطر التالي إلى Dockerfile:

بمجرد تثبيت node_modules، أضف السطر التالي الذي سيخبر Docker بنسخ كود التطبيق إلى دليل التطبيق في الحاوية بالأذونات والملكية الصحيحة، أي مستخدم node غير الجذري:

الخطوة الأخيرة هي كشف المنفذ 8090 على الحاوية، كما حددنا في ملف المدخل index.js :

EXPOSE يحدد المنافذ التي ستكون مفتوحة على الحاوية في وقت التشغيل. CMD يقوم بتشغيل الأمر لبدء التطبيق، في هذه الحالة، node index.js.

يجب أن يكون لديك أمر CMD واحد فقط في Dockerfile لأن الأمر الأخير فقط هو الذي يسري مفعوله. يرجى مراجعة وثائق مرجع Dockerfile للحصول على قائمة بالأشياء التي يمكنك القيام بها باستخدام Dockerfile.

يجب أن يبدو ملف Dockerfile الكامل الخاص بك كما يلي:

يمكنك الآن حفظ الملف وإغلاقه.

الشيء التالي الذي تفعله هو إضافة ملف .dockerignore . تمامًا مثل ملف .gitignore ، فإن ملف .dockerignore يحدد الملفات والمجلدات داخل مجلد المشروع التي لا ينبغي نسخها إلى الحاوية.

افتح الملف باستخدام محرر nano:

أضف الأسطر التالية داخل الملف:

إذا كنت تعمل مع مستودع git ، فيجب عليك أيضًا إضافة مجلد .git وملف .gitignore . احفظ الملف وأغلقه.

إذا سارت الأمور على ما يرام، فقد حان الوقت لبناء صورة التطبيق باستخدام أمر docker build . يمكنك إضافة علامة –t إلى أمر docker build لتسمية الصورة باسم يسهل تذكره بدلاً من السلسلة العشوائية التي يحددها docker افتراضيًا. سنقوم أيضًا بدفع الصورة إلى Docker Hub، لذا من الأفضل تضمين اسم مستخدم Docker Hub الخاص بك في العلامة.

سنستخدم nodejs-express-image كاسم للعلامة. أنت حر في اختيار اسم العلامة الذي تفضله. إليك الأمر لبناء الصورة:

تذكر استبدال your_dockerhub_username باسم مستخدم Docker Hub الفعلي الخاص بك. تحدد النقطة (.) في النهاية أن سياق البناء هو المجلد الحالي.

تستغرق عملية البناء دقيقة أو دقيقتين. بمجرد الانتهاء، أدخل الأمر للتحقق من صورك:

يجب أن ترى شيئًا كهذا:

sudo docker images

تذكر أننا استبدلنا your_dockerhub_username باسم مستخدم حقيقي.

بعد التأكد من بناء صورتك، يمكنك الآن إنشاء حاوية باستخدام الصورة باستخدام docker run . سيتم تضمين العلامات التالية:

  • -p: ينشر المنفذ على الحاوية ويرسمه إلى منفذ على النظام المضيف. سنستخدم المنفذ 80 على النظام المضيف لأغراض العرض التوضيحي. ومع ذلك، إذا كان لديك عملية أخرى تعمل على هذا المنفذ، فلا تتردد في تعديل ذلك حسب الضرورة. تعرف على المزيد حول ربط المنافذ من وثائق Docker.
  • -d: للوضع المنفصل. يسمح للحاوية بالاستمرار في العمل في الخلفية.
  • --name: يمكنك استخدام هذا لتعيين اسم يسهل تذكره بدلاً من السماح لـ Docker بتعيين سلسلة عشوائية.

أمر بناء الحاوية هو كما يلي. استبدل اسم مستخدم Docker Hub الخاص بك بشكل مناسب:

انتظر حتى يتم بناء الحاوية وتبدأ في العمل. يمكنك استخدام هذا الأمر لفحص جميع الحاويات قيد التشغيل:

يجب أن ترى مخرجات مشابهة لما يلي:

Node.js app install on Ubuntu 3

كما هو موضح في المخرجات، فإن الحاوية تعمل الآن. يمكنك عرضها في المتصفح إذا قمت بزيارة عنوان IP العام لخادمك دون المنفذ في المتصفح. سيتم تحميل صفحتك الرئيسية:

awesome recipe

 

لقد قمت بنشر موقع ويب ثابت Node Express بنجاح باستخدام Docker. دعنا نرى كيف يمكننا دفع هذه الصورة إلى Docker Hub لاستخدامها في المستقبل ولأغراض التوسيع.

الخطوة 4: العمل مع مستودعات صور Docker

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

استخدم الأمر التالي لتسجيل الدخول إلى حساب Docker Hub الخاص بك. استبدله باسم مستخدم Docker Hub الفعلي الخاص بك:

أدخل كلمة المرور الخاصة بك عندما يُطلب منك ذلك. بمجرد تسجيل الدخول، سيتم إنشاء ملف ~/.docker/config.json في الدليل الرئيسي للمستخدم الخاص بك والذي يحتوي على بيانات اعتماد Docker Hub الخاصة بك.

مع ضبط ذلك، أدخل الأمر التالي لدفع الصورة إلى Docker Hub، مع تحديد العلامة التي قمت بتعيينها عند بناء الصورة سابقًا:

يقوم هذا الأمر بدفع صورة docker إلى حساب Docker Hub الخاص بك. إذا قمت بزيارة حسابك، يمكنك رؤية الصورة التي قمت بدفعها مؤخرًا:

Docker Hub

يمكننا اختبار مدى فائدة مستودع الصور عن طريق تدمير حاوية التطبيق الحالية وإعادة بنائها باستخدام الصورة الموجودة في المستودع.

قم بسرد حاوياتك الحالية عن طريق إدخال الأمر:

يجب أن ترى مخرجات مشابهة لهذا:

Docker Hub

لاحظ CONTAINER ID المدرج في مخرجاتك، وقم بنسخه، واستخدمه لإيقاف الحاوية الخاصة بك باستخدام الأمر، مع استبدال المعرف بالمعرف الخاص بك:

أدخل الأمر التالي لسرد جميع صور docker المتاحة في نظامك:

ستظهر المخرجات اسم صورتك، وصورة node.js، وصورًا أخرى من عملية البناء.

أدخل الأمر التالي لإزالة الصور، بما في ذلك الصور غير المستخدمة أو المعلقة:

اكتب y للتأكيد. يؤدي هذا إلى إزالة الحاويات والصور المتوقفة. إذا قمت بسردها، فسترى قائمة فارغة في المخرجات:

output

الآن، قمت بإزالة كل من الحاوية التي تشغل التطبيق، والصورة نفسها. تعرف على المزيد حول إزالة حاويات وصور وأحجام Docker باتباع برنامجنا التعليمي.

يمكننا الآن إعادة إنشاء العملية بأكملها عن طريق سحب الصورة أولاً من Docker Hub باستخدام الأمر التالي. استبدل اسم مستخدم Docker Hub الخاص بك بشكل مناسب:

قم بسرد صور Docker الخاصة بك مرة أخرى باستخدام الأمر:

يجب أن ترى الصورة في المخرجات:

sudo docker

يمكنك الآن إعادة بناء حاويتك باستخدام الأمر من الخطوة 3. بالطبع، استبدل اسم مستخدم Docker Hub الخاص بك حيثما كان ذلك مناسبًا:

قم بسرد حاوياتك للتأكد من أنه قد تم إعادة بنائها:

يجب أن ترى مخرجات مشابهة:

في متصفحك، انتقل إلى عنوان IP العام لخادمك ويجب أن ترى تطبيقك قيد التشغيل.

الخاتمة

إذا كنت قد تابعت البرنامج التعليمي حتى هذه النقطة، فلديك الآن موقع ويب ثابت تم إنشاؤه باستخدام Express و Bootstrap، وتم نشره باستخدام Docker. لقد استخدمت ملفات موقع الويب الثابت لبناء صورة Docker واستخدمت الصورة لإنشاء حاوية. ثم قمت بدفع الصورة إلى سجل صور Docker، Docker Hub، مما يجعلها متاحة للاستخدام المستقبلي أو لتوسيع نطاقها. لاختبار استخدام سجل الصور، قمت بتدمير الصور والحاويات، وسحبت الصور من السجل، وأعدت بناء الحاويات.

شرح هذا البرنامج التعليمي كيفية نشر تطبيق Node.js. إذا كنت ترغب في معرفة كيفية استخدام بيئة تطوير ويب مختلفة، فلدينا برنامج تعليمي حول نشر تطبيق Laravel باستخدام Docker Compose على Nginx.

لمزيد من الموارد حول استخدام Docker، راجع البرامج التعليمية التالية:

حوسبة سعيدة!

author

Hark Labs

المؤلف · CloudSigma

Preslav Dobrev هو مصمم إبداعي في CloudSigma، يركز على هوية أعمال متسقة باستخدام قنوات التسويق التقليدية والمبتكرة. هو بارع في دمج الرؤية الفنية مع التسويق الاستراتيجي لخلق سرد قصصي مؤثر للعلامة التجارية.

التعليقات

لا توجد تعليقات بعد. كن أول من يعلق.