Як встановити 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 — це поточна стабільна гілка. Вона містить значні покращення веб-панелі (pm2 plus), ротації журналів та системи модулів порівняно з v4.
Крок 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 МБ 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 МБ, зберігає 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/uk/vps/) | Економічно вигідно, повний root-доступ, масштабованість |
|---|
| Високонавантажені API | [Виділені сервери](https://alexhost.com/uk/dedicated-servers/) | Передбачувана продуктивність, відсутність конкуренції за ресурси |
|---|
| ML-інференс + Node.js | [GPU Хостинг](https://alexhost.com/uk/gpu-hosting/) | Перенесення обчислювально інтенсивних завдань на GPU-воркери |
|---|
| Керована панель управління | [VPS з cPanel](https://alexhost.com/uk/vps/control-panels/cpanel-vps/) | Керування процесами та файлами через GUI |
|---|
Контрольний список технічних рішень
Використовуйте цей контрольний список перед розгортанням 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 є справжньою вимогою.
