Введение
В этом обучающем руководстве мы создадим образ приложения для статического сайта, который использует веб-фреймворки Express и Bootstrap. Затем вы создадите контейнер с использованием этого образа, разместите его в Docker Hub и используете его для сборки другого контейнера, продемонстрировав способ воссоздания и масштабирования вашего приложения.
Более подробные указания с детальными разъяснениями каждого этапа приведены в обучающем руководстве Создание приложения Node.js с помощью Docker.
Предварительные требования
Для данного обучающего руководства вам потребуется следующее:
- Пользователь
sudo
на сервере или в локальной среде. - Docker.
- Node.js и
npm
. - Учетная запись Docker Hub.
Шаг 1 — Установка зависимостей вашего приложения
Вначале создайте для вашего проекта директорию в домашней директории пользователя без привилегий root:
- mkdir node_project
Перейдите в эту директорию:
- cd node_project
Это будет корневая директория проекта.
Затем создайте файл package.json
с зависимостями вашего проекта:
- nano package.json
Добавьте в файл следующую информацию о проекте; обязательно измените данные автора собственным именем и контактными данными:
~/node_project/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", "scripts": { "start": "node app.js", "test": "echo "Error: no test specified" && exit 1" }, "keywords": [ "nodejs", "bootstrap", "express" ], "dependencies": { "express": "^4.16.4" } }
Установите зависимости вашего проекта:
- npm install
Шаг 2 — Создание файлов приложения
Мы создадим сайт, который предоставляет пользователям данные об акулах.
Откройте файл app.js
в главной директории проекта, чтобы определить маршруты проекта:
- nano app.js
Добавьте в файл следующее содержание, чтобы создать приложение Express и объекты Router, определите базовую директорию, порт и хост как переменные, задайте маршруты и смонтируйте промежуточное ПО router
вместе со статическими ресурсами приложения:
~/node_project/app.js
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
Добавьте в файл следующий код, который импортирует Boostrap и создаст компонент 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://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 и пользовательскую таблицу стилей и предлагает пользователям подробную информацию об определенных акулах:
~/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://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
Откройте таблицу стилей и добавьте следующий код, который задает желаемые цвет и шрифт для наших страниц:
~/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; }
Запустите приложение:
- npm start
Откройте в браузере адрес http://your_server_ip:8080
или localhost:8080
, если вы работаете локально. Вы увидите следующую начальную страницу:
Нажмите кнопку Get Shark Info (Получить информацию об акулах). Вы увидите следующую информационную страницу:
Ваше приложение запущено и работает. Когда вы будете готовы, покиньте сервер, нажав CTRL+C
.
Шаг 3 — Создание файла Dockerfile
Создайте файл Dockerfile в корневой директории вашего проекта:
- nano 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" ]
Этот файл Dockerfile использует базовый образ alpine и обеспечивает принадлежность файлов приложения пользователю node без привилегий root, который предоставляется по умолчанию образом Docker Node.
Затем добавьте модули локального узла, журналы npm, файл Dockerfile и .dockerignore
в ваш файл .dockerignore
:
~/node_project/.dockerignore
node_modules npm-debug.log Dockerfile .dockerignore
Соберите образ приложения, используя команду docker build
:
- docker build -t your_dockerhub_username/nodejs-image-demo .
Символ .
указывает, что контекст команды build — текущая директория.
Проверьте образы:
- docker images
Результат будет выглядеть следующим образом:
OutputREPOSITORY 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
:
- docker ps
Результат будет выглядеть следующим образом:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e50ad27074a7 your_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
или localhost
. После этого откроется начальная страница вашего приложения:
Вы создали образ приложения, и теперь можете опубликовать его в Docker Hub для будущего использования.
Шаг 4 — Использование хранилища для работы с образами
Прежде всего для размещения образа следует войти в учетную запись Docker Hub:
- docker login -u your_dockerhub_username -p your_dockerhub_password
При входе в домашней директории вашего пользователя будет создан файл ~/.docker/config.json
с вашими учетными данными Docker Hub.
Разместите образ, используя свое имя пользователя вместо your_dockerhub_username
:
- docker push your_dockerhub_username/nodejs-image-demo
Если хотите, вы можете протестировать утилиту реестра образов, уничтожив существующие контейнер приложения и образ, а затем воссоздав их.
Вначале перечислите запущенные контейнеры:
- docker ps
Результат будет выглядеть следующим образом:
OutputCONTAINER 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
, показанный в результатах. Обязательно замените выделенный ниже идентификатор собственным идентификатором CONTAINER ID
:
- docker stop e50ad27074a7
Перечислите все образы, используя флаг -a
:
- docker images -a
Вы увидите следующие результаты с именем образа your_dockerhub_username/nodejs-image-demo
, а также образом узла
и другими образами из вашей сборки:
OutputREPOSITORY 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
Вы увидите образ вашего приложения:
OutputREPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 895MB
Теперь вы можете воссоздать свой контейнер, используя команду из шага 3:
- docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo
Перечислите запущенные контейнеры:
- docker ps
OutputCONTAINER 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
или localhost
еще раз для просмотра работающих приложений.
Другие обучающие руководства
Ниже представлены ссылки на более подробные материалы, связанные с настоящим обучающим руководством:
- Установка Docker Compose в Ubuntu 18.04.
- Выделение ресурсов и управление дистанционными хостами Docker с Docker Machine в Ubuntu 18.04.
- Общий доступ к данным контейнеров Docker
- Обеспечение общего доступа к данным контейнера и хоста Docker.
Также вы можете пройти более длинную серию обучающих руководств От контейнеров к Kubernetes с Node.js, на основе которой адаптировано это обучающее руководство.
Кроме того, вы можете посмотреть в Docker нашу полную библиотеку ресурсов Docker.