Node.js – это платформа JavaScript для программирования общего назначения, которая позволяет быстро создавать сетевые приложения. Она работает на Linux, macOS, FreeBSD и Windows. Приложения Node.js можно запускать в командной строке, но данный мануал продемонстрирует, как запустить его как сервис (в таком случае приложение сможет автоматически перезагружаться вместе с сервером или при сбое и будет безопасно работать в производственной среде).
Этот мануал поможет подготовить среду Node.js к производству на сервере Ubuntu 20.04. Приложение Node.js будет управляться PM2 и предоставит пользователям безопасный доступ при помощи обратного прокси-сервера Nginx. Сервер Nginx будет поддерживать трафик HTTPS с помощью бесплатного сертификата от сервиса Let’s Encrypt.
Требования
- Сервер Ubuntu 20.04, настроенный по этому мануалу.
- Домен, направленный на внешний IP-адрес сервера. В этом мануале используется условный домен example.com.
- Nginx (можно установить по мануалу Установка Nginx в Ubuntu 20.04)
- SSL-сертификат от Let’s Encrypt (читайте Создание сертификата Let’s Encrypt для Nginx в Ubuntu 20.04).
Выполнив требования, вы получите сервер, обслуживающий стандартную страницу Nginx по адресу https://example.com/.
1: Установка Node.js
Для начала нужно установить Node.js из архива NodeSource.
Установите NodeSource PPA в домашний каталог, чтобы получить доступ к его содержимому. Используйте curl, чтобы извлечь установочный скрипт необходимой версии (укажите её вместо 14.x ):
cd ~
curl -sL https://deb.nodesource.com/setup_14.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
v14.4.0
Примечание: При установке Node.js из архива PPA бинарный файл, как правило, называется nodejs, а не node.
Пакет nodejs содержит бинарный файл nodejs и npm (потому вам не придётся устанавливать npm отдельно).
Для отслеживания обновлений npm использует конфигурационный файл в домашнем каталоге. Он создается при первом запуске npm. Запустите эту команду, чтобы убедиться, что npm установлен и файл на месте:
npm -v
6.14.5
Для работы некоторых компонентов 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@latest -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.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Как видите, PM2 автоматически устанавливает App name (имя файла без расширения .js) и PM2 id. Также PM2 предоставляет другую информацию: PID процесса, текущее состояние, использование памяти.
Запущенное с помощью PM2 приложение будет автоматически перезапускаться в случае ошибок или сбоев, однако автозагрузку приложения нужно настроить отдельно. Для этого существует подкоманда startup. Эта команда генерирует и настраивает сценарий запуска менеджера PM2 и всех его процессов вместе с загрузкой сервера.
pm2 startup systemd
В последней строке вывода находится команда, которую нужно запустить с привилегиями суперпользователя, чтобы добавить PM2 в автозагрузку:
[PM2] Init System found: systemd
8host
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u 8host --hp /home/8host
Запустите сгенерированную команду, чтобы настроить автозапуск PM2.
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u 8host --hp /home/8host
Также можно сохранить процесс PM2 и соответствующую среду.
pm2 save
Эта команда создаст unit-файл для systemd, запускающий pm2 при запуске сервера. Менеджер pm2, в свою очередь, запустит приложение hello.js. Запустите сервис:
sudo systemctl start pm2-8host
Если эта команда выдаст ошибку, попробуйте перезапустить процесс с помощью команды sudo reboot.
Проверьте состояние юнита systemd:
sudo systemctl status pm2-8host
Читайте также: Основы 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/example.com. Откройте его:
sudo nano /etc/nginx/sites-available/example.com
В блоке 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-каталогу. К примеру, если сервер доступен по домену example.com, то приложение будет доступно по ссылке:
http://example.com/
Это отправит запрос приложению hello.js на порт 3000 localhost.
В этот файл можно добавить ещё несколько блоков location, чтобы открыть доступ к другим приложениям, размещённым на этом сервере. К примеру, если бы другое приложение использовало порт 3001, блок, открывающий доступ по ссылке http://example.com/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 в качестве обратного прокси-сервера на сервере Ubuntu 20.04. Эта настройка прокси очень гибкая.