До основного вмісту

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 проти 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.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці