مقدمه
پلتفرم 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 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 و یک فهرست views خواهد بود که شامل دارایی های ثابت پروژه می شود. صفحه فرود، index.html، اطلاعات اولیه و پیوندی به صفحه ای با اطلاعات دقیق تر کوسه، sharks.html را در اختیار کاربران قرار می دهد. در فهرست views، هم صفحه فرود و هم 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;
تابع نیاز ماژول اکسپرس را بارگیری می کند، که سپس از آن برای ایجاد برنامه و اشیاء روتر استفاده می کنیم. شی روتر عملکرد مسیریابی برنامه را انجام می دهد، و همانطور که مسیرهای متد HTTP را تعریف می کنیم، آنها را به این شی اضافه می کنیم تا نحوه رسیدگی برنامه ما به درخواست ها را مشخص کنیم.
این بخش از فایل همچنین چند ثابت، Path
و Port
را تنظیم می کند:
- path: دایرکتوری پایه را تعریف می کند که زیر شاخه views در فهرست پروژه فعلی خواهد بود.
- پورت: به برنامه میگوید به پورت 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!')
})
پس از اتمام کار فایل را ذخیره کرده و ببندید.
در مرحله بعد، اجازه دهید مقداری محتوای ثابت به برنامه اضافه کنیم. با ایجاد دایرکتوری views شروع کنید:
mkdir views
فایل صفحه فرود، index.html را باز کنید:
nano views/index.html
کد زیر را به فایل اضافه کنید، که بوت استرپ را وارد می کند و یک کامپوننت 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>
نوار ناوبری سطح بالا در اینجا به کاربران اجازه می دهد بین صفحات Home و 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 در فهرست views، استایل شیت سفارشی CSS را که در index.html و sharks.html به آن پیوند دادهاید، ایجاد کنید:
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 هدایت کنید. صفحه فرود زیر را بارگیری خواهید کرد:
بر روی دکمه Get Shark Info کلیک کنید. صفحه اطلاعات زیر بارگیری می شود:
شما اکنون یک برنامه کاربردی دارید و در حال اجرا هستید. وقتی آماده شدید، با تایپ CTRL+C از سرور خارج شوید. اکنون میتوانیم به ایجاد Dockerfile برویم که به ما امکان میدهد این برنامه را به دلخواه بازسازی و مقیاسبندی کنیم.
مرحله 3 – نوشتن Dockerfile
Dockerfile شما مشخص می کند که چه چیزی در محفظه برنامه شما در هنگام اجرا گنجانده می شود. استفاده از Dockerfile به شما این امکان را می دهد که محیط کانتینر خود را تعریف کنید و از اختلاف با وابستگی ها یا نسخه های زمان اجرا جلوگیری کنید.
با پیروی از این دستورالعملها در مورد ساخت کانتینرهای بهینه، تصویر خود را با به حداقل رساندن تعداد لایههای تصویر و محدود کردن عملکرد تصویر به یک هدف واحد – بازآفرینی فایلهای برنامه و محتوای ثابت، تا حد امکان کارآمد میکنیم.
در دایرکتوری ریشه پروژه خود، Dockerfile را ایجاد کنید:
nano Dockerfile
تصاویر Docker با استفاده از تصاویر لایهای متوالی ایجاد میشوند که بر روی یکدیگر ساخته میشوند. اولین قدم ما اضافه کردن تصویر پایه برای برنامه ما خواهد بود که نقطه شروع ساخت برنامه را تشکیل می دهد.
بیایید از تصویر node:10-alpine استفاده کنیم، زیرا در زمان نوشتن این نسخه LTS توصیه شده Node.js است. تصویر آلپاین از پروژه آلپاین لینوکس گرفته شده است و به ما کمک می کند اندازه تصویر خود را پایین نگه داریم. برای کسب اطلاعات بیشتر در مورد اینکه آیا تصویر آلپاین انتخاب مناسبی برای پروژه شما است یا خیر، لطفاً بحث کامل را در بخش Image Variants صفحه تصویر Docker Hub Node مرور کنید.
دستورالعمل FROM زیر را برای تنظیم تصویر پایه برنامه اضافه کنید:
FROM node:10-alpine
این تصویر شامل Node.js و npm است. هر Dockerfile باید با یک دستورالعمل FROM شروع شود.
بهطور پیشفرض، تصویر Docker Node شامل یک کاربر گره غیر روت است که میتوانید از آن برای جلوگیری از اجرای کانتینر برنامهتان بهعنوان روت استفاده کنید. اجتناب از اجرای کانتینرها به عنوان روت و محدود کردن قابلیتهای درون کانتینر فقط به مواردی که برای اجرای فرآیندهای آن لازم است، یک اقدام امنیتی توصیه شده است. بنابراین ما از فهرست اصلی کاربر گره به عنوان دایرکتوری کاری برای برنامه خود استفاده می کنیم و آنها را به عنوان کاربر خود در داخل ظرف تنظیم می کنیم. برای اطلاعات بیشتر در مورد بهترین شیوه ها هنگام کار با تصویر Docker Node، این راهنمای بهترین شیوه ها را بررسی کنید.
برای تنظیم دقیق مجوزهای کد برنامه ما در کانتینر، اجازه دهید زیر شاخه node_modules را در /home/node به همراه فهرست برنامه ایجاد کنیم. ایجاد این دایرکتوریها تضمین میکند که مجوزهای مورد نظر ما را دارند، که وقتی ماژولهای گره محلی را در ظرف با نصب npm ایجاد میکنیم، مهم خواهد بود. علاوه بر ایجاد این دایرکتوری ها، مالکیت آنها را برای کاربر گره خود تعیین می کنیم:
...
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 ./
افزودن این دستورالعمل COPY قبل از اجرای npm install یا کپی کد برنامه به ما امکان می دهد از مکانیسم کش Docker استفاده کنیم. در هر مرحله از ساخت، داکر بررسی می کند که آیا لایه ای برای آن دستورالعمل خاص ذخیره شده است یا خیر. اگر بسته.json را تغییر دهیم، این لایه دوباره ساخته میشود، اما اگر این کار را نکنیم، این دستورالعمل به Docker اجازه میدهد از لایه تصویر موجود استفاده کند و از نصب مجدد ماژولهای گره ما صرف نظر کند.
برای اطمینان از اینکه همه فایل های برنامه متعلق به کاربر غیر ریشه گره هستند، از جمله محتویات دایرکتوری node_modules، قبل از اجرای npm install، کاربر را به node تغییر دهید:
...
USER node
پس از کپی کردن وابستگی های پروژه و تعویض کاربر، می توانیم npm install را اجرا کنیم:
...
RUN npm install
در مرحله بعد، کد برنامه خود را با مجوزهای مناسب در فهرست برنامه روی کانتینر کپی کنید:
...
COPY --chown=node:node . .
این اطمینان حاصل می کند که فایل های برنامه متعلق به کاربر غیر روت است.
در نهایت، پورت 8080 را روی کانتینر قرار دهید و برنامه را شروع کنید:
...
EXPOSE 8080
CMD [ "node", "app.js" ]
EXPOSE پورت را منتشر نمی کند، اما در عوض به عنوان راهی برای مستند کردن پورت های موجود در کانتینر در زمان اجرا عمل می کند. CMD فرمان را برای شروع برنامه اجرا می کند – در این مورد، node app.js. توجه داشته باشید که در هر Dockerfile باید فقط یک دستور CMD وجود داشته باشد. اگر بیش از یک مورد را وارد کنید، فقط آخرین مورد اعمال می شود.
کارهای زیادی وجود دارد که می توانید با Dockerfile انجام دهید. برای فهرست کامل دستورالعملها، لطفاً به مستندات مرجع Docker’s 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 اضافه کنیم. با کار کردن به روشی مشابه با فایل .gitignore، .dockerignore مشخص می کند که کدام فایل ها و دایرکتوری ها در فهرست پروژه شما نباید در کانتینر شما کپی شوند.
فایل .dockerignore را باز کنید:
nano .dockerignore
در داخل فایل، ماژولهای گره محلی، گزارشهای npm، Dockerfile و فایل .dockerignore را اضافه کنید:
node_modules
npm-debug.log
Dockerfile
.dockerignore
اگر با Git کار می کنید، می خواهید دایرکتوری .git و فایل gitignore. خود را نیز اضافه کنید.
پس از اتمام کار فایل را ذخیره کرده و ببندید.
اکنون آماده ساخت تصویر برنامه با استفاده از دستور ساخت docker هستید. استفاده از پرچم -t با ساخت docker به شما این امکان را می دهد که تصویر را با یک نام به یاد ماندنی تگ کنید. از آنجایی که قصد داریم تصویر را به داکر هاب منتقل کنیم، اجازه دهید نام کاربری داکر هاب خود را در تگ قرار دهیم. ما تصویر را با عنوان 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 Docs در مورد اتصال پورت مرور کنید.
- -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 شما ایجاد می کند.
اکنون می توانید تصویر برنامه را با استفاده از برچسبی که قبلا ایجاد کرده اید، your_dockerhub_username/nodejs-image-demo، به Docker Hub وارد کنید:
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
با استفاده از شناسه CONTAINER فهرست شده در خروجی، کانتینر برنامه در حال اجرا را متوقف کنید. حتماً شناسه هایلایت شده زیر را با شناسه CONTAINER خودتان جایگزین کنید:
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 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 خود آنها را بازسازی کنید.