تتيح منصة Docker للمطورين تحزيم وتنفيذ التطبيقات على شكل حاويات (containers). وتعدّ الحاوية عملية (process) منعزلة تعمل على نظام تشغيل مشترك، وتوفر بديلاً أخفّ من الأجهزة الافتراضية (virtual machines) . رغم أن الحاويات ليست جديدة، إلا أن لها فوائد عديدة، من بينها عزل العمليات وتوحيد البيئة، وتزداد أهميتها نظرًا لتزايد إقبال المطورين على استخدام بنية التطبيقات الموزعة.
عند بناء تطبيق وتوسيع نطاقه باستخدام Docker، تكون نقطة البداية عادةً هي إنشاء صورة للتطبيق، والتي يمكنك تنفيذها بعد ذلك في حاوية. تتضمن الصورة شيفرة التطبيق والمكتبات وملفات التكوين ومتغيرات البيئة ووقت التشغيل. ويضمن استخدام صورة ما أن تكون البيئة في حاويتك موحدة ومتضمّنة فقط لما هو ضروري لإنشاء التطبيق وتنفيذه.
ستنشئ في هذا الدرس صورة تطبيق لموقع ويب ثابت يستخدم إطار عمل Express و Bootstrap. وستنشئ بعد ذلك حاوية باستخدام تلك الصورة ورفعها إلى Docker Hub للاستخدام المستقبلي. أخيرًا، ستتمكّن من سحب الصورة المخزنة من مستودع Docker Hub الخاص بك وتنشئ حاوية أخرى، مع توضيح كيف يمكنك إعادة إنشاء التطبيق وتوسيع نطاقه.
المتطلبات الأساسية
سوف تحتاج من أجل متابعة هذه السلسلة إلى العناصر التالية:
- خادم Ubuntu 18.04 يمكنك إعداده باتباع دليل إعداد الخادم الأولي.
- تثبيت Docker على الخادم الخاص بك، باتباع الخطوتين 1 و 2 في دليل كيفية تثبيت واستخدام Docker على Ubuntu 18.04.
- تثبيت Node.js و npm، باتباع هذه الإرشادات تحديدًا التّثبيت باستخدام أرشيف الحزم الشّخصي PPA المدار بواسطة NodeSource.
- حساب Docker Hub. لإلقاء نظرة عامة حول كيفية إعداده، راجع هذه المقدمة عن بدء استخدام Docker Hub.
الخطوة الأولى: تثبيت الاعتماديات لتطبيقك
لإنشاء الصورة، ستحتاج أولاً إلى إنشاء ملفات التطبيق الخاصة بك والتي يمكنك بعد ذلك نسخها إلى حاويتك. ستتضمن هذه الملفات المحتوى الثابت للتطبيق والشيفرة والاعتماديات.
أنشئ في البداية مجلًدًا لمشروعك في المجلّد الرئيسي للمستخدم غير الجذري. سنستدعي node_project
الخاص بنا، لكن يمكنك استبداله بشيء آخر:
$ mkdir node_project
انتقل إلى هذا المجلّد:
$ cd node_project
سيكون هذا هو المجلّد الرئيسي للمشروع.
أنشئ بعد ذلك ملف [package.json](https://docs.npmjs.com/files/package.json)
باعتماديات مشروعك ومعلومات التعريف الأخرى. افتح الملف باستخدام nano
أو المحرر المفضل لديك:
$ nano package.json
أضف المعلومات التالية حول المشروع، بما في ذلك اسم المشروع وصاحبه والترخيص ونقطة الدخول والاعتماديات. تأكد من استبدال معلومات صاحب المشروع باسمك ومعلومات الاتصال الخاصة بك:
- الملف :~/node_project/package.json
{ "name": "nodejs-image-demo", "version": "1.0.0", "description": "nodejs image demo", "author": "Sammy the Shark <sammy@example.com>", "license": "MIT", "main": "app.js", "keywords": [ "nodejs", "bootstrap", "express" ], "dependencies": { "express": "^4.16.4" } }
يحتوي هذا الملف على اسم المشروع وصاحبه والترخيص الذي تتم مشاركته بموجبه. ينصح npm بجعل اسم المشروع قصيرًا وذا دلالة وصفية مع تجنب التكرار في سجل npm. لقد أدرجنا ترخيص MIT في حقل الترخيص، مما يتيح الاستخدام المجاني لشيفرة التطبيق وتوزيعه.
بالإضافة إلى ذلك، يحدد الملف العناصر التالية:
-
"main"
: نقطة دخول التطبيقapp.js
، ستقوم بإنشاء هذا الملف بعد ذلك. -
"dependencies"
: اعتماديات المشروع، في هذه الحالة، Express إصدار 4.16.4 أو أعلى منه.
ورغم أن هذا الملف لا يحتوي على مستودعٍ، فيمكنك إضافته باتباع هذه الإرشادات حول إضافة مستودع إلى ملف package.json
الخاص بك. وتعدّ هذه إضافةً جيدةً إذا كنت تقوم بإصدار تطبيقك.
احفظ الملف وأغلقه عندما تنتهي من إجراء التعديلات.
لتثبيت اعتماديات مشروعك، نفّذ الأمر التالي:
$ npm install
سيؤدي ذلك إلى تثبيت الحزم التي أدرجتها في ملف package.json
في مجلّد المشروع الخاص بك.
يمكننا الآن الانتقال إلى بناء ملفات التطبيق.
الخطوة الثانية: إنشاء ملفات التطبيق
سنعمل على إنشاء موقع ويب يقدم للمستخدمين معلومات حول أسماك القرش. سيكون لدى لتطبيق نقطة دخول رئيسية و ملفّ app.js
ومجلّد views
يتضمن الأصول الثابتة للمشروع. ستوفر صفحة الهبوط index.html
للمستخدمين بعض المعلومات الأولية ورابطًا نحو صفحة تحتوي على معلومات أكثر تفصيلًا عن أسماك القرش، sharks.html
. سننشئ في مجلّد views
كلًّا من صفحة الهبوط و الصفحة sharks.html
.
في البداية، افتح ملفّ app.js
في مجلّد المشروع الرئيسي لتحديد مسارات المشروع:
$ nano app.js
سيعمل الجزء الأول من الملف على إنشاء تطبيق Express وكائنات الموجِّه، وتحديد المجلّد الأساسي والمنفذ كثوابت:
- الملف :~/node_project/app.js
const express = require('express'); const app = express(); const router = express.Router(); const path = __dirname + '/views/'; const port = 8080;
تحمّل الداّلة require
الوحدة express
التي نستخدمها فيما بعد لإنشاء الكائنات app
و router
. سيؤدي الكائن router
وظيفة التوجيه الخاصة بالتطبيق، وعندما نحدد مسارات طرق HTTP، سنضيفها إلى هذا الكائن لتحديد كيفية تعامل التطبيق مع الطلبات.
يعين هذا الجزء من الملف أيضًا ثابتتي المسار path
والمنفذ port
: *path
: يحدد المجلّد الأساسي، والذي سيكون المجلّد الفرعي ل views
داخل مجلّد المشروع الحالي.
-
port
: يطلب من التطبيق الاستماع على المنفذ8080
.
بعد ذلك، حدّد مسارات التطبيق باستخدام الكائن router
:
-
الملف
~/node_project/app.js
:
router.use(function (req,res,next) { console.log('/' + req.method); next(); }); router.get('/', function(req,res){ res.sendFile(path + 'index.html'); }); router.get('/sharks', function(req,res){ res.sendFile(path + 'sharks.html'); });
تحمّل الدالّة router.use
دالّة وسيطة تعمل على تسجيل طلبات الموجه وتمررها إلى مسارات التطبيق. تُحدّد هذه المسارات في الدوالّ الموالية، والتي تنصّ على أن تنفيذ الأمر GET على عنوان URL للمشروع الأساسي يجب أن يُرجع الصفحة index.html
، بينما يجب أن يُرجع تنفيذ الأمر GET على المسار sharks/
الصفحة sharks.html
.
ختامًا، صل بين البرمجية الوسيطة router
والأصول الثابتة للتطبيق واجعل التطبيق يستمع على المنفذ 8080
:
~/node_project/app.js ... app.use(express.static(path)); app.use('/', router); app.listen(port, function () { console.log('Example app listening on port 8080!') })
سيبدو ملف app.js
النهائي كما يلي:
const express = require('express'); const app = express(); const router = express.Router(); const path = __dirname + '/views/'; const port = 8080; router.use(function (req,res,next) { console.log('/' + req.method); next(); }); router.get('/', function(req,res){ res.sendFile(path + 'index.html'); }); router.get('/sharks', function(req,res){ res.sendFile(path + 'sharks.html'); }); app.use(express.static(path)); app.use('/', router); app.listen(port, function () { console.log('Example app listening on port 8080!') })
احفظ الملف وأغلقه عند الانتهاء.
بعد ذلك، دعنا نضيف بعض المحتوى الثابت إلى التطبيق. ابدأ بإنشاء المجلد views
:
$ mkdir views
افتح ملف صفحة الهبوط index.html
:
$ nano views/index.html
أضف الشيفرة التالية إلى الملف، الذي سيعمل على استيراد Bootstrap وإنشاء مكوّن jumbotron مع رابط إلى صفحة المعلومات المفصّلة sharks.html
:
-
الملف
~/node_project/views/index.html
:
<!DOCTYPE html> <html lang="en"> <head> <title>About Sharks</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <link href="css/styles.css" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css"> </head> <body> <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"> <div class="container"> <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> </button> <a class="navbar-brand" href="#">Everything Sharks</a> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav mr-auto"> <li class="active nav-item"><a href="/" class="nav-link">Home</a> </li> <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a> </li> </ul> </div> </div> </nav> <div class="jumbotron"> <div class="container"> <h1>Want to Learn About Sharks?</h1> <p>Are you ready to learn about sharks?</p> <br> <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a> </p> </div> </div> <div class="container"> <div class="row"> <div class="col-lg-6"> <h3>Not all sharks are alike</h3> <p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans. </p> </div> <div class="col-lg-6"> <h3>Sharks are ancient</h3> <p>There is evidence to suggest that sharks lived up to 400 million years ago. </p> </div> </div> </div> </body> </html>
يتيح شريط التنقل في الأعلى للمستخدمين المرور بين الصفحة الرئيسية وصفحة أسماك القرش. في المكون الفرعي navbar-nav
، نستخدم الصنف active
في Bootstrap للإشارة إلى الصفحة الحالية للمستخدم. لقد حددنا أيضًا الطرق المؤدية إلى الصفحات الثابتة لدينا، والتي تتوافق مع الطرق التي حددناها في app.js
:
-
الملف
~/node_project/views/index.html
:
... <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav mr-auto"> <li class="active nav-item"><a href="/" class="nav-link">Home</a> </li> <li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a> </li> </ul> </div> ...
بالإضافة إلى ذلك، أنشأنا رابطًا إلى صفحة معلومات سمك القرش في زر jumbotron الخاص بنا:
-
الملف
~/node_project/views/index.html
:
... <div class="jumbotron"> <div class="container"> <h1>Want to Learn About Sharks?</h1> <p>Are you ready to learn about sharks?</p> <br> <p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a> </p> </div> </div> ...
يوجد أيضًا رابط إلى ورقة أنماط مخصصة في عنصر الترويسة header:
-
الملف
~/node_project/views/index.html
:
... <link href="css/styles.css" rel="stylesheet"> ...
سننشئ ورقة الأنماط هذه في نهاية هذه الخطوة.
احفظ الملف وأغلقه عند الانتهاء.
يمكننا، من خلال صفحة الهبوط، إنشاء صفحة معلومات أسماك القرش sharks.html
، والتي ستوفر للمستخدمين المهتمين مزيدًا من المعلومات حول أسماك القرش.
افتح الملف:
$ nano views/sharks.html
-
الملف
~/node_project/views/sharks.html
:
<!DOCTYPE html> <html lang="en"> <head> <title>About Sharks</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <link href="css/styles.css" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css"> </head> <nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md"> <div class="container"> <button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> </button> <a class="navbar-brand" href="/">Everything Sharks</a> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav mr-auto"> <li class="nav-item"><a href="/" class="nav-link">Home</a> </li> <li class="active nav-item"><a href="/sharks" class="nav-link">Sharks</a> </li> </ul> </div> </div> </nav> <div class="jumbotron text-center"> <h1>Shark Info</h1> </div> <div class="container"> <div class="row"> <div class="col-lg-6"> <p> <div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans. </div> <img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark"> </p> </div> <div class="col-lg-6"> <p> <div class="caption">Other sharks are known to be friendly and welcoming!</div> <img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark"> </p> </div> </div> </div> </html>
لاحظ أنه في هذا الملف، نستخدم مرة أخرى الصنف active
للإشارة إلى الصفحة الحالية.
احفظ الملف وأغلقه عند الانتهاء.
ختامًا ، أنشئ ورقة الأنماط المخصصة CSS التي ربطتها بالصفحتين index.html
و sharks.html
، وذلك بإنشاء ملف css
أولاً في المجلّد views
:
$ mkdir views/css
افتح ورقة الأنماط:
nano views/css/styles.css
أضف الشيفرة التالية التي ستحدد اللون والخط المطلوب لصفحاتنا:
-
الملف
~/node_project/views/css/styles.css
:
.navbar { margin-bottom: 0; } body { background: #020A1B; color: #ffffff; font-family: 'Merriweather', sans-serif; } h1, h2 { font-weight: bold; } p { font-size: 16px; color: #ffffff; } .jumbotron { background: #0048CD; color: white; text-align: center; } .jumbotron p { color: white; font-size: 26px; } .btn-primary { color: #fff; text-color: #000000; border-color: white; margin-bottom: 5px; } img, video, audio { margin-top: 20px; max-width: 80%; } div.caption: { float: left; clear: both; }
بالإضافة إلى تعيين الخط واللون، يحدّد هذا الملف أيضًا حجم الصور بتحديد عرض أقصى يبلغ 80٪. هذا سيمنعها من شغل مساحة في الصفحة أكبر مما نريد.
احفظ الملف وأغلقه عند الانتهاء.
بعد إنشاء ملفات التطبيق وتثبيت اعتماديات المشروع، تكون جاهزًا لتشغيل التطبيق.
إذا كنت قد تابعت دليل إعداد الخادم الأولي المذكور في المتطلبات الأساسية، فسيكون لديك جدار حماية نشط يسمح فقط بحركة مرور SSH. للسماح بحركة المرور عبر المنفذ 8080
، نفّذ الأمر التالي :
$ sudo ufw allow 8080
لتشغيل التطبيق، تأكد من وجودك في المجلد الرئيسي للمشروع:
$ cd ~/node_project
ابدأ تشغيل التطبيق باستخدام node app.js
:
$ node app.js
انتقل بمتصفّحك إلى http://your_server_ip:8080
. وستظهر لك صفحة الهبوط التالية:
انقر على زر الحصول على معلومات القرش Get shark info. وستظهر لك صفحة المعلومات التالية:
لديك الآن تطبيق قيد التشغيل. عندما تكون جاهزًا، أوقف الخادم بكتابة CTRL+C
. يمكننا الآن الانتقال إلى إنشاء ملف Dockerfile الذي سيتيح لنا إعادة إنشاء هذا التطبيق وتوسيع نطاقه حسب الرغبة.
الخطوة الثالثة: كتابة ملف Dockerfile
يحدد ملف Dockerfile الخاص بك ما سيتم تضمينه في حاوية التطبيق عند تنفيذه. ويتيح لك استخدام هذا الملفّ تحديد بيئة الحاوية وتجنب التناقضات مع الاعتماديات أو إصدارات وقت التشغيل.
باتباع هذه الإرشادات حول إنشاء حاويات محسّنة، سنجعل صورة التطبيق أكثر فاعلية قدر الإمكان عن طريق تقليل عدد طبقات الصورة وتحديد وظيفة الصورة في غرض واحد هو إعادة إنشاء ملفات التطبيق والمحتوى الثابت.
في المجلّد الرئيسي لمشروعك، أنشئ الملف Dockerfile:
$ nano Dockerfile
تُنشَأ صور Docker باستخدام سلسلة متتالية من الصور ذات الطبقات التي تعتمد على بعضها بعضًا. ستكون خطوتنا الأولى هي إضافة الصورة الأساسية للتطبيق والتي ستشكل نقطة انطلاق إنشاء التطبيق.
لنستخدم الصورة node:10-alpine
. ويمكننا الحصول على الصورة alpine
من مشروع Alpine Linux لكي تساعدنا في تقليل حجم الصور لدينا.
أضف تعليمات FROM
التالية لتعيين الصورة الأساسية للتطبيق:
-
الملف
~/node_project/Dockerfile
:
FROM node:10-alpine
تتضمن هذه الصورة Node.js
و npm
. ويجب أن يبتدئ كل ملفّ Dockerfile بتعليمات FROM
.
بشكل افتراضي، تشتمل صورة Docker Node على مستخدم Node غير جذري يمكنك استخدامه لتجنب تشغيل حاوية التطبيق باستخدام الحساب الجذري. إنها ممارسة أمان موصى بها لتجنب تشغيل الحاويات باستخدام root وتقييد الصلاحيات داخل الحاوية في تلك المطلوبة فقط لتنفيذ عملياتها. لذلك، سوف نستخدم المجلّد الرئيسي لمستخدم Node كمجلّد العمل لتطبيقنا ونعيّنه كمستخدم داخل الحاوية. لمزيد من المعلومات حول أفضل الممارسات عند العمل مع صورة Docker Node، راجع دليل أفضل الممارسات هذا إذا كانت لغتك الانجليزية جيدة.
لضبط الأذونات على شيفرة تطبيقنا في الحاوية، دعنا ننشئ المجلّد الفرعي node_modules
في /home/node
رفقة المجلّد app
. سيضمن إنشاء هذه المجلّدات أنها تتوفّر على الأذونات التي نريدها، والتي ستكون مهمة عندما ننشئ وحدات node محلية في الحاوية باستخدام npm install
. بالإضافة إلى إنشاء هذه المجلّدات، سنعطي ملكيتها للمستخدم node: -الملف ~/node_project/Dockerfile
:
... RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
عيّن بعد ذلك مجلّد العمل للتطبيق على /home/node/app
:
-
الملف
~/node_project/Dockerfile :
... WORKDIR /home/node/app
إذا لم يتم تعيين مجلّد عمل WORKDIR
، فسوف يُنشئ Docker واحدًا افتراضيًا، لذلك من الجيد تعيينه بشكل صريح.
بعد ذلك، انسخ ملفات package.json
و package-lock.json
(بالنسبة لملفات الإصدار الخامس npm فما فوق):
-
الملف
~/node_project/Dockerfile
:
... COPY package*.json ./
تتيح إضافة تعليمة COPY
قبل تنفيذ npm install
تثبيت أو نسخ شيفرة التطبيق الاستفادة من آلية التخزين المؤقت لـ Docker. في كل مرحلة من مراحل البناء، سيقوم Docker بالتحقق مما إذا كان يحتوي على طبقة تم تخزينها في ذاكرة التخزين المؤقت لتلك التعليمات المحددة. إذا غيّرنا الحزمة package.json
، فسيُعاد بناء هذه الطبقة، لكن إذا لم نفعل ذلك، فسوف تسمح هذا التعليمة لـ Docker باستخدام طبقة الصورة الحالية وتخطي إعادة تثبيت وحدات node.
للتأكد من أن جميع ملفات التطبيق مملوكة للمستخدم node غير الجذري، بما في ذلك محتويات المجلّد node_modules
، حوّل المستخدم إلى node قبل تنفيذ npm install
:
-
الملف
-/node_project/Dockerfile
:
... USER node
بعد نسخ اعتماديات المشروع وتبديل مستخدمنا، يمكننا تنفيذ install npm
:
-
الملف
~/node_project/Dockerfile
:
... RUN npm install
بعد ذلك، انسخ شيفرة تطبيقك مع الأذونات المناسبة إلى مجلّد التطبيق على الحاوية:
-
الملف
~/node_project/Dockerfile
:
... COPY --chown=node:node . .
سيضمن هذا أن ملفات التطبيق مملوكة من قبل مستخدم node غير الجذري.
أخيرًا، اعرض المنفذ 8080
على الحاوية وابدأ تشغيل التطبيق:
-
الملف
~/node_project/Dockerfile
:
... EXPOSE 8080 CMD [ "node", "app.js" ]
لا ينشر الأمر EXPOSE
المنفذَ، ولكنه يعمل بدلاً من ذلك كوسيلة لتوثيق المنافذ على الحاوية التي سيتم نشرها في وقت التشغيل. يقوم CMD
بتنفيذ الأمر لبدء التطبيق، في هذه الحالة، node app.js
. لاحظ أنه يجب أن يكون هناك تعليمة CMD
واحدة فقط في كل Dockerfile. إذا ضمّنت أكثر من واحدة، فستُفعّل الأخيرة فقط.
هناك العديد من الأشياء التي يمكنك القيام بها باستخدام Dockerfile. للحصول على قائمة كاملة بالتعليمات، يرجى الرجوع إلى التوثيق المرجعي لملفات Dockerfile.
يكون الملفّ Dockerfile الكامل على هذا النحو:
-
الملف
~/node_project/Dockerfile
:
FROM node:10-alpine RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app WORKDIR /home/node/app COPY package*.json ./ USER node RUN npm install COPY --chown=node:node . . EXPOSE 8080 CMD [ "node", "app.js" ]
احفظ الملف وأغلقه عند الانتهاء من التحرير.
قبل بناء صورة التطبيق، دعنا نضيف ملف .dockerignore
ونظرًا لأنه يعمل بطريقة مشابهة لملف .gitignore
، فإن ملف .dockerignore
يحدّد ماهي الملفات والمجلّدات الموجودة في مجلّد مشروعك والتي لا ينبغي نسخها إلى حاويتك.
افتح الملف dockerignore.
:
$ nano .dockerignore
أضف داخل الملف وحدات node المحلية وسجلات npm وملف Dockerfile وملف dockerignore.
:
-
الملف
~/node_project/.dockerignore
:
node_modules npm-debug.log Dockerfile .dockerignore
إذا كنت تعمل باستخدام Git، فستحتاج أيضًا إلى إضافة مجلّد git.
وملف gitignore.
احفظ الملف وأغلقه عند الانتهاء.
أنت الآن جاهز لإنشاء صورة التطبيق باستخدام الأمر docker build
. سيسمح لك استخدام الراية t-
مع docker build
بتعليم الصورة باسم سهل التذكّر. ونظرًا لأننا سنقوم بنقل الصورة إلى Docker Hub، فلنضمّن اسم مستخدم Docker Hub الخاص بنا في العلامة. سنعلّم الصورة باستخدام nodejs-image-demo
، ولكن لا تتردد في استبدالها باسم تختاره. تذكر أيضًا استبدال your_dockerhub_username
باسم مستخدم Docker Hub الخاص بك:
$ docker build -t your_dockerhub_username/nodejs-image-demo .
تحدّد النقطة .
أن موضع البناء هو المجلّد الحالي.
سوف يستغرق الأمر دقيقة أو دقيقتين لبناء الصورة. بمجرد اكتمال الأمر، يمكنك التحقق من صورك:
$ docker images
سيظهر لك في المخرجات ما يلي:
output REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 73MB node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB
أصبح الآن من الممكن إنشاء حاوية بهذه الصورة باستخدام docker run
. وسنضمّن ثلاث علامات مع هذا الأمر:
-
-p
: تنشر هذه الراية المنفذ على الحاوية وتقدّمه كمنفذ على المضيف host. سنستخدم المنفذ80
على المضيف، ولكن يجب ألا تتردد في تعديل هذا عند الضرورة إذا كان لديك عملية أخرى تعمل على هذا المنفذ. لمزيد من المعلومات حول كيفية عمل هذا، راجع هذه النقاش في توثيقات Docker حول ربط المنافذ. -
-d
: تشغّل هذه العلامة الحاوية في الخلفية. -
-name
: هذا يتيح لنا إعطاء الحاوية اسمًا سهل التذكر.
نفّذ الأمر التالي لبناء الحاوية:
docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
بمجرد تشغيل حاويتك، يمكنك فحص قائمة الحاويات قيد التشغيل باستخدام docker ps
:
$ docker ps
سيظهر لك الإخراج التالي:
Output CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo
بعد تشغيل حاويتك، يمكنك الآن الولوج إلى تطبيقك بالانتقال بمتصفحك إلى http://your_server_ip
. ستظهر لك صفحتك الهبوط مرة أخرى:
الآن وبعد بناء صورة لتطبيقك، يمكنك رفعها إلى Docker Hub للاستخدام المستقبلي.
الخطوة الرابعة: استخدام مستودع للعمل بالصور
برفعك لصورة التطبيق الخاصة بك إلى سجلّ مثل Docker Hub، فأنت تجعلها متاحة للاستخدام المستقبلي عندما تكون بصدد بناء حاوياتك وتوسيع نطاقها. سنوضح كيف يعمل هذا عن طريق رفع صورة التطبيق إلى مستودع ثم استخدام الصورة لإعادة إنشاء حاويتنا.
الخطوة الأولى لرفع الصورة هي تسجيل الدخول إلى حساب Docker Hub الذي أنشأته في المتطلبات الأساسية:
$ docker login -u your_dockerhub_username
أدخل كلمة مرور حساب Docker Hub، وسيؤدي التسجيل بهذه الطريقة إلى إنشاء ملف ~/.docker/config.json
في المجلّد الرئيسي لمستخدمك بالبيانات الاعتمادية لDocker Hub.
يمكنك الآن رفع صورة التطبيق إلى Docker Hub باستخدام العلامة التي أنشأتها مسبقًا، your_dockerhub_username/nodejs-image-demo
$ docker push your_dockerhub_username/nodejs-image-demo
دعنا نختبر الآن أهمّية سجلّ الصور بتدمير حاوية التطبيق الحالية والصورة وإعادة بنائها باستخدام الصورة التي في مستودعنا.
استعرض أولاً حاوياتك التي توجد قيد التشغيل:
$ docker ps
سيظهر لك الإخراج التالي:
Output CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_dockerhub_username/nodejs-image-demo "node app.js" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-demo
باستخدام CONTAINER ID
الظاهر في المخرجات، أوقف حاوية التطبيق قيد التشغيل. تأكد من استبدال المعرّف أدناه بمعرّف الحاوية CONTAINER ID
:
$ docker stop e50ad27074a7
اعرض قائمة صورك باستخدام الراية -a
:
$ docker images -a
سيظهر لك الإخراج التالي مع اسم صورتك، your_dockerhub_username/nodejs-image-demo
، إلى جانب صورة node وباقي الصور الأخرى الخاصة ببنائك:
Output REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 73MB <none> <none> 2e3267d9ac02 4 minutes ago 72.9MB <none> <none> 8352b41730b9 4 minutes ago 73MB <none> <none> 5d58b92823cb 4 minutes ago 73MB <none> <none> 3f1e35d7062a 4 minutes ago 73MB <none> <none> 02176311e4d0 4 minutes ago 73MB <none> <none> 8e84b33edcda 4 minutes ago 70.7MB <none> <none> 6a5ed70f86f2 4 minutes ago 70.7MB <none> <none> 776b2637d3c1 4 minutes ago 70.7MB node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB
احذف الحاوية المتوقفة وجميع الصور، بما في ذلك الصور غير المستخدمة أو المعلّقة، باستخدام الأمر التالي:
$ docker system prune -a
اكتب y
في المحثّ عند الإخراج لتأكيد رغبتك في إزالة الحاوية والصور المتوقفة. وينبغي التوضيح أن هذا سيؤدي أيضًا إلى حذف ذاكرة التخزين المؤقت للبناء.
لقد حذفت الآن كلًا من الحاوية التي تشغّل صورة التطبيق والصورة نفسها. لمزيد من المعلومات حول إزالة حاويات Docker والصور، يرجى الاطلاع على كيفية التعامل مع الحاويات.
بعد حذف كل الصور والحاويات الخاصة بك ، يمكنك الآن سحب صورة التطبيق من Docker Hub:
$ docker pull your_dockerhub_username/nodejs-image-demo
اعرض قائمة صورك مرة أخرى:
$ docker images
ستظهر لك صورة تطبيقك:
Output REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 73MB
يمكنك الآن إعادة بناء حاويتك باستخدام الأمر التالي من الخطوة 3:
docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
اعرض قائمة الحاويات قيد التشغيل:
$ docker ps
Output CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "node app.js" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo
تصفّح http://your_server_ip
مرة أخرى لعرض التطبيق قيد التشغيل.
الخلاصة
في هذا الدرس، عملت على بناء تطبيق ويب ثابت باستخدام Express و Bootstrap، بالإضافة إلى صورة Docker لهذا التطبيق. استخدمت هذه الصورة لإنشاء حاوية ورفعت الصورة إلى Docker Hub. بعد ذلك، تمكنت من تدمير صورتك وحاوياتك وإعادة إنشائها باستخدام مستودع Docker Hub.
ترجمة -وبتصرف- للمقال How To Build a Node.js Application with Docker لصاحبته Kathleen Juell
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.