15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать
09.10.2024

Как установить Node.js и PM2 на Ubuntu: полное руководство по производственной среде

Node.js — это асинхронная, событийно-ориентированная среда выполнения JavaScript, построенная на движке V8 от Chrome и предназначенная для выполнения JavaScript-кода на стороне сервера с высокой пропускной способностью. PM2 — это менеджер процессов производственного уровня для приложений Node.js, который обеспечивает демонизацию, автоматическое восстановление после сбоев, агрегацию логов, балансировку нагрузки в режиме кластера и генерацию скриптов запуска — всё через единый интерфейс CLI.

В этом руководстве рассматриваются все методы установки, параметры конфигурации и операционные шаблоны, необходимые для надёжного запуска приложений Node.js на Ubuntu 20.04, 22.04 или 24.04 LTS в производственной среде.

Предварительные требования

Перед началом убедитесь в следующем:

  • Операционная система: Ubuntu 20.04, 22.04 или 24.04 LTS (серверная или десктопная)
  • Привилегии пользователя: `sudo` или root-доступ
  • Сетевой доступ: Исходящий HTTPS для загрузки пакетов и скриптов
  • Установлен curl: Выполните `sudo apt install curl -y`, если он ещё не установлен

Если вы запускаете это на облачном сервере, среда VPS Хостинг является наиболее распространённой целью развёртывания для рабочих нагрузок Node.js, и всё описанное в этом руководстве применимо напрямую.

Шаг 1: Обновление системных пакетов

Всегда синхронизируйте индекс пакетов и применяйте ожидающие обновления перед установкой нового программного обеспечения. Устаревшие метаданные пакетов — частый источник конфликтов зависимостей.

“`bash

sudo apt update

sudo apt upgrade -y

“`

После завершения обновления перезагрузитесь, если было обновлено ядро:

“`bash

sudo reboot

“`

Шаг 2: Установка Node.js — выбор подходящего метода

Существует три основных метода установки Node.js на Ubuntu. Каждый из них имеет свои компромиссы с точки зрения управления версиями, изоляции и общесистемной доступности.

Сравнение методов

ФункцияNodeSource (apt)NVMСистемный apt (universe)
Управление версиямиОдна фиксированная мажорная версияНесколько версий на пользователяКак правило, устаревшая LTS
Общесистемная установкаДаНет (по умолчанию для каждого пользователя)Да
Переключение версийТребует повторного запуска скрипта настройки`nvm use <version>`Не поддерживается
Лучше всего подходит дляCI/CD, серверы с одной версиейРазработка, мультипроектные средыТолько быстрое тестирование
sudo требуется для глобальных npm-пакетовДаНетДа
Пригодность для продакшенаВысокаяСредняяНизкая

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

NodeSource поддерживает актуальные репозитории Debian/Ubuntu для каждой активной ветки выпуска Node.js. Это предпочтительный подход для производственных серверов, где требуется единая стабильная версия на уровне всей системы.

Добавьте репозиторий NodeSource для текущего LTS-релиза:

“`bash

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash –

“`

Этот скрипт выполняет несколько действий: определяет вашу версию Ubuntu, добавляет соответствующий apt-репозиторий NodeSource, импортирует GPG-ключ подписи и запускает `apt-get update`. Флаг `-E` сохраняет переменные окружения при повышении привилегий до sudo, что важно, если у вас настроены параметры прокси.

Установите Node.js и npm:

“`bash

sudo apt install nodejs -y

“`

Пакет NodeSource включает в себя как `node`, так и `npm` в едином пакете `nodejs`. В отличие от пакета Ubuntu universe, он не разделяет их.

Проверьте установку:

“`bash

node -v

npm -v

“`

Пример ожидаемого вывода:

“`

v20.14.0

10.7.0

“`

Фиксация на конкретной мажорной версии: Если вам нужен Node.js 18 вместо текущей LTS, замените `setup_lts.x` на `setup_18.x` в команде curl. Доступные ветки включают `setup_18.x`, `setup_20.x` и `setup_22.x`.

Метод 2: Установка Node.js через NVM (рекомендуется для разработки и сред с несколькими версиями)

NVM (Node Version Manager) устанавливает Node.js в ваш домашний каталог, не требуя привилегий root ни для самого Node.js, ни для глобально установленных npm-пакетов. Это устраняет проблемы с правами доступа, которые часто возникают при запуске `npm install -g` на системно установленном Node.js.

Установите NVM:

“`bash

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

“`

Перед выполнением этой команды проверьте официальный репозиторий NVM на наличие последнего тега релиза — номер версии в URL меняется с каждым выпуском.

Перезагрузите окружение оболочки:

“`bash

source ~/.bashrc

“`

Если вы используете Zsh, вместо этого подключите `~/.zshrc`. Установщик NVM добавляет свой блок инициализации в тот файл конфигурации оболочки, который он обнаружит.

Установите последнюю LTS-версию Node.js:

“`bash

nvm install –lts

“`

Установите конкретную версию наряду с LTS:

“`bash

nvm install 18

nvm install 20

“`

Переключайтесь между установленными версиями:

“`bash

nvm use 20

nvm alias default 20

“`

Команда `alias default` устанавливает версию, которая активируется в новых сеансах оболочки, что критически важно для скриптов и заданий cron, которые не подключают ваш интерактивный профиль оболочки.

Проверка:

“`bash

node -v

npm -v

“`

Критическая проблема NVM для продакшена: Поскольку NVM привязан к пользователю, скрипты запуска PM2 и юниты systemd не будут иметь доступа к бинарному файлу Node.js, управляемому NVM, если вы явно не настроите путь. Смотрите Шаг 5, чтобы узнать, как правильно это обработать.

Шаг 3: Установка PM2

PM2 распространяется как npm-пакет и должен быть установлен глобально, чтобы его CLI был доступен на уровне всей системы.

Установите PM2:

“`bash

sudo npm install -g pm2

“`

Если вы установили Node.js через NVM, опустите `sudo`:

“`bash

npm install -g pm2

“`

Проверьте установку:

“`bash

pm2 -v

“`

Установите конкретную версию PM2 (полезно при фиксации инфраструктуры):

“`bash

sudo npm install -g pm2@5.3.1

“`

PM2 версии 5.x — это текущая стабильная ветка. По сравнению с v4 в ней были внесены значительные улучшения в веб-панель управления (pm2 plus), ротацию логов и систему модулей.

Шаг 4: Управление приложениями Node.js с помощью PM2

Запуск приложения

Перейдите в каталог вашего приложения и запустите его:

“`bash

cd /var/www/my-app

pm2 start app.js –name "my-app"

“`

Всегда указывайте флаг `–name`. Без него PM2 использует имя файла в качестве имени процесса, что становится неоднозначным при наличии нескольких сервисов.

Запуск с дополнительными параметрами:

“`bash

pm2 start app.js –name "my-app" –watch –max-memory-restart 300M

“`

  • `–watch`: Перезапускает процесс при изменении исходных файлов (полезно на стейджинге, не рекомендуется в продакшене)
  • `–max-memory-restart 300M`: Автоматически перезапускает процесс, если он превышает 300 MB RSS-памяти — критическая защита от утечек памяти

Просмотр запущенных процессов

“`bash

pm2 list

“`

Выводит таблицу с идентификатором процесса, именем, режимом (fork/cluster), PID, статусом, использованием CPU, потреблением памяти и количеством перезапусков.

Для панели мониторинга в реальном времени:

“`bash

pm2 monit

“`

Управление процессами

“`bash

pm2 restart my-app # Graceful restart

pm2 reload my-app # Zero-downtime reload (cluster mode only)

pm2 stop my-app # Stop without removing from process list

pm2 delete my-app # Stop and remove from process list

“`

Разница между `restart` и `reload`: `restart` завершает процесс и запускает новый, вызывая кратковременный простой. `reload` (доступно только в режиме кластера) поочерёдно перезапускает воркеры, сохраняя доступность на протяжении всего процесса. Всегда используйте `reload` в продакшен-развёртываниях с кластером.

Управление логами

“`bash

pm2 logs # Stream logs from all processes

pm2 logs my-app # Stream logs for a specific process

pm2 logs my-app –lines 200 # Show last 200 lines

pm2 flush # Clear all log files

“`

По умолчанию PM2 хранит логи в `~/.pm2/logs/`. Для производственных серверов установите модуль ротации логов, чтобы предотвратить исчерпание дискового пространства:

“`bash

pm2 install pm2-logrotate

pm2 set pm2-logrotate:max_size 50M

pm2 set pm2-logrotate:retain 10

pm2 set pm2-logrotate:compress true

“`

Это выполняет ротацию логов при достижении 50 MB, сохраняет 10 сжатых архивов и предотвращает неконтролируемый рост логов — распространённая проблема на долго работающих серверах, которую часто замечают только тогда, когда заканчивается место на диске.

Шаг 5: Настройка автозапуска PM2 при загрузке системы

PM2 должен быть настроен на работу после перезагрузки сервера. Это обеспечивается через юнит systemd-сервиса, генерируемый самим PM2.

Сгенерируйте команду запуска:

“`bash

pm2 startup

“`

PM2 выведет команду, адаптированную к вашей системе инициализации и текущему пользователю. Она выглядит следующим образом:

“`

[PM2] Init System found: systemd

[PM2] To setup the Startup Script, copy/paste the following command:

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu –hp /home/ubuntu

“`

Скопируйте и выполните эту точную команду. Не изменяйте её — путь к бинарному файлу PM2 и домашний каталог должны соответствовать конфигурации вашей системы.

Настройка запуска для NVM: Если вы установили Node.js через NVM, путь в сгенерированной команде будет указывать на ваш бинарный файл, управляемый NVM. Это правильно, но вы должны убедиться, что версия NVM установлена как версия по умолчанию перед запуском `pm2 startup`:

“`bash

nvm alias default 20

pm2 startup

“`

Сохраните текущий список процессов:

“`bash

pm2 save

“`

Это записывает список процессов в `~/.pm2/dump.pm2`. При перезагрузке юнит systemd читает этот файл и восстанавливает все сохранённые процессы. Если вы впоследствии добавляете или удаляете приложения, снова запустите `pm2 save`, чтобы обновить снимок.

Убедитесь, что юнит systemd активен:

“`bash

systemctl status pm2-ubuntu

“`

Замените `ubuntu` на ваше фактическое имя пользователя.

Шаг 6: Производственное развёртывание с файлами экосистемы PM2

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

Генерация файла экосистемы

“`bash

pm2 ecosystem

“`

Это создаёт `ecosystem.config.js` в текущем каталоге.

Готовая к продакшену конфигурация экосистемы

“`javascript

module.exports = {

apps: [

{

name: 'api-server',

script: './src/server.js',

instances: 'max',

exec_mode: 'cluster',

watch: false,

max_memory_restart: '500M',

log_date_format: 'YYYY-MM-DD HH:mm:ss Z',

error_file: '/var/log/pm2/api-server-error.log',

out_file: '/var/log/pm2/api-server-out.log',

merge_logs: true,

env: {

NODE_ENV: 'development',

PORT: 3000

},

env_production: {

NODE_ENV: 'production',

PORT: 8080

}

},

{

name: 'worker',

script: './src/worker.js',

instances: 2,

exec_mode: 'fork',

cron_restart: '0 2 * * *',

env_production: {

NODE_ENV: 'production'

}

}

]

};

“`

Пояснение ключевых решений по конфигурации:

  • `instances: 'max'`: PM2 автоматически создаёт по одному воркеру на каждое логическое ядро CPU. На 4-ядерном сервере это создаёт 4 процесса Node.js, полностью используя возможности оборудования.
  • `exec_mode: 'cluster'`: Использует встроенный модуль кластера Node.js. Все экземпляры совместно используют один порт через балансировку нагрузки сокетов операционной системы.
  • `exec_mode: 'fork'`: Запускает процесс как отдельный дочерний процесс. Требуется для приложений, которые не являются HTTP-серверами (обработчики очередей, запланированные задания, WebSocket-серверы со sticky-сессиями).
  • `merge_logs: true`: Объединяет stdout всех экземпляров кластера в единый файл лога, что значительно упрощает анализ логов.
  • `cron_restart`: Планирует автоматические перезапуски с использованием синтаксиса cron. Полезно для воркеров, накапливающих состояние, или для применения ночных изменений конфигурации.

Запуск с файлом экосистемы

“`bash

pm2 start ecosystem.config.js –env production

pm2 save

“`

Рабочий процесс развёртывания без простоев

При развёртывании новой версии вашего приложения:

“`bash

git pull origin main

npm install –production

pm2 reload ecosystem.config.js –env production

“`

`pm2 reload` отправляет `SIGINT` каждому воркеру по одному, ожидает готовности нового воркера, затем завершает старый. Ваше приложение должно корректно обрабатывать `SIGINT` и сигнализировать о готовности с помощью `process.send('ready')`, чтобы это работало правильно.

Обработчик корректного завершения в вашем приложении:

“`javascript

process.on('SIGINT', () => {

server.close(() => {

console.log('HTTP server closed');

process.exit(0);

});

});

“`

Шаг 7: Мониторинг и наблюдаемость PM2

Встроенный мониторинг

“`bash

pm2 monit

“`

Отображает графики CPU и памяти в реальном времени для каждого процесса в терминале.

Информация о процессах

“`bash

pm2 show my-app

“`

Выводит подробные метаданные: время работы, количество перезапусков, версионирование, путь к интерпретатору, переменные окружения и расположение файлов логов.

Веб-панель PM2 (PM2 Plus)

PM2 предлагает размещённую панель мониторинга на pm2.io. Подключите ваш сервер:

“`bash

pm2 link <secret_key> <public_key>

“`

Это обеспечивает исторические метрики, оповещения и удалённое управление процессами — особенно ценно при управлении несколькими серверами или когда вам нужна видимость без SSH-доступа.

Шаг 8: Обновление Node.js и PM2

Обновление PM2

“`bash

sudo npm install -g pm2@latest

pm2 update

“`

`pm2 update` необходим после обновления бинарного файла PM2 — он обновляет работающий демон PM2 в памяти без прерывания запущенных процессов.

Обновление Node.js через NodeSource

Повторно запустите скрипт настройки для новой мажорной версии:

“`bash

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash –

sudo apt install nodejs -y

“`

После обновления Node.js перезапустите PM2, чтобы убедиться, что он использует новый бинарный файл:

“`bash

pm2 restart all

“`

Обновление Node.js через NVM

“`bash

nvm install 22

nvm alias default 22

nvm use 22

pm2 restart all

“`

Если вы изменили версию NVM по умолчанию, повторно сгенерируйте скрипт запуска PM2, чтобы обновить путь к бинарному файлу в юните systemd:

“`bash

pm2 unstartup

pm2 startup

pm2 save

“`

Соображения по усилению безопасности

Запуск приложений Node.js в продакшене требует внимания помимо управления процессами:

  • Запускайте от имени непривилегированного пользователя: Никогда не запускайте PM2 или Node.js от имени root. Создайте выделенного системного пользователя (`adduser –system –group nodeapp`) и запускайте PM2 под этой учётной записью.
  • Управление переменными окружения: Не вшивайте секреты в `ecosystem.config.js`. Используйте файл `.env`, загружаемый через `dotenv`, или передавайте секреты через ваш конвейер развёртывания. Файл экосистемы обычно фиксируется в системе контроля версий.
  • Обратный прокси: Разместите Nginx или Caddy перед вашим приложением Node.js. Это обеспечивает завершение TLS, раздачу статических файлов, ограничение частоты запросов и буферизацию запросов. Дополните это решением SSL Сертификаты для принудительного использования HTTPS.
  • Правила брандмауэра: Заблокируйте прямой доступ к порту Node.js (например, 3000, 8080) из публичного интернета. Только обратный прокси должен взаимодействовать с Node.js.
  • Ограничения ресурсов: Установите `max_memory_restart` в PM2 и настройте системные значения `ulimit`, чтобы предотвратить дестабилизацию сервера одним неуправляемым процессом.

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

Выбор подходящей среды хостинга для Node.js

Рабочая нагрузкаРекомендуемая средаОбоснование
Личные проекты, стейджинг[VPS Хостинг](https://alexhost.com/ru/vps/)Экономичность, полный root-доступ, масштабируемость
Высоконагруженные API[Выделенные серверы](https://alexhost.com/ru/dedicated-servers/)Предсказуемая производительность, отсутствие конкуренции за ресурсы
ML-инференс + Node.js[GPU Хостинг](https://alexhost.com/ru/gpu-hosting/)Перенос вычислительно интенсивных задач на GPU-воркеры
Управляемая панель управления[VPS с cPanel](https://alexhost.com/ru/vps/control-panels/cpanel-vps/)Управление процессами и файлами через графический интерфейс

Контрольный список технических решений

Используйте этот контрольный список перед развёртыванием Node.js и PM2 в продакшене:

  • [ ] Node.js установлен через NodeSource (сервер) или NVM (разработка) — не через пакет Ubuntu universe
  • [ ] PM2 установлен глобально с правильными разрешениями для вашего метода установки
  • [ ] Приложение запущено с флагом `–name` и определённым порогом `–max-memory-restart`
  • [ ] Режим кластера включён для HTTP-серверов; режим fork используется для фоновых воркеров
  • [ ] `pm2 startup` выполнен и сгенерированная команда запущена с sudo
  • [ ] `pm2 save` выполнен после настройки всех процессов
  • [ ] Модуль ротации логов установлен и настроен
  • [ ] Nginx или Caddy настроен как обратный прокси с TLS
  • [ ] Приложение корректно обрабатывает `SIGINT` для перезагрузок без простоев
  • [ ] Секреты управляются вне `ecosystem.config.js`
  • [ ] Юнит systemd PM2 проверен с помощью `systemctl status pm2-<username>`
  • [ ] Брандмауэр блокирует прямой доступ к портам Node.js из публичного интернета

Часто задаваемые вопросы

В чём разница между режимом fork и режимом кластера в PM2?

Режим fork запускает приложение как единственный дочерний процесс — один экземпляр, используется одно ядро CPU. Режим кластера использует нативный модуль кластера Node.js для создания нескольких рабочих процессов, которые совместно используют один TCP-порт, обеспечивая истинное использование нескольких ядер и перезагрузки без простоев. Используйте режим кластера для HTTP/HTTPS-серверов и режим fork для воркеров, заданий cron или приложений, поддерживающих внутреннее состояние, несовместимое с многопроцессным совместным использованием.

Почему PM2 не перезапускается после перезагрузки сервера, хотя я выполнил `pm2 startup`?

Наиболее распространённая причина — `pm2 save` не был выполнен после настройки процессов, поэтому файл дампа пуст или отсутствует. Вторая по распространённости причина — несоответствие пути NVM: если версия NVM по умолчанию была изменена после генерации скрипта запуска, юнит systemd указывает на несуществующий бинарный файл. Решите это, запустив `pm2 unstartup`, установив правильную версию NVM по умолчанию, затем повторно выполнив `pm2 startup` и `pm2 save`.

Может ли PM2 управлять процессами, не связанными с Node.js?

Да. PM2 может управлять любым исполняемым файлом, указав интерпретатор. Например: `pm2 start script.py –interpreter python3`. Это делает PM2 полезным в качестве универсального супервизора процессов для микросервисных архитектур со смешанными языками.

Как запустить несколько приложений Node.js на разных портах за одним сервером?

Определите каждое приложение как отдельную запись в `ecosystem.config.js` с отдельными переменными окружения `PORT`. Настройте Nginx как обратный прокси с отдельными блоками `server` или директивами `location`, маршрутизирующими к каждому порту. Все приложения совместно используют один демон PM2 и управляются через единое представление `pm2 list`.

Что лучше использовать для производственного VPS — NVM или NodeSource?

NodeSource, как правило, предпочтительнее для производственных серверов. Он устанавливает Node.js как системный пакет, делая его доступным для всех пользователей и системных сервисов без зависимостей от инициализации оболочки. Модель активации NVM для каждого пользователя и каждой оболочки создаёт тонкие сбои в юнитах systemd, заданиях cron и конвейерах CI/CD, которые выполняются вне интерактивного сеанса оболочки. Оставьте NVM для локальных машин разработки, где одновременное управление несколькими версиями Node.js является реальной необходимостью.

15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать