Nginx Unit — окремий сервер застосунків від розробників nginx: він запускає PHP, Python, Node.js та ще кілька мов з одного процесу керування, без окремих служб типу php-fpm чи pm2. Веб-сервер nginx при цьому не замінюється: Unit бере на себе виконання застосунку, а TLS і роздачу статики перед ним зазвичай усе одно налаштовують через nginx. Розглянемо, коли така зв'язка полегшує адміністрування, а коли звична схема з php-fpm чи pm2 лишається простішою.
Чим Unit відрізняється від php-fpm і pm2
Unit керується не текстовим конфігом з перезавантаженням за сигналом, а REST API над керуючим сокетом: застосунки, лістенери і маршрути описуються JSON-об'єктом і застосовуються PUT-запитом без зупинки процесу. Додавання нового застосунку або зміна кількості воркерів не вимагає редагування файлу конфігурації і команди reload, як у зв'язці з php-fpm.
Для Node.js різниця принципова: pm2 запускає звичайний процес Node.js і стежить за ним ззовні, а Unit вбудовується у застосунок через модуль unit-http, який підставляється замість стандартного http-модуля. Перенесення наявного Node-застосунку на Unit вимагає правки коду запуску, а не лише конфігурації сервера.
Встановлення і процеси Unit
Unit встановлюється як окремий пакет плюс мовні модулі — для PHP, Python, Node.js і так далі, зібрані під конкретну версію інтерпретатора. Основний процес unitd слухає керуючий сокет control.unit.sock і породжує процеси-роутери та окремі процеси застосунків, кількість яких задається у конфігурації кожного застосунку.
Роль nginx у цій схемі не змінюється: він лишається тим самим веб-сервером, що описаний у статті про архітектуру Nginx. Nginx слухає порт 80 або 443, роздає статику напряму і проксує динамічні запити на Unit через proxy_pass, як на будь-який інший upstream.
curl -X PUT --data-binary @app.json --unix-socket /var/run/control.unit.sock http://localhost/config/applications/myapp
{
"type": "php",
"root": "/var/www/myapp/public/",
"index": "index.php",
"processes": { "max": 4, "spare": 1 }
}
Застосунок у JSON-конфігурації
Кожен застосунок описується окремим об'єктом з типом, шляхом і кількістю процесів. Лістенер пов'язує мережевий порт або unix-сокет з назвою застосунку, тому на одному хості одночасно можуть працювати PHP-сайт, Python-сервіс і Node-бекенд, кожен зі своїми процесами і лімітами.
| Параметр | php-fpm + pm2 | Nginx Unit |
|---|---|---|
| Формат конфігурації | текстові файли ini і json окремо для кожної служби | один JSON-об'єкт через REST API |
| Застосування змін | reload або restart служби | PUT-запит без зупинки процесу |
| Запуск Node.js | звичайний процес, pm2 стежить ззовні | модуль unit-http усередині коду застосунку |
| Декілька мов на одному хості | окрема служба на кожну мову | один процес unitd для усіх мов |
Такий поділ зручний для хостингу кількох застосунків різними мовами на одній VDS: не треба тримати окремий systemd-юніт під кожну мову і синхронізувати їх перезапуск вручну.
Nginx перед Unit: проксі і статика
Unit слухає власний порт або unix-сокет, а nginx перед ним працює так само, як перед php-fpm чи будь-яким іншим backend: приймає з'єднання, роздає статичні файли напряму з файлової системи і проксує запити до динамічного контенту.
Базове налаштування server-блоку, TLS-сертифікатів і логів не змінюється і описане у статті про налаштування Nginx для сайту на VDS. Додатково у location для динамічних запитів вказується proxy_pass на лістенер Unit замість fastcgi_pass на php-fpm.
Що перевірити перед переходом
Перш ніж переносити робочий сайт на Unit, варто пройти короткий список перевірок — частина обмежень проявляється лише у продакшені, а не на тестовому стенді.
- Node.js-застосунок потребує правки коду запуску під unit-http — звичайний process.listen не запрацює з Unit без змін.
- Для PHP потрібен модуль unit-php, зібраний під встановлену версію PHP — невідповідність версії не дасть застосунку стартувати.
- Керуючий сокет control.unit.sock повинен бути доступний лише локально і закритий від зовнішнього доступу файрволом.
- Кількість процесів застосунку задається у конфігурації явно, а не визначається автоматично за навантаженням.
- Логи застосунку за умовчанням потрапляють у спільний лог Unit, а не в окремий файл на процес, як звично для pm2.
Часті питання
Чи можна прибрати nginx і лишити тільки Unit?
Технічно Unit уміє самостійно слухати порт і роздавати статичні файли, але для продакшен-сайту з TLS-сертифікатами і кількома доменами на одній VDS зазвичай простіше лишити nginx перед ним — так зручніше керувати сертифікатами і логами на одному рівні.
Що робити, якщо версія PHP на сервері не збігається з модулем Unit?
Unit дозволяє тримати кілька мовних модулів одночасно — наприклад php81 і php83 як окремі файли модулів, і кожен застосунок у конфігурації вказує потрібну версію. Модуль зібраний під конкретну версію PHP і не підходить для сусідньої мінорної версії без перезбирання.
Як перевірити, що застосунок у Unit запущений і відповідає?
Поточна конфігурація і статус читаються через той самий керуючий сокет: GET-запит до /config показує активні застосунки і лістенери, а /status — кількість процесів і опрацьованих запитів. Помилки запуску застосунку потрапляють у лог Unit.