Node.js приложение с PM2 и Nginx
Node.js-приложение, запущенное просто командой node app.js в SSH-сессии, умирает вместе с этой сессией и не переживёт падение или перезагрузку сервера. В этой статье вы установите Node.js, запустите приложение через менеджер процессов PM2 (автоперезапуск при падении, автозапуск после reboot), поставите перед ним Nginx как реверс-прокси и проверите, что всё это переживёт перезагрузку VPS.
Что понадобится
- VPS mHost на Ubuntu 22.04/24.04, Debian 11/12 или AlmaLinux/Rocky Linux 8/9.
- Доступ по SSH под
rootлибо пользователем с правамиsudo. - Код вашего Node.js-приложения уже загружен на сервер (например, через
git cloneилиscp) и в нём естьpackage.json. В примерах ниже используется путь/var/www/myapp— замените на свой. - (опционально) домен, A-запись которого указывает на IP сервера — понадобится для
server_nameв Nginx. Без домена тоже можно, тогда используйте IP-адрес сервера.
Шаг 1. Установите Node.js
Два стандартных способа поставить Node.js на VPS: системный пакет из репозитория NodeSource (рекомендуется для продакшена — сразу интегрируется с systemd и PM2) или nvm (удобен, если нужны несколько версий Node или установка без root).
Вариант А: через NodeSource (системный Node.js)
Актуальная LTS-ветка на момент написания — Node.js 24.x. Подставьте нужную версию вместо 24, если требуется другая (например, 22 — предыдущая LTS-ветка).
Ubuntu/Debian:
curl -fsSL https://deb.nodesource.com/setup_24.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt-get install -y nodejsAlmaLinux/Rocky Linux:
sudo dnf module disable -y nodejs
curl -fsSL https://rpm.nodesource.com/setup_24.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo dnf install -y nodejsПроверьте установку:
node -v
npm -vВариант Б: через nvm (без root, несколько версий Node)
nvm ставит Node.js в домашнюю директорию пользователя — без root и с возможностью держать несколько версий и переключаться между ними.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bashПереоткройте SSH-сессию или выполните для текущего шелла (bash):
source ~/.bashrcУстановите и включите текущую LTS-версию:
nvm install --lts
nvm use --lts
node -vШаг 2. Установите PM2 и запустите приложение
- Установите PM2 глобально:
sudo npm install -g pm2- Перейдите в директорию приложения и установите зависимости:
cd /var/www/myapp
npm ci- Запустите приложение через PM2:
pm2 start app.js --name myapp- Проверьте статус и логи:
pm2 status
pm2 logs myappmodule.exports = {
apps: [
{
name: "myapp",
script: "./app.js",
cwd: "/var/www/myapp",
instances: 1,
exec_mode: "fork",
env: {
NODE_ENV: "production",
PORT: 3000
}
}
]
};Запуск: pm2 start ecosystem.config.js.
Шаг 3. Сохраните список процессов и включите автозапуск PM2
Пока список процессов PM2 не сохранён и автозапуск не настроен, приложение не переживёт перезагрузку сервера.
- Сгенерируйте startup-скрипт:
pm2 startupPM2 определит используемую init-систему (systemd) и выведет готовую команду примерно такого вида:
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u root --hp /rootСкопируйте и выполните именно ту команду, которую PM2 вывел у вас, — путь PATH, пользователь (-u) и домашняя директория (--hp) будут подставлены под вашу систему.
- Сохраните текущий список процессов:
pm2 saveШаг 4. Настройте Nginx как реверс-прокси
- Установите Nginx и включите автозапуск:
Ubuntu/Debian:
sudo apt-get install -y nginx
sudo systemctl enable --now nginxAlmaLinux/Rocky Linux:
sudo dnf install -y nginx
sudo systemctl enable --now nginx- Создайте конфиг для сайта — путь зависит от дистрибутива.
Debian/Ubuntu: sites-available/sites-enabled
sudo nano /etc/nginx/sites-available/myappAlmaLinux/Rocky Linux: conf.d
sudo nano /etc/nginx/conf.d/myapp.confСодержимое файла одинаковое для обоих вариантов:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Замените example.com на свой домен или IP сервера, 127.0.0.1:3000 — на адрес и порт, которые слушает приложение.
Для Debian/Ubuntu дополнительно включите сайт симлинком:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/Проверьте конфигурацию и перечитайте её:
sudo nginx -t
sudo systemctl reload nginxsudo setsebool -P httpd_can_network_connect onШаг 5. Откройте порты в файрволе
Порт 80 (и 443, если позже добавите HTTPS) должен быть открыт наружу. Порт самого приложения (в примере — 3000) открывать во внешнем файрволе не нужно — к нему обращается только Nginx на этом же сервере.
Ubuntu/Debian (ufw):
sudo ufw allow 80,443/tcpПодробнее про настройку — в статье «Файрвол ufw».
AlmaLinux/Rocky Linux (firewalld):
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reloadШаг 6. Проверьте, что всё переживёт перезагрузку
- Убедитесь, что и Nginx, и PM2 включены в автозапуск:
systemctl is-enabled nginx
systemctl is-enabled pm2-rootОбе команды должны вывести enabled (замените root на своего пользователя, если pm2 startup выполняли не под root).
- Проверьте на деле — перезагрузите сервер:
sudo rebootПодождите минуту-две, подключитесь по SSH заново и проверьте:
pm2 status
curl -I http://127.0.0.1:3000
curl -I http://localhost/
systemctl status nginxЕсли pm2 status показывает приложение в статусе online, а оба curl возвращают HTTP-ответ — всё настроено верно.
Что дальше
Дальше обычно добавляют HTTPS (например, через Let's Encrypt/certbot) и открывают правило для 443 в файрволе (см. шаг 5). Если на сервере несколько приложений — заведите под каждое отдельный конфиг Nginx и отдельную запись в ecosystem.config.js, и не забывайте про pm2 save после любых изменений списка процессов.