Home » Как настроить продакшен окружение Node.js с PM2 на Ubuntu VPS
Как настроить продакшен окружение Node.js с PM2 на Ubuntu VPS

Как настроить продакшен окружение Node.js с PM2 на Ubuntu VPS

В продакшене Node.js-приложение требует стабильности, управления процессами и автоматического восстановления после сбоев. PM2 — это мощный менеджер процессов, который превращает ваш простой скрипт в полноценный продакшен-сервис. Настройка правильного окружения на Ubuntu VPS — это не только про запуск приложения, но и про мониторинг, балансировку нагрузки, логирование и автоматический перезапуск при крашах.

Разберём пошагово, как поднять надёжную инфраструктуру для Node.js с PM2, настроить reverse proxy через nginx, организовать систему логов и автоматизировать деплой. Это руководство поможет избежать типичных ошибок и создать production-ready окружение, которое будет работать стабильно даже под нагрузкой.

Как работает PM2 и зачем он нужен

PM2 (Process Manager 2) — это daemon менеджер процессов для Node.js приложений. В отличие от простого запуска через node app.js, PM2 предоставляет:

  • Автоматический перезапуск при крашах или изменениях кода
  • Кластеризацию — запуск нескольких инстансов приложения
  • Мониторинг ресурсов в реальном времени
  • Логирование с ротацией логов
  • Startup scripts для автозапуска при перезагрузке сервера

PM2 работает как daemon процесс, который управляет дочерними процессами вашего приложения. Когда основной процесс падает, PM2 немедленно перезапускает его, обеспечивая нулевое время простоя (zero downtime).

Подготовка Ubuntu VPS

Для начала нужен качественный VPS на Ubuntu. Минимальные требования: 1GB RAM, 1 CPU, 20GB SSD для небольших приложений. Для высоконагруженных проектов рассмотрите выделенный сервер.

Обновляем систему и устанавливаем необходимые пакеты:

sudo apt update && sudo apt upgrade -y
sudo apt install curl software-properties-common apt-transport-https ca-certificates gnupg lsb-release -y

Устанавливаем Node.js через NodeSource репозиторий (рекомендуется для продакшена):

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
node --version
npm --version

Установка и базовая настройка PM2

Устанавливаем PM2 глобально:

sudo npm install pm2@latest -g
pm2 --version

Создаём тестовое приложение для демонстрации:

mkdir ~/myapp && cd ~/myapp
npm init -y
npm install express

Простой Express сервер (app.js):

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({ 
    message: 'Hello from PM2!', 
    pid: process.pid,
    uptime: process.uptime()
  });
});

app.get('/health', (req, res) => {
  res.json({ status: 'OK', timestamp: new Date().toISOString() });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}, PID: ${process.pid}`);
});

Конфигурация PM2 через ecosystem файл

Создаём ecosystem.config.js для управления конфигурацией:

module.exports = {
  apps: [{
    name: 'myapp',
    script: 'app.js',
    instances: 'max', // или конкретное число
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    env_production: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    // Настройки логов
    log_file: './logs/combined.log',
    out_file: './logs/out.log',
    error_file: './logs/error.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
    
    // Мониторинг и перезапуск
    watch: false,
    ignore_watch: ['node_modules', 'logs'],
    max_memory_restart: '1G',
    
    // Опции для кластера
    kill_timeout: 3000,
    wait_ready: true,
    listen_timeout: 3000,
    
    // Автоматический перезапуск
    autorestart: true,
    max_restarts: 10,
    min_uptime: '10s'
  }]
};

Создаём директорию для логов и запускаем приложение:

mkdir logs
pm2 start ecosystem.config.js --env production
pm2 status
pm2 logs

Настройка nginx как reverse proxy

Устанавливаем nginx для проксирования запросов:

sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

Создаём конфигурацию nginx (/etc/nginx/sites-available/myapp):

upstream myapp {
    server 127.0.0.1:3000;
    # Добавить больше серверов для балансировки
    # server 127.0.0.1:3001;
    # server 127.0.0.1:3002;
}

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    
    # Безопасность
    server_tokens off;
    client_max_body_size 10M;
    
    # Логи
    access_log /var/log/nginx/myapp_access.log;
    error_log /var/log/nginx/myapp_error.log;
    
    # Gzip сжатие
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    
    location / {
        proxy_pass http://myapp;
        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;
        proxy_cache_bypass $http_upgrade;
        
        # Таймауты
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
    
    # Статические файлы (если есть)
    location /static/ {
        alias /home/user/myapp/public/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Health check
    location /health {
        proxy_pass http://myapp/health;
        access_log off;
    }
}

Активируем конфигурацию:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

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

Настраиваем автозапуск PM2 через systemd:

pm2 startup
# Выполнить команду, которую выведет PM2
pm2 save

Проверяем, что всё работает:

sudo systemctl status pm2-user
sudo reboot
# После перезагрузки:
pm2 status

Мониторинг и управление процессами

PM2 предоставляет богатые возможности мониторинга:

# Статус всех процессов
pm2 status

# Подробная информация
pm2 show myapp

# Мониторинг в реальном времени
pm2 monit

# Управление процессами
pm2 restart myapp
pm2 reload myapp  # Zero downtime restart
pm2 stop myapp
pm2 delete myapp

# Управление логами
pm2 logs
pm2 logs myapp --lines 100
pm2 flush  # Очистить логи

Настройка логирования и ротации

Устанавливаем модуль для ротации логов:

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:dateFormat YYYY-MM-DD_HH-mm-ss

Также можно использовать системную ротацию через logrotate:

sudo nano /etc/logrotate.d/pm2
/home/user/.pm2/logs/*.log {
    daily
    missingok
    rotate 52
    compress
    notifempty
    create 644 user user
    postrotate
        pm2 reloadLogs
    endscript
}

Настройка SSL с Let’s Encrypt

Для продакшена обязательно нужен SSL:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
sudo systemctl status certbot.timer

Сравнение PM2 с альтернативами

Решение Кластеризация Мониторинг Zero Downtime Сложность
PM2 ✅ Встроенная ✅ Богатая ✅ Да Низкая
systemd ❌ Нет ⚠️ Базовая ❌ Нет Средняя
Docker + Docker Compose ✅ Да ✅ Хорошая ✅ Да Высокая
Kubernetes ✅ Отличная ✅ Отличная ✅ Да Очень высокая

Продвинутые возможности и автоматизация

PM2 открывает интересные возможности для автоматизации:

Graceful shutdown для корректного завершения соединений:

// В app.js
process.on('SIGINT', () => {
    console.log('Received SIGINT, shutting down gracefully');
    server.close(() => {
        console.log('Process terminated');
        process.exit(0);
    });
});

Webhooks для автоматического деплоя:

#!/bin/bash
# deploy.sh
cd /home/user/myapp
git pull origin main
npm install --production
pm2 reload myapp

Интеграция с системами мониторинга. PM2 может отправлять метрики в различные системы:

pm2 install pm2-server-monit
# Или интеграция с Prometheus
pm2 install pm2-prometheus-exporter

Оптимизация производительности

Несколько важных настроек для максимальной производительности:

# Увеличиваем лимиты файловых дескрипторов
echo "* soft nofile 65535" | sudo tee -a /etc/security/limits.conf
echo "* hard nofile 65535" | sudo tee -a /etc/security/limits.conf

# Оптимизация TCP
echo "net.core.somaxconn = 65535" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog = 65535" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Настройка кластера с учётом ресурсов:

# Для 4-core сервера оставляем 1 ядро для системы
instances: 3,
exec_mode: 'cluster',
instance_var: 'INSTANCE_ID'

Troubleshooting и типичные проблемы

Проблема: Приложение не запускается после перезагрузки

Решение: Проверить статус PM2 startup script:

pm2 unstartup
pm2 startup
pm2 save

Проблема: Высокое потребление памяти

Решение: Настроить автоматический перезапуск при превышении лимита:

max_memory_restart: '500M'

Проблема: Логи занимают много места

Решение: Настроить ротацию и использовать structured logging:

npm install winston
// Использовать winston вместо console.log

Интересные факты и нестандартные применения

PM2 можно использовать не только для Node.js! Он поддерживает запуск любых скриптов:

pm2 start python_script.py --interpreter python3
pm2 start "php -S localhost:8000" --name php-server
pm2 start npm --name "webpack-dev" -- run dev

PM2 Plus (платформа мониторинга) предоставляет real-time мониторинг через веб-интерфейс. Хотя базовые возможности платные, есть бесплатный tier для небольших проектов.

Можно использовать PM2 для создания микросервисной архитектуры на одном сервере:

pm2 start api-service.js --name api
pm2 start auth-service.js --name auth
pm2 start notification-service.js --name notifications

Автоматизация и CI/CD интеграция

PM2 отлично интегрируется с системами CI/CD. Пример GitHub Actions для автоматического деплоя:

# .github/workflows/deploy.yml
name: Deploy to Production
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Deploy to server
      uses: appleboy/ssh-action@v0.1.2
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd /home/user/myapp
          git pull origin main
          npm install --production
          pm2 reload myapp

Заключение и рекомендации

PM2 — это надёжное решение для продакшена Node.js приложений, которое решает основные проблемы стабильности и масштабируемости. Основные преимущества:

  • Простота настройки — можно поднять production-ready окружение за час
  • Автоматическое восстановление — приложение перезапускается при сбоях
  • Кластеризация из коробки — используем все ядра процессора
  • Богатые возможности мониторинга — видим что происходит с приложением
  • Zero downtime deployment — обновляем без остановки сервиса

Когда использовать PM2:

  • Средние и крупные Node.js приложения
  • Когда нужна высокая доступность
  • Для команд, которые хотят быстро настроить продакшен

Когда рассмотреть альтернативы:

  • Микросервисная архитектура — лучше подойдёт Docker/Kubernetes
  • Очень простые приложения — достаточно systemd
  • Когда нужна кроссплатформенность — рассмотрите контейнеризацию

PM2 отлично подходит для большинства случаев использования Node.js в продакшене. Комбинация PM2 + nginx + качественный VPS создаёт надёжную основу для веб-приложений любого масштаба.


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked