• База знаний
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Статья также доступна на украинском (перейти к просмотру).

Пошаговая инструкция по созданию и запуску Node.js-приложения в Docker-контейнере: от установки Node.js до конфигурации Dockerfile и запуску веб-сайта на Express и Bootstrap. Все на примере Debian 12 VPS – Тел. +380 (44) 364 05 71 - Компания FREEhost.UA

Содержание:

В одной из наших предыдущих работ мы рассматривали процесс создания и запуска PHP-дополнение к Docker. Теперь попробуем продемонстрировать в средеDocker работу с приложениемтипа Node.js. Нашей основной задачей будет получение «зафиксированного» в Docker-контейнеры изолированной среды для создания, редактирования и запуска Node.js приложения. Затем такой контейнер можно «переправить» на любой другой хост или поместить в Docker-Hub репозиторий для дальнейшего использования и/или раздачи в открытом доступе.         

Исходные положения

Наше приложение будет состоять из нескольких взаимосвязанных статических html-страниц веб-сайта, построенного с использованием фреймворков Bootstrap и Express. Приложение будет создано и размещено на VPS-серверы под управлением ОС Debian 12 с заранее развернутым Docker-средой

Для выполнения нашей задачи мы должны получить полностью трудоспособный Node.js-приложение, после чего создать на его базе Docker-шаблон. И уже потом запустить процесс формирования готового контейнера с соответствующими зависимостями. Это и будет нашей конечной целью

Разобьем процесс на несколько отдельных этапов

  • азвертывание среды выполнения JavaScript;

  • Установление зависимостей;

  • Создание файлов приложения;

  • Запуск веб-приложения;

  • Создание Docker-шаблона;

  • Строительство контейнера.

Ниже будет выполнен каждый из указанных этапов.

Развертывание среды выполнения

Установить Node.js можно из репозитория Debian или из альтернативного репозитория PPA (Personal Package Archive) где есть широкий выбор версий программы. Воспользуемся последним способом. Это позволит избежать отдельной установки менеджера пакетов npm, поскольку он включен в пакет NodeSource nodejs. 

Перейдем в домашний каталог пользователя testing_node с правами sudo и введем команду curl для получения скрипта, необходимого для установки нужной версии Node.js. Для этого введем в терминале:

$ cd ~
$ curl -sL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh

$ cd ~

Проверим содержимое скрипта nodesource_setup.sh с помощью редактора, чтобы убедиться в его безопасности:

$ nano nodesource_setup.sh

$ nano nodesource_setup.sh

Выйдем из редактора (Ctrl+X). 

Теперь мы можем запустить сценарий средствами командной оболочки bash. При этом PPA-репозиторий будет добавлен в конфигурацию нашей системы и будет обновлен локальный кэш пакетов:

$ sudo bash nodesource_setup.sh

$ sudo bash nodesource_setup.sh

Выход команды: 2025-04-05 18:00:41 - Repository configured successfully. Это значит, что сценарий корректно проделал свою работу.

Установим Node.js:

$ sudo apt install nodej

$ sudo apt install nodej

Выход команды: Настройка nodejs (20.19.0-1nodesource1)... . Итак, программа установлена. 

Проверим ее версию:

$ node -

$ node -

Результат: v20.19.0

Итак, Node.js да НПМ корректно установлены в нашей системе и потому можно переходить к следующему этапу.

Установление зависимостей

Файлы веб-приложения содержат код, статический контент и зависимости. Нам нужно свести эти зависимости в отдельный файл в формате JSON. Но прежде создадим каталог проекта с названием node_docker.

Введем в терминале:

$ mkdir node_docker
$ cd node_docker

$ cd node_docker

Создадим файл package.json, который будет содержать зависимости проекта и другие идентификационные данные: 

$ nano package.jso

Содержимое файла будет следующим:

{
  "name": "nodejs-image-application",
  "version": "1.0.0",
  "description": "nodejs image new application",
  "author": "Alexander R. <alexandr7500@meta.ua>",
  "license": "MIT",
  "main": "app.js",
  "keywords": [
    "nodejs",
    "bootstrap",
    "express"
  ],
  "dependencies": {
    "express": "^4.16.4"
  }

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

Вставим приведенный код в окно редактора nano, как показано ниж

Вставим приведенный код в окно редактора nano

Сохраним внесенные изменения и выйдем из редактора.

Для установки зависимостей, перечисленных в файле package.json в каталог проекта, выполним следующую команду:

$ npm install

$ npm install

Пакеты установлены. Переходим к следующему этапу.

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

В корневом каталоге проекта создадим файл приложения с именем app.js. Для этого введем в терминале:

$ nano app.js

Код файла приведен ниже:

const express = require('express');
const app = express();
const router = express.Router();
const path = __dirname + '/performances/';
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('/newinfo', function(req,res){
  res.sendFile(path + 'newinfo.html');
});
app.use(express.static(path));
app.use('/', router);
app.listen(port, function () {
  console.log('New port listening application')
})

При помощи конструкций const будут созданы объекты роутера и программы Express, а также определены базовая директория и порт.

При помощи конструкции router определены маршруты приложения.

Последняя часть кода объединяет программу роутера и статические данные.

Вставим приведенный код в файл app.js:

файл app.js

Сохраним файл на диске и выйдем из редактора.

Теперь перейдем к созданию файлов со статическим контентом. Но прежде нужно создать директорию для их размещения. 

Введем в терминале: 

$ mkdir performances

$ mkdir performances

Откроем главный индексный файл для внесения контента:

$ nano performances/index.html

Ниже приведен код указанного файла, импортируемого Бутстрап:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>About new cases in building mobile communications</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">View Control</span>
            </button> <a class="navbar-brand" href="#">All about mobile communications</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="/newinfo" class="nav-link"> Mobile communications</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="jumbotron">
        <div class="container">
            <h1>New methods of building mobile communications</h1>
            <p>Let's start our training</p>
            <br>
            <p><a class="btn btn-primary btn-lg" href="/newinfo" role="button">Additional information about mobile communications</a>
            </p>
        </div>
    </div>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <h3>What types of data transmission systems exist?</h3>
                <p> Currently, there are more than a dozen known solutions for designing data transmission systems using radio waves.
                </p>
            </div>
            <div class="col-lg-6">
                <h3>What is the effectiveness of existing solutions?</h3>
                <p>The effectiveness of a particular solution depends on the conditions in which it is applied.
                </p>
            </div>
        </div>
    </div>
</body>
</html>

Как видим, код содержит ссылку на веб-страницу newinfo.html, которую мы тоже будем создавать. 

В открывшемся окне редактора код выглядит следующим образом:

newinfo.html

Сохраним изменения и закроем файл. 

Теперь перейдем к созданию файла newinfo.html, содержащий более подробную информацию о мобильных технологиях.

Вызовем редактор:  

$ nano performances/newinfo.html

Код файла приведен ниже: 

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Digital Communications News</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">View Control</span>
        </button> <a class="navbar-brand" href="/">All about mobile communications</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="/newinfo" class="nav-link">Mobile communications</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<div class="jumbotron text-center">
    <h1>Mobile communications New Info</h1>
</div>
<div class="container">
    <div class="row">
        <div class="col-lg-6">
            <p>
                <div class="caption">New technologies for data transmission using ultra-high frequencies are emerging.
                </div>
                <img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Photo1">
            </p>
        </div>
        <div class="col-lg-6">
            <p>
                <div class="caption">New approaches to managing data encryption are emerging</div>
                <img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Photo2">
            </p>
        </div>
    </div>
</div>
</html>

Вставим код в файл:

Фото 12

Сохраним файл на диске и выйдем из редактора.

Код каждого из созданных нами файлов содержит ссылку на таблицу стилей CSS. Создадим ее и каталог CSS, в котором она будет содержаться:  

$ mkdir performances/css

$ mkdir performances/css

$ nano Performances/css/styles.css

Приведенный код определяет типы шрифтов и цвета элементов для обоих html-страниц:

.navbar {
    margin-bottom: 1;
}
body {
    background: #030B3A;
    color: #ffffff;
    font-family: 'Merriweather', sans-serif;
}
h1,
h2 {
    font-weight: normal;
}
p {
    font-size: 17px;
    color: #ffffff;
}
.jumbotron {
    background: #1247AC;
    color: white;
    text-align: center;
}
.jumbotron p {
    color: white;
    font-size: 24px;
}
.btn-primary {
    color: #fff;
    text-color: #120000;
    border-color: white;
    margin-bottom: 10px;
}
img,
video,
audio {
    margin-top: 10px;
    max-width: 90%;
}
div.caption: {
    float: left;
    clear: both;
}

Вставим код в окно редактору:

ФОТО 14

Сохраним данные и закроем файл.

Работа со статическим контентом приложения завершена, и поэтому можно переходить к его использованию. 

Запуск веб-приложения

Перед запуском программы настроим брандмауэр нашей системы, который обычно позволяет трафик через SSH, но для портов необходимо изменять настройки. Разрешим трафик на порт 8080:

$ sudo ufw allow 8080

$ sudo ufw allow 8080

Выход команды: Rules updated. Следовательно, трафик через порт разрешен.

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

$ node app.js

$ node app.js

Теперь приложение будет находиться в режиме прослушивания порта 8080, как и было нами определено в настройках проекта.

Для проверки правильности работы приложения перейдем к просмотру содержимого индексного файла со статическим контентом. Для этого введем в адресной строчке браузеру следующий адрес:  

http://178.20.159.96:8080

Здесь 178.20.159.96 – IP-адрес нашего сервера.

Результат показан ниже.

Результат

Для перехода на веб-страницу с именем newinfo.html нажмем кнопку мыши по названию «Additional information about mobile communications», после чего страница загрузится в открывшемся окне, как показано ниже: 

Additional information about mobile

Итак, мы имеем работоспособное приложение и поэтому перейдем к этапу его создания Docker-шаблон. 

Создание Docker-шаблона

Перед тем, как создавать шаблон программы, необходимо подготовить Dockerfile что позволит нам в дальнейшем восстановить ее или внести любые изменения. 

Вызовем редактор:

$ nano 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, который будет использоваться для блокировки копирования определенных файлов в контейнер проекта. К ним, в частности, относятся npm-журналы, модули узлов и другие.  

Введем в терминале:

$ nano .dockerignore
node_modules
npm-debug.log
Dockerfile
.dockerignore

node_modules

Сохраним внесенные изменения и вернемся к командной строчке.

После этого создадим шаблон приложения с именем nodejs-image-application. 

$ sudo docker build -t alexandr7500/nodejs-image-application .

Здесь alexandr7500 – имя владельца учетной записи в Docker Hub. $ sudo docker build -t alexandr7500/nodejs-image-application

Построение контейнера

После создания шаблона можно перейти к созданию контейнера приложения. Для этого выполним в терминале следующую команду: 

$ sudo docker run --name nodejs-image-application -p 80:8080 -d alexandr7500/nodejs-image-application

В результате, мы получили контейнер из Node.js-приложение, которое можно запускать и масштабировать по нашему желанию в любой среде, а также загружать в Docker Hub репозиторий. 

Для проверки работы достаточно ввести в адресной строчке браузера IP-адрес вашего сервера без указания порта

Результат работы приложения приведен ниже.

178.20.159.96  Результат работы приложения приведен ниже.

Подписывайтесь на наш телеграмм-канал https://t.me/freehostua, чтобы быть в курсе новых полезных материалов

Смотрите наш канал Youtube на https://www.youtube.com/freehostua.

Мы в чем ошиблись, или что-то пропустили?

Напишите об этом в комментариях, мы с удовольствием ответим и обсуждаем Ваши замечания и предложения.

Дата: 10.04.2025
Автор: Александр Ровник
Голосование

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:

comments powered by Disqus
navigate
go
exit
Спасибо, что выбираете FREEhost.UA