مقدمة
تتيح منصة Docker للمطورين تجميع التطبيقات وتشغيلها كحاويات. الحاوية هي عملية واحدة تعمل على نظام تشغيل مشترك، وهي بديل أخف وزنًا للآلات الافتراضية. على الرغم من أن الحاويات ليست جديدة، إلا أنها توفر مزايا - تشمل عزل العمليات وتوحيد معايير البيئة - ستزداد أهميتها مع تزايد اعتماد المطورين لبنى التطبيقات الموزعة.
عند بناء تطبيق وتوسيع نطاقه باستخدام Docker، عادةً ما تكون نقطة البداية هي إنشاء صورة لتطبيقك، والتي يمكنك تشغيلها بعد ذلك في حاوية. تحتوي هذه الصورة على شيفرة التطبيق، والمكتبات، وملفات التكوين، ومتغيرات البيئة، ووقت التشغيل. يضمن استخدام صورة أن تكون بيئة الحاوية الخاصة بك موحدة وتحتوي فقط على ما هو ضروري لبناء تطبيقك وتشغيله.
في هذا البرنامج التعليمي، ستنشئ صورة تطبيق لموقع ويب ثابت يستخدم إطاري عمل Express وBootstrap. بعد ذلك، ستنشئ حاوية باستخدام هذه الصورة وترفعها إلى Docker Hub لاستخدامها لاحقًا. وأخيرًا، ستسحب الصورة المحفوظة من مستودع Docker Hub وتبنيها في حاوية أخرى، موضحًا كيفية إعادة تصميم تطبيقك وتوسيع نطاقه.
المتطلبات الأساسية
- خادم يعمل بنظام أوبونتو، مع مستخدم غير جذر بصلاحيات sudo وجدار حماية مُفعّل. للحصول على تعليمات حول كيفية إعداده، يُرجى اختيار توزيعتك من هذه القائمة واتباع دليل التثبيت الأولي للخادم.
- تم تثبيت Docker على الخادم الخاص بك.
- تم تثبيت Node.js وnpm.
- حساب Docker Hub.
الخطوة 1 – تثبيت تبعيات التطبيق الخاص بك
لإنشاء صورتك، عليك أولاً إنشاء ملفات تطبيقك، ثم يمكنك نسخها إلى الحاوية. تحتوي هذه الملفات على المحتوى الثابت، والرمز، والتبعيات الخاصة بتطبيقك.
أولاً، أنشئ مجلدًا لمشروعك في المجلد الرئيسي للمستخدم غير الجذر. سنسمي مشروعنا node_project، ولكن يمكنك استبداله باسم آخر:
mkdir node_projectانتقل إلى هذا الدليل:
cd node_projectسيكون هذا هو الدليل الرئيسي للمشروع.
بعد ذلك، أنشئ ملف package.json يتضمن تبعيات مشروعك ومعلومات تعريفية أخرى. افتح الملف باستخدام nano أو محرر النصوص المفضل لديك:
nano package.jsonأضف المعلومات التالية عن المشروع، بما في ذلك اسمه، ومؤلفه، وترخيصه، ونقطة دخوله، والتبعيات. تأكد من استبدال معلومات المؤلف باسمك ومعلومات الاتصال بك:
{
"name": "nodejs-image-demo",
"version": "1.0.0",
"description": "nodejs image demo",
"author": "Sammy the Shark <[email protected]>",
"license": "MIT",
"main": "app.js",
"keywords": [
"nodejs",
"bootstrap",
"express"
],
"dependencies": {
"express": "^4.16.4"
}
}يحتوي هذا الملف على اسم المشروع، ومؤلفه، والترخيص المُستخدم لتوزيعه. يُوصي Npm باختيار اسم مشروع قصير وواضح، وتجنب التكرار في سجل NPM. نُدرج ترخيص MIT في قسم الترخيص، والذي يسمح باستخدام وتوزيع شيفرة البرنامج مجانًا. بالإضافة إلى ذلك، يُحدد الملف ما يلي:
- “"main": نقطة دخول التطبيق، app.js. ستنشئ هذا الملف لاحقًا.
- “"التبعيات": تبعيات المشروع - في هذه الحالة، Express 4.16.4 أو أعلى.
مع أن هذا الملف لا يتضمن مستودعًا، يمكنك إضافته باتباع هذه التعليمات لإضافة مستودع إلى ملف package.json. تُعد هذه إضافة قيّمة إذا كنت تُعدّل تطبيقك. احفظ الملف وأغلقه عند الانتهاء من إجراء التغييرات.
لتثبيت تبعيات مشروعك، قم بتشغيل الأمر التالي:
npm installسيؤدي هذا إلى تثبيت الحزم المدرجة في ملف package.json في دليل مشروعك. الآن، يمكننا بناء ملفات التطبيق.
الخطوة 2 – إنشاء ملفات البرنامج
سننشئ موقعًا إلكترونيًا يوفر للمستخدمين معلومات عن أسماك القرش. سيحتوي تطبيقنا على مدخل رئيسي، app.js، ودليل للعروض يحتوي على الأصول الثابتة للمشروع. ستوفر صفحة الهبوط، index.html، للمستخدمين معلومات أساسية ورابطًا لصفحة تحتوي على معلومات أكثر تفصيلًا عن أسماك القرش، sharks.html. في دليل العروض، سننشئ كلًا من صفحة الهبوط وملف sharks.html.
أولاً، افتح app.js في دليل المشروع الرئيسي لتحديد مسارات المشروع:
nano app.jsيقوم الجزء الأول من الملف بإنشاء كائنات تطبيق Express وRouter ويحدد الدليل الأساسي والمنفذ كثوابت:
const express = require('express'); const app = express(); const router = express.Router(); const path = __dirname + '/views/'; const port = 8080;
تُحمّل دالة "require" وحدة Express، التي نستخدمها لإنشاء التطبيق وكائنات جهاز التوجيه. يُنفّذ كائن جهاز التوجيه وظيفة التوجيه الخاصة بالتطبيق، وعند تعريف مسارات طريقة HTTP، نضيفها إلى هذا الكائن لتحديد كيفية تعامل تطبيقنا مع الطلبات.
يحتوي هذا القسم من الملف أيضًا على العديد من الثوابت، طريق و ميناء المجموعات:
- المسار: يحدد الدليل الأساسي الذي سيكون أسفل دليل العروض في دليل المشروع الحالي.
- المنفذ: يخبر البرنامج بالاستماع إلى المنفذ 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');
});تُحمّل دالة router.use دالة وسيطة تُسجّل طلبات جهاز التوجيه وتُعيد توجيهها إلى مسارات التطبيق. تُعرّف هذه الدوال في الدوال التالية، والتي تُحدّد أن طلب GET إلى عنوان URL للمشروع الأساسي يجب أن يُعيد صفحة index.html، بينما يجب أن يُعيد طلب GET إلى مسار /sharks صفحة sharks.html.
أخيرًا، قم بتثبيت برنامج الوسيط الخاص بالموجه والأصول الثابتة للتطبيق وأخبر التطبيق بالاستماع على المنفذ 8080:
...
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!')
})احفظ الملف وأغلقه عند الانتهاء.
الآن، لنُضِف محتوى ثابتًا إلى التطبيق. ابدأ بإنشاء مجلد المشاهدات:
mkdir viewsافتح ملف صفحة الهبوط، index.html:
nano views/index.htmlأضف الكود التالي إلى الملف، والذي يقوم باستيراد Bootstrap وإنشاء مكون jumbotron مع رابط إلى صفحة المعلومات التفصيلية 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>
<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>يتيح شريط التنقل العلوي هنا للمستخدمين التنقل بين صفحتي "الصفحة الرئيسية" و"Sharks". ضمن مكون navbar-nav، نستخدم فئة Bootstrap النشطة لعرض الصفحة الحالية للمستخدم. كما حددنا مسارات لصفحاتنا الثابتة تتوافق مع المسارات التي حددناها في app.js.
...
<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>
...بالإضافة إلى ذلك، قمنا بإنشاء رابط لصفحة معلومات القرش الخاصة بنا على زر jumbotrons:
...
<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>
...هناك أيضًا رابط إلى جدول أنماط مخصص في العنوان:
...
<link href="css/styles.css" rel="stylesheet">
...في نهاية هذه الخطوة، سننشئ جدول الأنماط هذا. عند الانتهاء، احفظ الملف وأغلقه. بإضافة صفحة هبوط التطبيق، يمكننا إنشاء صفحة معلومات أسماك القرش المسماة sharks.html، والتي ستوفر للمستخدمين المهتمين المزيد من المعلومات حول أسماك القرش.
افتح الملف:
nano views/sharks.htmlأضف الكود التالي، الذي يستورد Bootstrap وجدول أنماط مخصص ويوفر للمستخدمين معلومات مفصلة حول أسماك القرش المحددة:
<!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>لاحظ أننا في هذا الملف نستخدم الفئة النشطة لعرض الصفحة الحالية. احفظ الملف وأغلقه عند الانتهاء.
أخيرًا، قم بإنشاء ورقة أنماط CSS المخصصة التي قمت بربطها في index.html و sharks.html عن طريق إنشاء مجلد css أولاً في دليل views:
mkdir views/cssافتح ورقة الأنماط:
nano 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. ستُحمّل صفحة الوصول التالية:
انقر على زر "الحصول على معلومات القرش". ستُحمَّل صفحة المعلومات التالية:
لديك الآن تطبيق جاهز للعمل. عندما تكون جاهزًا، اخرج من الخادم بالضغط على CTRL+C. الآن، يمكننا الانتقال إلى إنشاء ملف Dockerfile الذي سيسمح لنا بإعادة بناء هذا التطبيق وتوسيع نطاقه حسب الحاجة.
الخطوة 3 - كتابة ملف Dockerfile
يُحدد ملف Dockerfile ما سيتم تضمينه في حاوية تطبيقك عند تشغيله. يتيح لك استخدام ملف Dockerfile تحديد بيئة الحاوية وتجنب التعارضات مع التبعيات أو إصدارات وقت التشغيل.
من خلال اتباع هذه الإرشادات لبناء حاويات مثالية، فإننا نجعل صورتنا فعالة قدر الإمكان من خلال تقليل عدد طبقات الصورة والحد من وظيفة الصورة لغرض واحد - إعادة إنشاء ملفات التطبيق والمحتوى الثابت.
في الدليل الجذر لمشروعك، قم بإنشاء Dockerfile:
nano Dockerfileتُنشأ صور Docker باستخدام صور متسلسلة ومتعددة الطبقات، تُبنى فوق بعضها. خطوتنا الأولى هي إضافة الصورة الأساسية لتطبيقنا، والتي ستكون نقطة البداية لبناء التطبيق.
لنستخدم صورة node:10-alpine، فهي إصدار LTS المُوصى به من Node.js وقت كتابة هذه السطور. صورة Alpine مأخوذة من مشروع Alpine Linux، وتساعدنا على تقليل حجم الصورة. لمزيد من المعلومات حول ما إذا كانت صورة Alpine خيارًا جيدًا لمشروعك، يُرجى مراجعة المناقشة الكاملة في قسم "متغيرات الصورة" بصفحة صورة Node في Docker Hub.
أضف التوجيه FROM التالي لتعيين الصورة الأساسية للتطبيق:
FROM node:10-alpineتتضمن هذه الصورة Node.js وnpm. يجب أن يبدأ كل ملف Dockerfile بتوجيه FROM.
افتراضيًا، تتضمن صورة عقدة Docker مستخدم عقدة غير جذر، والذي يمكنك استخدامه لمنع حاوية تطبيقك من العمل كمستخدم جذر. يُعد تجنب تشغيل الحاويات كمستخدم جذر وتقييد الإمكانيات داخل الحاوية على تلك اللازمة لتشغيل عملياتها فقط إجراءً أمنيًا مُوصى به. لذلك، نستخدم الدليل الرئيسي لمستخدم العقدة كدليل عمل لتطبيقنا ونُعيّنه كمستخدم داخل الحاوية. لمزيد من المعلومات حول أفضل الممارسات عند العمل مع صورة عقدة Docker، يُرجى الاطلاع على دليل أفضل الممارسات هذا.
لضبط أذونات كود تطبيقنا في الحاوية، لننشئ مجلدًا فرعيًا باسم node_modules في /home/node مع مجلد التطبيق. يضمن إنشاء هذه المجلدات حصولها على الأذونات المطلوبة، وهو أمر مهم عند إنشاء وحدات Node محلية في الحاوية باستخدام npm install. بالإضافة إلى إنشاء هذه المجلدات، نعيّن ملكيتها لمستخدم Node الخاص بنا:
...
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/appلمزيد من المعلومات حول استخدام تعليمات RUN المتكاملة، اقرأ هذه المناقشة حول كيفية إدارة طبقات الحاوية.
بعد ذلك، قم بتعيين دليل عمل التطبيق إلى /home/node/app:
...
WORKDIR /home/node/appإذا لم يتم تعيين WORKDIR، فسوف يقوم Docker بإنشاء واحد بشكل افتراضي، لذا فمن الجيد تعيينه صراحةً.
ثم انسخ الملفات package.json و package-lock.json (لـ npm 5+):
...
COPY package*.json ./إضافة أمر النسخ هذا قبل تشغيل تثبيت npm أو نسخ شيفرة التطبيق يتيح لنا الاستفادة من آلية التخزين المؤقت في Docker. في كل مرحلة من مراحل البناء، يتحقق Docker مما إذا كانت طبقة قد تم تخزينها مؤقتًا لهذا الأمر المحدد. إذا غيّرنا ملف package.json، فسيتم إعادة بناء هذه الطبقة، ولكن إذا لم نغيّره، يسمح هذا الأمر لـ Docker باستخدام طبقة الصورة الحالية وتخطي إعادة تثبيت وحدات Node.
للتأكد من أن جميع ملفات التطبيق مملوكة لمستخدم العقدة غير الجذر، بما في ذلك محتويات دليل node_modules، قم بتغيير المستخدم إلى node قبل تشغيل npm install:
...
USER nodeبعد نسخ تبعيات المشروع والتبديل بين المستخدمين، يمكننا تشغيل npm install:
...
RUN npm installبعد ذلك، انسخ كود التطبيق الخاص بك مع الأذونات المناسبة إلى دليل التطبيق على الحاوية:
...
COPY --chown=node:node . .يضمن هذا أن ملفات التطبيق مملوكة للمستخدم غير الجذر.
أخيرًا، قم بتعيين المنفذ 8080 على الحاوية وابدأ تشغيل التطبيق:
...
EXPOSE 8080
CMD [ "node", "app.js" ]لا يكشف EXPOSE عن المنفذ، بل يعمل كوسيلة لتوثيق المنافذ المتاحة للحاوية وقت التشغيل. ينفذ CMD الأمر لبدء التطبيق - في هذه الحالة، node app.js. يُرجى ملاحظة أنه يجب استخدام أمر CMD واحد فقط لكل ملف Dockerfile. في حال تضمين أكثر من أمر، سيتم تطبيق الأمر الأخير فقط.
هناك العديد من الميزات التي يمكنك استخدامها باستخدام ملفات Dockerfile. للاطلاع على قائمة كاملة بالتعليمات، يُرجى مراجعة وثائق Dockerfile المرجعية.
يبدو ملف 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. يعمل ملف .dockerignore بطريقة مشابهة لملف .gitignore، حيث يُحدد الملفات والمجلدات في دليل مشروعك التي لا يجب نسخها إلى الحاوية.
افتح ملف .dockerignore:
nano .dockerignoreداخل الملف، أضف وحدات العقدة المحلية، وسجلات npm، وDockerfile، وملف .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 الخاص بك:
sudo docker build -t your_dockerhub_username/nodejs-image-demo .. يحدد أن سياق البناء هو الدليل الحالي.
سيستغرق إنشاء الصورة دقيقة أو دقيقتين. بعد الانتهاء، تحقق من صورك:
sudo 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: سيؤدي هذا إلى نشر المنفذ على الحاوية وربطه بمنفذ على جهازنا المضيف. سنستخدم المنفذ 80 على الجهاز المضيف، ولكن إذا كانت هناك عملية أخرى تعمل على هذا المنفذ، فينبغي عليك تغييره عند الحاجة. لمزيد من المعلومات حول كيفية عمل ذلك، راجع هذه المناقشة في وثائق Docker حول ربط المنافذ.
- -d: تشغيل هذه الحاوية في الخلفية.
- --name: يسمح لنا هذا بإعطاء الحاوية اسمًا لا يُنسى.
لإنشاء الحاوية، قم بتشغيل الأمر التالي:
sudo docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demoبمجرد تشغيل الحاوية الخاصة بك، يمكنك التحقق من قائمة الحاويات قيد التشغيل باستخدام docker ps:
sudo 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أثناء تشغيل الحاوية الخاصة بك، يمكنك الآن زيارة تطبيقك من خلال توجيه متصفحك إلى عنوان IP الخاص بخادمك دون المنفذ:
http://your_server_ip
سيتم تحميل صفحة التطبيق الخاصة بك مرة أخرى.
الآن بعد أن قمت بإنشاء صورة لتطبيقك، يمكنك دفعها إلى Docker Hub لاستخدامها في المستقبل.
الخطوة 4 - استخدام مستودع للعمل مع الصور
برفع صورة تطبيقك إلى سجلّ مثل Docker Hub، ستجعلها متاحة للاستخدام لاحقًا أثناء بناء الحاويات وتوسيع نطاقها. سنشرح لك كيفية القيام بذلك برفع صورة تطبيقك إلى مستودع، ثم استخدامها لإعادة إنشاء حاويتك.
الخطوة الأولى لدفع الصورة هي تسجيل الدخول إلى حساب Docker Hub الذي قمت بإنشائه في المتطلبات الأساسية:
sudo docker login -u your_dockerhub_usernameعند المطالبة، أدخل كلمة مرور حساب Docker Hub الخاص بك. سيؤدي تسجيل الدخول بهذه الطريقة إلى إنشاء ملف ~/.docker/config.json في دليل المستخدم الرئيسي الخاص بك باستخدام بيانات اعتماد Docker Hub.
يمكنك الآن دفع صورة التطبيق إلى Docker Hub باستخدام العلامة التي أنشأتها سابقًا، your_dockerhub_username/nodejs-image-demo:
sudo docker push your_dockerhub_username/nodejs-image-demoدعنا نختبر أداة تسجيل الصور عن طريق تدمير حاوية التطبيق والصورة الحالية وإعادة بنائها باستخدام الصورة الموجودة في مستودعنا.
أولاً، قم بإدراج الحاويات التي تعمل لديك:
sudo 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أوقف تشغيل حاوية التطبيق باستخدام مُعرِّف الحاوية المذكور في المُخرَج. تأكد من استبدال المُعرِّف المُحدَّد أدناه بمُعرِّف الحاوية الخاص بك:
sudo docker stop e50ad27074a7قم بإدراج جميع صورك باستخدام -a:
docker images -aستحصل على الناتج التالي مع اسم صورتك، your_dockerhub_username/nodejs-image-demo، بالإضافة إلى صورة العقدة والصور الأخرى من البناء الخاص بك:
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 والحاويات والمجلدات.
بعد إزالة جميع صورك وحاوياتك، يمكنك الآن سحب صورة التطبيق من 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.












