Введение
Node.js – это среда выполнения JavaScript с открытым исходным кодом для создания серверных и сетевых приложений. Платформа работает на Linux, macOS, FreeBSD и Windows. Хотя вы можете запускать приложения Node.js из командной строки, этот учебник сосредоточен на их запуске в качестве службы. Это означает, что они будут перезапускаться при перезагрузке или сбое и безопасны для использования в производственной среде.
В этом учебнике вы настроите готовую к использованию в производстве среду Node.js на одном сервере с Rocky Linux 9. На этом сервере будет запущено приложение Node.js, управляемое PM2, и предоставлен безопасный доступ пользователям к приложению через обратный прокси Nginx. Сервер Nginx будет предлагать HTTPS с использованием бесплатного сертификата, предоставленного Let’s Encrypt.
Предварительные требования
Это руководство предполагает, что у вас есть следующее:
- A Rocky Linux 9 server setup, as described in the initial server setup guide for Rocky Linux 9. You should have a non-root user with sudo privileges and an active firewall.
- A domain name pointed at your server’s public IP. This tutorial will use the domain name example.com throughout.
- Установленный Nginx, как описано в руководстве Как установить Nginx на Rocky Linux 9.
- Nginx настроен с SSL с использованием сертификатов Let’s Encrypt. Как защитить Nginx с Let’s Encrypt на Rocky Linux 9 проведет вас через процесс.
- Node.js установлен на вашем сервере. Как установить Node.js на Rocky Linux 9
Когда вы завершите предварительные требования, у вас будет сервер, обслуживающий страницу-заполнитель по умолчанию вашего домена по адресу https://example.com/
.
Шаг 1 — Создание приложения Node.js
Давайте напишем приложение Hello World, которое возвращает “Hello World” на любые HTTP-запросы. Это примерное приложение поможет вам начать работу с Node.js. Вы можете заменить его на свое собственное приложение — просто убедитесь, что вы модифицировали ваше приложение для прослушивания соответствующих IP-адресов и портов.
Текстовый редактор по умолчанию, поставляемый с Rocky Linux 9, – vi
. vi
– это чрезвычайно мощный текстовый редактор, но он может быть несколько сложным для пользователей без опыта работы с ним. Вам может понадобиться установить более удобный для пользователя редактор, такой как nano
, чтобы облегчить редактирование файлов конфигурации на вашем сервере Rocky Linux 9:
- sudo dnf install nano
Теперь, используя nano
или ваш текстовый редактор по умолчанию, создайте образец приложения с именем hello.js
:
- 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}/`);
});
Сохраните файл и выйдите из редактора. Если вы используете nano
, нажмите Ctrl+X
, затем, когда будет предложено, введите Y
, а затем нажмите Enter.
Это приложение Node.js слушает указанный адрес (localhost
) и порт (3000
), и возвращает “Hello World!” с HTTP-кодом успеха 200
. Поскольку мы слушаем localhost
, удаленные клиенты не смогут подключиться к нашему приложению.
Чтобы проверить ваше приложение, введите:
- node hello.js
Вы получите следующий вывод:
OutputServer running at http://localhost:3000/
Примечание: Запуск приложения Node.js таким образом заблокирует выполнение дополнительных команд до тех пор, пока приложение не будет завершено, нажав CTRL+C
.
Чтобы протестировать приложение, откройте другую сессию терминала на вашем сервере и подключитесь к localhost
с помощью curl
:
- curl http://localhost:3000
Если вы получите следующий вывод, приложение работает правильно и слушает правильный адрес и порт:
OutputHello World!
Если вы не получите ожидаемый вывод, убедитесь, что ваше приложение Node.js запущено и настроено на прослушивание правильного адреса и порта.
Как только вы убедитесь, что все работает, завершите выполнение приложения (если вы еще этого не сделали), нажав CTRL+C
.
Шаг 2 — Установка PM2
Теперь давайте установим PM2, менеджер процессов для приложений на Node.js. PM2 позволяет демонизировать приложения, чтобы они запускались в фоновом режиме как служба.
Используйте npm
, чтобы установить последнюю версию PM2 на вашем сервере:
- sudo npm install pm2@latest -g
Опция -g
указывает npm
установить модуль глобально, чтобы он был доступен системно.
Давайте сначала воспользуемся командой pm2 start
, чтобы запустить ваше приложение, hello.js
, в фоновом режиме:
- pm2 start hello.js
Это также добавляет ваше приложение в список процессов PM2, который выводится каждый раз при запуске приложения:
Output...
[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
Как указано выше, PM2 автоматически присваивает Имя приложения
(на основе имени файла, без расширения .js
) и идентификатор PM2
. PM2 также сохраняет другую информацию, такую как PID
процесса, его текущий статус и использование памяти.
Приложения, запущенные под управлением PM2, будут автоматически перезапускаться, если приложение выйдет из строя или будет завершено, но мы можем предпринять дополнительные шаги, чтобы приложение запускалось при загрузке системы, используя подкоманду startup
. Эта подкоманда создает и настраивает скрипт запуска для запуска PM2 и управляемых им процессов при загрузке сервера:
- pm2 startup systemd
Output…
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Скопируйте и выполните предоставленную команду (это сделано для избежания проблем с разрешениями при запуске инструментов Node.js от имени sudo
):
- sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Output…
[ 'systemctl enable pm2-sammy' ]
[PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service
[PM2] Making script booting at startup...
[PM2] [-] Executing: systemctl enable pm2-sammy...
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service.
[PM2] [v] Command successfully executed.
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save
[PM2] Remove init script via:
$ pm2 unstartup systemd
Теперь вам потребуется внести изменение в службу системы, которая была только что сгенерирована, чтобы сделать ее совместимой с системой безопасности SELinux Rocky Linux. С помощью nano
или вашего любимого текстового редактора откройте /etc/systemd/system/pm2-sammy.service
:
- sudo nano /etc/systemd/system/pm2-sammy.service
В блоке [Service]
файла конфигурации замените содержимое параметра PIDFile
на /run/pm2.pid
, как показано ниже, и добавьте другую выделенную строку Environment
:
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target
[Service]
Type=forking
User=sammy
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/home/sammy/.local/bin:/home/sammy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/sammy/.pm2
PIDFile=/run/pm2.pid
Restart=on-failure
Environment=PM2_PID_FILE_PATH=/run/pm2.pid
ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill
[Install]
Сохраните и закройте файл. Теперь вы создали службу systemd unit, которая запускает pm2
для вашего пользователя при загрузке. Этот экземпляр pm2
, в свою очередь, запускает hello.js
.
Запустите службу с помощью systemctl
:
- sudo systemctl start pm2-sammy
Проверьте состояние службы systemd:
- systemctl status pm2-sammy
Для подробного обзора systemd, пожалуйста, ознакомьтесь с Основы systemd: работа с сервисами, юнитами и журналом.
Кроме того, помимо того, что мы рассмотрели, PM2 предоставляет множество подкоманд, которые позволяют управлять или получать информацию о ваших приложениях.
Остановите приложение с помощью этой команды (указав имя App name
или id
PM2):
- pm2 stop app_name_or_id
Перезапустите приложение:
- pm2 restart app_name_or_id
Выведите список приложений, управляемых в данный момент PM2:
- pm2 list
Получите информацию о конкретном приложении, используя его App name
:
- pm2 info app_name
Мониторинг процессов PM2 можно вызвать с помощью подкоманды monit
. Это отображает состояние приложения, использование ЦП и память:
- pm2 monit
Обратите внимание, что запуск pm2
без аргументов также отобразит справочную страницу с примерами использования.
Теперь, когда ваше приложение Node.js запущено и управляется PM2, давайте настроим обратный прокси.
Шаг 3 — Настройка Nginx в качестве обратного прокси-сервера
Ваше приложение запущено и слушает localhost
, но вам нужно настроить способ доступа для ваших пользователей. Мы настроим веб-сервер Nginx в качестве обратного прокси для этой цели.
В предварительном руководстве вы настроили конфигурацию Nginx в файле /etc/nginx/conf.d/ваш_домен.conf
. Откройте этот файл для редактирования:
- sudo nano /etc/nginx/conf.d/your_domain.conf
Внутри блока 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;
}
...
}
Это настраивает сервер для ответа на запросы в его корне. Предполагая, что наш сервер доступен по ваш_домен
, обращение по адресу https://ваш_домен/
через веб-браузер отправит запрос к файлу hello.js
, слушающему порт 3000
на localhost
.
Вы можете добавить дополнительные блоки location
в тот же блок сервера, чтобы предоставить доступ к другим приложениям на том же сервере. Например, если вы также запускаете еще одно приложение Node.js на порту 3001
, вы можете добавить этот блок location
, чтобы разрешить доступ к нему через https://ваш_домен/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;
}
...
}
Как только вы закончите добавление блоков location
для ваших приложений, сохраните файл и закройте редактор.
Убедитесь, что вы не ввели синтаксические ошибки, набрав:
- sudo nginx -t
Перезапустите Nginx:
- sudo systemctl restart nginx
Предполагая, что ваше приложение Node.js работает, и ваша конфигурация приложения и Nginx корректны, вы теперь должны иметь доступ к вашему приложению через обратный прокси Nginx. Попробуйте это, обратившись к URL-адресу вашего сервера (его общедоступный IP-адрес или доменное имя).
Заключение
Поздравляю! Теперь у вас есть ваше приложение Node.js, работающее за обратным прокси Nginx на сервере Rocky Linux 9. Эта настройка обратного прокси достаточно гибкая, чтобы предоставлять вашим пользователям доступ к другим приложениям или статическому веб-контенту, который вы хотите поделиться.
После этого вам может понадобиться изучить Как создать приложение Node.js с помощью Docker.