- Home »

Как настроить продакшен окружение 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 создаёт надёжную основу для веб-приложений любого масштаба.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.