К основному содержимому

Node.js + PM2 на VPS: деплой приложений

VDS / VPS · 10.05.2025 · 4 мин чтения
Иллюстрация к статье «Node.js + PM2 на VPS: деплой приложений»

Node.js позволяет запускать JavaScript на сервере. PM2 управляет процессами: автоматически перезапускает приложение при сбоях и при старте системы.

Установка Node.js через NodeSource

# Установить Node.js 20 LTS
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Проверить версии
node --version   # v20.x.x
npm --version    # 10.x.x

Установка PM2

sudo npm install -g pm2

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

# Клонировать проект
git clone https://github.com/your/app.git /var/www/myapp
cd /var/www/myapp
npm install
npm run build   # для Next.js

# Запустить через PM2
pm2 start npm --name "myapp" -- start

# Для Express
pm2 start server.js --name "myapp"

Автозапуск PM2 при перезагрузке

# Сохранить текущие процессы
pm2 save

# Настроить автозапуск
pm2 startup systemd
# Скопировать и выполнить команду, которую выведет PM2

Полезные команды PM2

pm2 list              # список всех процессов
pm2 logs myapp        # логи приложения
pm2 restart myapp     # перезапуск
pm2 stop myapp        # остановка
pm2 monit             # реалтайм мониторинг CPU/RAM

Nginx как reverse proxy

sudo nano /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name example.com;

    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;
    }
}
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
💡 Используйте pm2 monit для отслеживания потребления RAM в реальном времени. Для Node.js приложений рекомендуем VPS с 1–2 ГБ RAM.

Установка Node.js и PM2

# Node.js 20 LTS через NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install nodejs -y

# PM2 глобально
npm install -g pm2

# Проверка
node --version && pm2 --version

ecosystem.config.js

module.exports = {
  apps: [{
    name: 'myapp',
    script: './server.js',
    instances: 'max',
    exec_mode: 'cluster',
    watch: false,
    max_memory_restart: '500M',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
}

Основные команды PM2

КомандаОписание
pm2 listСписок процессов
pm2 logs myappЛоги приложения
pm2 monitМониторинг в реальном времени
pm2 reload myappZero-downtime перезагрузка
pm2 saveСохранить список процессов
pm2 startupАвтозапуск при загрузке

Автозапуск при перезагрузке

pm2 save
pm2 startup
# Выполните команду, которую выведет PM2
💡 В cluster mode PM2 автоматически балансирует нагрузку между воркерами и перезапускает упавшие инстансы.

Частые ошибки Node.js и PM2

СообщениеЧто означает
Error: listen EADDRINUSE: address already in use :::3000Порт уже занят процессом, который PM2 не отслеживает — приложение запущено вручную через node, а не через pm2 start
PM2 process died with exit code 1 (restart loop)Приложение падает сразу после старта, чаще всего из-за отсутствующих переменных окружения или несовпадения версии Node.js
npm ERR! code EACCES при глобальной установкеnpm install -g запущен без прав или без правильно настроенного префикса для текущего пользователя
После перезагрузки сервера приложение не поднялосьpm2 save не выполнен после последнего изменения списка процессов — автозапуск восстанавливает старый снимок

PM2 vs systemd: что использовать

КритерийPM2systemd
Zero-downtime reloadЕсть, pm2 reloadНет, только restart с разрывом соединений
Кластер-режим для Node.jsВстроенный exec_mode clusterНужно поднимать вручную несколько unit-файлов
Ротация логовЧерез pm2-logrotateЧерез journald из коробки
Простота для не-Node процессовНе предназначенУниверсален для любых сервисов

Когда PM2 не подходит

  • Проект уже управляется Docker и оркестратором (Kubernetes, Swarm) — перезапуск и масштабирование берёт на себя оркестратор
  • Сервер работает под systemd-first дистрибутивом, а команда хочет единый способ управления всеми сервисами через systemctl
  • Приложение не на Node.js — PM2 умеет запускать произвольные бинарники, но это не его основной сценарий
  • Нужна интеграция с cgroups и лимитами ресурсов на уровне ОС — для этого больше подходят systemd или контейнеры

Проверка результата

# Подробный статус процесса: память, аптайм, число рестартов
pm2 describe myapp

# Приложение реально отвечает на HTTP
curl -sI http://localhost:3000/ | head -1

Если pm2 describe показывает большое число restarts за короткое время — это тот самый restart loop, ищите причину в pm2 logs myapp --lines 50. Смежные темы — базовая настройка Nginx и Docker Compose на VDS как альтернатива PM2.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке