// Tutorial //

Создание приложения Node.js с помощью Docker [Краткое руководство]

Published on March 5, 2020
Default avatar
By Kathleen Juell
Developer and author at DigitalOcean.
Создание приложения Node.js с помощью Docker [Краткое руководство]

Введение

В этом обучающем руководстве мы создадим образ приложения для статического сайта, который использует веб-фреймворки Express и Bootstrap. Затем вы создадите контейнер с использованием этого образа, разместите его в Docker Hub и используете его для сборки другого контейнера, продемонстрировав способ воссоздания и масштабирования вашего приложения.

Более подробные указания с детальными разъяснениями каждого этапа приведены в обучающем руководстве Создание приложения Node.js с помощью Docker.

Предварительные требования

Для данного обучающего руководства вам потребуется следующее:

  • Пользователь sudo на сервере или в локальной среде.
  • Docker.
  • Node.js и npm.
  • Учетная запись Docker Hub.

Шаг 1 — Установка зависимостей вашего приложения

Вначале создайте для вашего проекта директорию в домашней директории пользователя без привилегий root:

  1. mkdir node_project

Перейдите в эту директорию:

  1. cd node_project

Это будет корневая директория проекта.

Затем создайте файл package.json с зависимостями вашего проекта:

  1. 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",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }
}

Установите зависимости вашего проекта:

  1. npm install

Шаг 2 — Создание файлов приложения

Мы создадим сайт, который предоставляет пользователям данные об акулах.

Откройте файл app.js в главной директории проекта, чтобы определить маршруты проекта:

  1. 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:

  1. mkdir views

Откройте файл index.html:

  1. 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:

  1. 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:

  1. 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;
}

Запустите приложение:

  1. npm start

Откройте в браузере адрес http://your_server_ip:8080 или localhost:8080, если вы работаете локально. Вы увидите следующую начальную страницу:

Начальная страница приложения

Нажмите кнопку Get Shark Info (Получить информацию об акулах). Вы увидите следующую информационную страницу:

Страница информации об акулах

Ваше приложение запущено и работает. Когда вы будете готовы, покиньте сервер, нажав CTRL+C.

Шаг 3 — Создание файла Dockerfile

Создайте файл Dockerfile в корневой директории вашего проекта:

  1. 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:

  1. docker build -t your_dockerhub_username/nodejs-image-demo .

Символ . указывает, что контекст команды build — текущая директория.

Проверьте образы:

  1. docker images

Результат будет выглядеть следующим образом:

Output
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

Запустите следующую команду для сборки контейнера с использованием этого образа:

  1. docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Проверьте список работающих контейнеров с помощью docker ps:

  1. docker ps

Результат будет выглядеть следующим образом:

Output
CONTAINER 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:

  1. docker login -u your_dockerhub_username -p your_dockerhub_password

При входе в домашней директории вашего пользователя будет создан файл ~/.docker/config.json с вашими учетными данными Docker Hub.

Разместите образ, используя свое имя пользователя вместо your_dockerhub_username:

  1. docker push your_dockerhub_username/nodejs-image-demo

Если хотите, вы можете протестировать утилиту реестра образов, уничтожив существующие контейнер приложения и образ, а затем воссоздав их.

Вначале перечислите запущенные контейнеры:

  1. docker ps

Результат будет выглядеть следующим образом:

Output
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, показанный в результатах. Обязательно замените выделенный ниже идентификатор собственным идентификатором CONTAINER ID:

  1. docker stop e50ad27074a7

Перечислите все образы, используя флаг -a:

  1. 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 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

Удалите остановленный контейнер и все образы, включая неиспользуемые или недействительные образы, с помощью следующей команды:

  1. docker system prune -a

Удалив все образы и контейнеры, вы можете извлечь образ приложения из Docker Hub:

  1. docker pull your_dockerhub_username/nodejs-image-demo

Еще раз перечислите образы:

  1. docker images

Вы увидите образ вашего приложения:

Output
REPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 11 minutes ago 895MB

Теперь вы можете воссоздать свой контейнер, используя команду из шага 3:

  1. docker run --name nodejs-image-demo -p 80:8080 -d your_dockerhub_username/nodejs-image-demo

Перечислите запущенные контейнеры:

  1. docker ps
Output
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 или localhost еще раз для просмотра работающих приложений.

Другие обучающие руководства

Ниже представлены ссылки на более подробные материалы, связанные с настоящим обучающим руководством:

Также вы можете пройти более длинную серию обучающих руководств От контейнеров к Kubernetes с Node.js, на основе которой адаптировано это обучающее руководство.

Кроме того, вы можете посмотреть в Docker нашу полную библиотеку ресурсов Docker.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
Leave a comment