- Home »

Как настроить Node.js приложение для продакшена на Ubuntu 24
Многие думают, что деплой Node.js приложения — это просто npm start
на сервере. Но когда дело доходит до продакшена, все становится куда сложнее. Нужно правильно настроить процесс-менеджер, обеспечить стабильность, безопасность и производительность. Ubuntu 24 со своими последними обновлениями дает отличные возможности для хостинга Node.js приложений, но требует грамотной настройки.
В этой статье разберем весь процесс от установки до мониторинга. Покажу проверенные схемы, которые использую сам, и поделюсь граблями, на которые не стоит наступать. Если вы ищете быстрые решения для настройки продакшен-среды — вы по адресу.
🔧 Подготовка системы и установка Node.js
Первым делом нужно подготовить свежую Ubuntu 24. Если у вас еще нет сервера, рекомендую взять VPS или выделенный сервер с достаточными ресурсами.
Обновляем систему и устанавливаем базовые пакеты:
sudo apt update && sudo apt upgrade -y
sudo apt install curl wget gnupg2 software-properties-common -y
Для установки Node.js есть несколько способов. Я рекомендую использовать NodeSource репозиторий для стабильных версий:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install nodejs -y
node --version
npm --version
Альтернативный способ — через snap (но он медленнее):
sudo snap install node --classic
⚙️ Настройка приложения и структуры проекта
Создаем пользователя для приложения (никогда не запускайте под root!):
sudo adduser --system --group --home /var/www/myapp myapp
sudo mkdir -p /var/www/myapp
sudo chown -R myapp:myapp /var/www/myapp
Переключаемся на пользователя и клонируем проект:
sudo -u myapp -i
cd /var/www/myapp
git clone https://github.com/yourproject/app.git .
npm install --production
Создаем файл конфигурации окружения:
# .env
NODE_ENV=production
PORT=3000
DB_HOST=localhost
DB_PORT=5432
# остальные переменные
🚀 PM2 — ваш лучший друг в продакшене
PM2 — это де-факто стандарт для управления Node.js процессами в продакшене. Устанавливаем глобально:
sudo npm install pm2 -g
Создаем конфигурационный файл ecosystem.config.js
:
module.exports = {
apps: [{
name: 'myapp',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: 3000
},
error_file: './logs/err.log',
out_file: './logs/out.log',
log_file: './logs/combined.log',
time: true,
max_memory_restart: '1G',
node_args: '--max-old-space-size=1024'
}]
};
Запускаем приложение:
mkdir logs
pm2 start ecosystem.config.js
pm2 save
pm2 startup
🔄 Настройка автозапуска и мониторинга
PM2 отлично интегрируется с systemd в Ubuntu 24. После выполнения pm2 startup
система выдаст команду, которую нужно выполнить от root:
# Примерная команда (будет отличаться)
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u myapp --hp /var/www/myapp
Теперь можно управлять сервисом через systemctl:
sudo systemctl status pm2-myapp
sudo systemctl restart pm2-myapp
🌐 Nginx как reverse proxy
Устанавливаем и настраиваем Nginx:
sudo apt install nginx -y
sudo systemctl enable nginx
Создаем конфигурацию для сайта:
# /etc/nginx/sites-available/myapp
server {
listen 80;
server_name yourdomain.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_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_read_timeout 86400;
}
}
Активируем конфигурацию:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
🔐 SSL и безопасность
Устанавливаем Certbot для Let’s Encrypt:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
Настраиваем автообновление сертификатов:
sudo crontab -e
# Добавляем строку:
0 12 * * * /usr/bin/certbot renew --quiet
📊 Сравнение процесс-менеджеров
Менеджер | Кластеризация | Мониторинг | Автозапуск | Сложность |
---|---|---|---|---|
PM2 | ✅ Встроенная | ✅ Веб-интерфейс | ✅ Простая | Низкая |
Forever | ❌ Нет | ⚠️ Базовый | ⚠️ Требует настройки | Низкая |
Systemd | ❌ Нет | ⚠️ Через journald | ✅ Отличная | Средняя |
Docker | ✅ Orchestration | ✅ Множество решений | ✅ Отличная | Высокая |
🐛 Отладка и логирование
Настраиваем ротацию логов PM2:
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 30
pm2 set pm2-logrotate:compress true
Для централизованного логирования можно использовать winston:
npm install winston winston-daily-rotate-file
Полезные команды для диагностики:
pm2 logs --lines 200
pm2 monit
pm2 show myapp
pm2 restart myapp --update-env
🔍 Мониторинг и метрики
PM2 Plus (бывший Keymetrics) предоставляет отличный веб-интерфейс для мониторинга:
pm2 link your_secret_key your_public_key
Альтернативы для мониторинга:
- PM2 Health — простая проверка здоровья
- PM2 Server Monit — системный мониторинг
- Prometheus + Grafana — для серьезных проектов
⚡ Оптимизация производительности
Настраиваем кеширование в Nginx:
# Добавляем в server block
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
location ~* \.(html)$ {
expires 1h;
add_header Cache-Control "public";
}
Включаем gzip компрессию:
# /etc/nginx/nginx.conf
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
🔥 Практические кейсы и грабли
Кейс 1: Высокая нагрузка
При росте нагрузки увеличиваем количество воркеров в PM2:
pm2 scale myapp +2
Кейс 2: Memory leak
Настраиваем автоматический рестарт при превышении лимита памяти:
max_memory_restart: '500M'
Грабли которых стоит избегать:
- Запуск под root пользователем
- Отсутствие ограничений памяти
- Игнорирование логов ошибок
- Неправильная настройка proxy headers
- Отсутствие health checks
🛠️ Автоматизация деплоя
Создаем простой скрипт для деплоя:
#!/bin/bash
# deploy.sh
cd /var/www/myapp
git pull origin main
npm install --production
pm2 restart myapp
Для более сложных проектов рекомендую использовать:
- Shipit — простой деплой
- Capistrano — для Ruby, но работает с Node.js
- GitHub Actions или GitLab CI для CI/CD
🔧 Альтернативные решения
Docker подход:
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Systemd сервис (минималистский подход):
# /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js App
After=network.target
[Service]
Type=simple
User=myapp
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node app.js
Restart=always
RestartSec=10
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
📈 Интересные факты и статистика
По статистике Stack Overflow Survey 2024, Node.js остается одной из самых популярных серверных технологий. PM2 используется в 67% Node.js проектов в продакшене.
Интересные возможности Ubuntu 24:
- Улучшенная производительность systemd
- Новые возможности для контейнеризации
- Лучшая поддержка ARM архитектуры
- Обновленные пакеты безопасности
🎯 Заключение и рекомендации
Настройка Node.js приложения в продакшене — это не только технические аспекты, но и понимание принципов надежности и масштабируемости. PM2 остается золотым стандартом для большинства проектов, но не стоит забывать об альтернативах.
Мои рекомендации:
- Используйте PM2 для старта — он покроет 90% потребностей
- Обязательно настройте мониторинг и алерты
- Не экономьте на SSL — Let’s Encrypt бесплатный
- Настройте автоматическое резервное копирование
- Планируйте масштабирование заранее
Для небольших проектов хватит связки PM2 + Nginx на одном сервере. При росте нагрузки переходите на кластер серверов с балансировщиком нагрузки. Docker стоит рассматривать для сложных многосервисных архитектур.
Помните: лучший деплой — это тот, который работает стабильно и не требует постоянного вмешательства. Потратьте время на правильную настройку сейчас, и сэкономите кучу нервов в будущем.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.