Быстрая сборка приложения Node.js с помощью Docker
Java, Quickstart, Ubuntu | Комментировать запись
Этот мануал поможет вам создать образ приложения для статического веб-сайта на фреймворке Express и Bootstrap. Мы соберем контейнер с помощью полученного образа, а затем загрузим его на Docker Hub для дальнейшего использования. После этого мы загрузим образ с Docker Hub и соберем новый контейнер, чтобы понять, как работает воссоздание и масштабирование приложения.
Расширенную версию этого мануала вы найдете здесь.
Требования
- Сервер Ubuntu 18.04, настроенный по этому мануалу.
- Установка Docker.
- Node.js и npm.
- Аккаунт Docker Hub. Создать его вам поможет эта страница.
1: Установка зависимостей приложения
Создайте каталог для вашего проекта в домашнем каталоге пользователя sudo.
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 <sammy@example.com>",
"license": "MIT",
"main": "app.js",
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"nodejs",
"bootstrap",
"express"
],
"dependencies": {
"express": "^4.16.4"
}
}
Чтобы установить зависимости проекта, которые вы перечислили в файле package.json, выполните следующую команду:
npm install
2: Создание файлов приложения
Для примера мы создадим сайт, который предлагает пользователям информацию об акулах.
Откройте app.js в каталоге проекта, чтобы определить маршруты проекта.
nano app.js
Вставьте в файл следующие строки, чтобы создать приложение Express и объекты Router, определить базовый каталог, порт и хост как переменные, настроить маршруты, смонтировать промежуточное программное обеспечение router и статические ресурсы приложения.
var express = require("express");
var app = express();
var router = express.Router();
var path = __dirname + '/views/';
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
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(8080, function () {
console.log('Example app listening on port 8080!')
})
Сохраните и закройте файл.
Теперь давайте добавим статичный контент приложения. Создайте каталог views :
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://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="css/styles.css" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Everything Sharks</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li class="active"><a href="/">Home</a></li>
<li><a href="/sharks">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-md-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-md-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.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://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="css/styles.css" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Merriweather:400,700' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Everything Sharks</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li><a href="/">Home</a></li>
<li class="active"><a href="/sharks">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-md-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-md-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>
</body>
</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;
}
Запустите приложение:
npm start
В браузере откройте:
http://your_server_ip:8080
Вы попадете на посадочную страницу приложения.
Нажмите кнопку Get Shark Info, чтобы открыть вторую страницу приложения.
Теперь у вас есть запущенное приложение. Чтобы остановить сервер, нажмите Ctrl+C.
3: Написание Dockerfile
В корневом каталоге проекта создайте Dockerfile:
nano Dockerfile
Добавьте в файл следующий код:
FROM node:10
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
RUN npm install
COPY . .
COPY --chown=node:node . .
USER node
EXPOSE 8080
CMD [ "npm", "start" ]
Этот файл использует базовый образ alpine, а также передает права на каталоги пользователю node, который предоставляется по умолчанию образом Docker Node.
В файл .dockerignore добавьте модули локальной ноды, логи npm, файл Dockerfile:
node_modules
npm-debug.log
Dockerfile
.dockerignore
Теперь можно собрать образ приложения с помощью команды docker build.
docker build -t your_dockerhub_username/nodejs-image-demo .
Точка указывает, что контекстом сборки является текущий каталог.
После завершения сборки проверьте образы:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds ago 895MB
node 10 f09e7c96b6de 17 hours ago 893MB
Запустите следующую команду, чтобы собрать контейнер на основе этого образа:
docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
Проверьте список работающих контейнеров:
docker ps
Вы увидите такой вывод:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e50ad27074a7 dockerhub_username/nodejs-image-demo "npm start" 8 seconds ago Up 7 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo
Теперь, когда контейнер работает, вы можете зайти в свое приложение, перейдя в браузере по адресу http://your_server_ip. Вы снова увидите посадочную страницу своего приложения.
4: Репозиторий для работы с образами
Чтобы опубликовать свой образ, сначала нужно войти в учетную запись Docker Hub:
docker login -u your_dockerhub_username -p your_dockerhub_password
Такая аутентификация создаст файл ~/.docker/config.json с учетными данными Docker Hub в домашнем каталоге вашего пользователя.
Теперь можно загрузить образ приложения на Docker Hub:
docker push your_dockerhub_username/nodejs-image-demo
Давайте проверим работу реестра образов. Для этого остановите текущий контейнер приложения и образ и попробуйте восстановить их с помощью образа в репозитории.
Сначала просмотрите список работающих контейнеров:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e50ad27074a7 your_dockerhub_username/nodejs-image-demo "npm start" 3 minutes ago Up 3 minutes 0.0.0.0:80->8080/tcp nodejs-image-demo
Используя указанный в выводе CONTAINER ID, остановите контейнер работающего приложения. Обязательно замените условный идентификатор в команде своим значением.
docker stop e50ad27074a7
Теперь просмотрите все свои контейнеры, добавив флаг -а:
docker images -a
Вы увидите следующий вывод с именем вашего образа, your_dockerhub_username/nodejs-image-demo, вместе с образом node и другими образами из вашей сборки:
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 7 minutes ago 895MB
<none> <none> e039d1b9a6a0 7 minutes ago 895MB
<none> <none> dfa98908c5d1 7 minutes ago 895MB
<none> <none> b9a714435a86 7 minutes ago 895MB
<none> <none> 51de3ed7e944 7 minutes ago 895MB
<none> <none> 5228d6c3b480 7 minutes ago 895MB
<none> <none> 833b622e5492 8 minutes ago 893MB
<none> <none> 5c47cc4725f1 8 minutes ago 893MB
<none> <none> 5386324d89fb 8 minutes ago 893MB
<none> <none> 631661025e2d 8 minutes ago 893MB
node 10 f09e7c96b6de 17 hours ago 893MB
Удалите остановленный контейнер и все образы, включая неиспользуемые:
docker system prune -a
Теперь вы можете загрузить образы и контейнеры с Docker Hub.
docker pull your_dockerhub_username/nodejs-image-demo
Запросите список своих образов:
docker images
В списке должен быть образ вашего приложения:
REPOSITORY TAG IMAGE ID CREATED SIZE
your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 895MB
Теперь можете повторно собрать контейнер с помощью этой команды:
docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
Просмотрите запущенные контейнеры:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6bc2f50dff6 your_dockerhub_username/nodejs-image-demo "npm start" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp nodejs-image-demo
Чтобы убедиться, что все работает, снова откройте http://your_server_ip. Вы должны увидеть свое приложение.
Заключение
Предлагаем вам список дополнительных руководств, которые могут быть вам интересны.
- Установка Docker Compose в Ubuntu 18.04
- Управление удалёнными хостами Docker с помощью Docker Machine в Ubuntu 18.04
- Обмен данными между контейнерами Docker
- Обмен данными между контейнером Docker и хостом