Подготовка приложения Node.js к производству в Debian 10

Node.js – это платформа JavaScript для программирования общего назначения, которая позволяет быстро создавать сетевые приложения. Данная платформа работает на Linux, macOS, FreeBSD и Windows. Приложения Node.js можно запускать в командной строке, но данный мануал продемонстрирует, как запустить его как сервис (в таком случае приложение сможет автоматически перезагружаться вместе с сервером или при сбое и будет безопасно работать в производственной среде).

Этот мануал поможет подготовить приложение Node.js к среде производства на сервере Debian 10. Приложение Node.js будет управляться PM2 и предоставит пользователям безопасный доступ при помощи обратного прокси-сервера Nginx. Сервер Nginx будет поддерживать трафик HTTPS с помощью бесплатного сертификата от сервиса Let’s Encrypt.

Требования

Выполнив требования, вы получите сервер, обслуживающий стандартную страницу Nginx по адресу https://your_domain/.

1: Установка Node.js

Для начала нужно при помощи архива NodeSource установить Node.js.

Установите PPA в домашний каталог, чтобы получить доступ к его содержимому. Для этого вам понадобится curl:

sudo apt update
sudo apt install curl

Используйте curl, чтобы извлечь установочный скрипт необходимой версии (укажите её вместо 10.x ).

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

Чтобы просмотреть содержимое скрипта, введите:

nano nodesource_setup.sh

Запустите скрипт:

sudo bash nodesource_setup.sh

Архив PPA будет добавлен в настройки. Индекс пакетов обновится автоматически. После запуска установочного сценария nodesource можно установить пакет Node.js:

sudo apt install nodejs

Чтобы проверить версию Node.js, введите:

nodejs -v
v10.16.0

Примечание: При установке Node.js из архива PPA бинарный файл, как правило, называется nodejs, а не node.

Пакет nodejs содержит бинарный файл nodejs и npm (поэтому вам не придётся устанавливать npm отдельно).

Для отслеживания обновлений npm использует конфигурационный файл в домашнем каталоге. Он создается при первом запуске npm. Запустите эту команду, чтобы убедиться, что npm установлен и файл на месте:

npm -v
6.9.0

Для работы некоторых компонентов npm (компилирующих исходный код и т.п.) необходим пакет build-essential:

sudo apt install build-essential

Теперь можно приступать к созданию приложения.

2: Создание приложения Node.js

В качестве примера можно создать простое приложение Hello World; оно будет возвращать фразу Hello World на любой запрос HTTP. Такое приложение можно в дальнейшем использовать в качестве шаблона для более сложного приложения.

Примечание: Копируя код, не забудьте указать свой IP-адрес вместо условных данных.

Создайте файл приложения Node.js и откройте его в текстовом редакторе (здесь файл называется hello.js):

cd ~
nano hello.js

Вставьте в него такой код:

const http = require('http');
const hostname = 'localhost';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});

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

Данное приложение будет слушать заданный адрес (localhost) и порт (3000) и возвращать фразу Hello World с HTTP-кодом 200. При прослушивании localhost удалённые клиенты не смогут получить доступ к приложению.

Чтобы протестировать приложение, введите:

node hello.js

Команда вернет:

Server running at http://localhost:3000/

Примечание: Запуская Node.js таким образом, вы блокируете дополнительные команды. Команды будут доступны после остановки приложения (Ctrl-C).

Чтобы протестировать приложение, откройте новый терминал и подключитесь к localhost с помощью curl:

curl http://localhost:3000

Если на экране появился следующий вывод, приложение работает правильно:

Hello World

Если такой вывод не появился, убедитесь, что приложение Node.js запущено и правильно настроено (слушает правильный адрес и порт).

Остановите приложение, нажав Ctrl+C.

3: Установка PM2

Теперь нужно установить PM2. Это менеджер процессов Node.js. PM2 предоставляет простой способ управления и демонизации приложений.

Установку можно выполнить при помощи пакетного менеджера npm.

sudo npm install pm2 -g

При помощи опции –g менеджер npm выполнит глобальную установку PM2.

Менеджер процессов PM2 очень прост в использовании. Рассмотрим основы его работы.

Для запуска приложений в фоновом режиме используется команда pm2 start:

pm2 start hello.js

Также эта команда добавит приложение в список процессов PM2, который выводится на экран при запуске каждого приложения:

[PM2] Spawning PM2 daemon with pm2_home=/home/8host/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/8host/hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬───────┬──────────┐

│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user  │ watching │


├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤


│ hello    │ 0  │ fork │ 1338 │ online │ 0       │ 0s     │ 0%  │ 23.0 MB   │ 8host │ disabled │


└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘

Use `pm2 show <id|name>` to get more details about an app

Как видите, PM2 автоматически устанавливает App name (имя файла без расширения .js) и PM2 id. Также PM2 предоставляет другую информацию: PID процесса, текущее состояние, использование памяти.

Запущенное с помощью PM2 приложение будет автоматически перезапускаться в случае ошибок или сбоев, однако автозагрузку приложения нужно настроить отдельно. Для этого существует подкоманда startup. Эта команда генерирует и настраивает сценарий запуска менеджера PM2 и всех его процессов вместе с загрузкой сервера.

sudo pm2 startup

На экране появится такой вывод, описывающий конфигурацию сервиса:

[PM2] Init System found: systemd
Platform systemd
Template
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target
[Service]
Type=forking
User=root
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/root/.pm2
PIDFile=/root/.pm2/pm2.pid
Restart=on-failure
ExecStart=/usr/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/lib/node_modules/pm2/bin/pm2 kill
[Install]
WantedBy=multi-user.target
Target path
/etc/systemd/system/pm2-root.service
Command list
[ 'systemctl enable pm2-root' ]
[PM2] Writing init configuration in /etc/systemd/system/pm2-root.service
[PM2] Making script booting at startup...
[PM2] [-] Executing: systemctl enable pm2-root...
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-root.service → /etc/systemd/system/pm2-root.service.
[PM2] [v] Command successfully executed.
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save
[PM2] Remove init script via:
$ pm2 unstartup systemd

Только что вы создали юнит systemd, который запускает pm2 вместе с сервером.

Запустите сервис с помощью systemctl:

sudo systemctl start pm2-root.service

Проверьте состояние юнита:

systemctl status pm2-root.service

Вы получите примерно такой вывод:

pm2-root.service - PM2 process manager
Loaded: loaded (/etc/systemd/system/pm2-root.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2019-07-12 16:09:54 UTC; 4s ago

Читайте также: Основы Systemd: управление сервисами и журналирование

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

Остановить приложение можно при помощи:

pm2 stop app_name_or_id

Чтобы перезапустить приложение, введите:

pm2 restart app_name_or_id

Список приложений, управляемых PM2, можно просмотреть при помощи следующей подкоманды:

pm2 list

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

pm2 info app_name

Подкоманда monit показывает данные процесса PM2: состояние приложения, использование CPU и памяти:

pm2 monit

Запуск PM2 без каких-либо аргументов отобразит страницу справки, на которой можно найти подробные примеры использования PM2.

Теперь нужно настроить обратный прокси.

4: Nginx как обратный прокси-сервер

Итак, приложение запущено и прослушивает localhost. Теперь нужно настроить доступ к нему. Установите Nginx как обратный прокси-сервер.

В мануале из требований вы установили Nginx и поместили конфигурации в файл /etc/nginx/sites-available/your_domain. Откройте его:

sudo nano /etc/nginx/sites-available/your_domain

В блоке server найдите блок location /. Замените его содержимое следующими конфигурациями. Если ваше приложение прослушивает другой порт, укажите его.

server {
...
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
...
}

Теперь сервер будет отвечать на запросы к root-каталогу. К примеру, если сервер доступен по домену your_domain, то приложение будет доступно по ссылке:

https://your_domain/

Это отправит запрос приложению hello.js на порт 3000 localhost.

В этот файл можно добавить ещё несколько блоков location, чтобы открыть доступ к другим приложениям, размещённым на этом сервере. К примеру, если бы другое приложение использовало порт 3001, блок, открывающий доступ по ссылке https://your_domain/app2, имел бы такой вид:

server {
...
location /app2 {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
...
}

Сохраните и закройте файл. Проверьте файл на наличие ошибок:

sudo nginx -t

Перезапустите Nginx:

sudo systemctl restart nginx

Если приложение Node.js запущено, а сервер Nginx правильно настроен, вы можете получить доступ к приложению через обратный прокси-сервер Nginx. Попробуйте открыть приложение в браузере.

Заключение

Теперь приложение Node.js запущено и использует Nginx в качестве обратного прокси-сервера на сервере Debian 9. Эта настройка прокси очень гибкая и может предоставить вашим пользователям доступ к другим приложениям или статическому контенту.

Tags: , , , , ,