PM2: как запускать Node.js-приложения в продакшене
Практика3 минРедакция Innovialabs
Коротко
PM2 держит Node.js-приложение запущенным, перезапускает его при падении, распределяет нагрузку по ядрам в cluster mode и поднимает процессы после перезагрузки сервера.
Коротко: зачем нужен PM2
Если запустить приложение командой node server.js, оно остановится при закрытии терминала, ошибке или перезагрузке сервера. PM2 — менеджер процессов для Node.js, который:
- держит приложение в фоне и перезапускает при падении;
- запускает несколько копий на разных ядрах CPU (cluster mode);
- перезагружает код без простоя;
- поднимает процессы после рестарта сервера;
- собирает логи и показывает потребление ресурсов.
Установка и первый запуск
npm install -g pm2
pm2 start server.js --name api
Основные команды:
| Команда | Что делает |
|---|---|
pm2 list | список процессов и их статус |
pm2 logs api | логи в реальном времени |
pm2 monit | CPU и память в терминале |
pm2 restart api | жесткий перезапуск |
pm2 reload api | перезапуск без простоя |
pm2 stop api / pm2 delete api | остановить / убрать из списка |
Ecosystem-файл вместо длинных команд
Настройки удобнее хранить в репозитории, в файле ecosystem.config.js:
module.exports = {
apps: [
{
name: "api",
script: "./dist/server.js",
instances: "max",
exec_mode: "cluster",
max_memory_restart: "500M",
env: {
NODE_ENV: "production",
PORT: 3000,
},
},
],
};
Запуск: pm2 start ecosystem.config.js. Так конфигурация одинакова на всех серверах и видна в истории Git. Секреты в этот файл не кладите — передавайте их через переменные окружения сервера или .env, который не попадает в репозиторий.
Cluster mode
Node.js выполняет JavaScript в одном потоке, то есть один процесс использует одно ядро. В cluster mode PM2 запускает несколько экземпляров и распределяет входящие соединения между ними. instances: "max" — по числу ядер.
Важные условия:
- приложение должно быть stateless: сессии, кэш и очереди — во внешнем хранилище (Redis, база), а не в памяти процесса;
- cron-задачи внутри приложения будут выполняться в каждом экземпляре — выносите их отдельно или запускайте только в одном;
- WebSocket в кластере требует внимания к sticky-сессиям или внешнему адаптеру.
Перезапуск без простоя
pm2 reload api перезапускает экземпляры по очереди: пока один перезагружается, остальные обслуживают запросы. Это работает в cluster mode. Чтобы reload был по-настоящему плавным:
- обрабатывайте сигнал
SIGINT— закрывайте сервер и соединения с базой корректно; - при необходимости используйте
wait_ready: trueиprocess.send("ready"), чтобы PM2 ждал фактической готовности приложения.
Автозапуск после перезагрузки сервера
pm2 startup
# выполните команду, которую выведет PM2
pm2 save
pm2 startup создает системную службу, а pm2 save запоминает текущий список процессов. Повторяйте pm2 save после добавления или удаления приложений.
Управление логами
По умолчанию логи пишутся в ~/.pm2/logs и сами не удаляются. Установите модуль ротации:
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 10
Иначе логи рано или поздно заполнят диск.
PM2 или Docker
| PM2 | Docker | |
|---|---|---|
| Порог входа | низкий | выше |
| Окружение | зависит от сервера | одинаковое везде |
| Несколько языков и сервисов | неудобно | естественно |
| Масштабирование на много серверов | вручную | через оркестратор |
| Подходит для | один сервер, небольшой проект | команды, микросервисы, CI/CD |
Если у вас один VPS и одно-два Node.js-приложения, PM2 — простой и надежный выбор. Если проект растет, есть несколько сервисов и нужна воспроизводимость окружения, переходите на Docker. Внутри контейнера PM2 обычно не нужен: перезапуском занимается сам Docker или оркестратор, а несколько копий запускаются как отдельные контейнеры.