В статье — подробная инструкция по установке Node.js на Ubuntu 24.04: от выбора версии до production-настроек. Рассмотрели создание изолированного пользователя, systemd-юнит для автозапуска, сетевые настройки, мониторинг и журналирование.
Введение
Node.js — среда выполнения JavaScript, ставшая фундаментом для миллионов современных веб-приложений, от динамических бэкендов до инструментов сборки фронтенда. Если вы разрабатываете или планируете развернуть такое приложение на сервере под управлением Ubuntu 24.04, то эта статья поможет вам правильно установить и настроить Node.js.
Подготовка системы
Обновление пакетов:
sudo apt update && sudo apt upgrade -y
Установка базовых утилит:
sudo apt install -y ca-certificates curl gnupg
Пакет ca-certificates содержит корневые сертификаты доверенных центров сертификации — без него сервер не сможет проверить подлинность удаленных серверов (например, репозиториев NodeSource, сайтов для скачивания скриптов). curl — утилита командной строки для передачи данных по сетевым протоколам (HTTP, HTTPS, FTP и др.). gnupg (GNU Privacy Guard) — реализация стандарта OpenPGP, необходимая для работы с криптографическими ключами.
Базовая настройка файрвола (ufw):
sudo ufw allow ssh # Разрешаем входящие подключения по SSH (порт 22/TCP по умолчанию)
sudo ufw enable # Активируем файрвол и применяем правила
Node.js-приложение будет слушать на определённом порту (например, 3000, 8080). На этапе подготовки системы открывать этот порт в файрволе не нужно — это небезопасно! Добавляйте соответствующее правило (sudo ufw allow <порт>/tcp) только после того, как приложение будет установлено, настроено и запущено как сервис.
Установите пакет unattended-upgrades, который автоматизирует обновления безопасности — он периодически (по расписанию) проверяет репозитории, загружает и устанавливает только обновления, помеченные как относящиеся к безопасности:
sudo apt install unattended-upgrades -y
После установки нужно отредактировать конфигурационные файлы (в основном /etc/apt/apt.conf.d/50unattended-upgrades), чтобы убедиться, что нужные репозитории (особенно security и updates для Ubuntu, а позже и добавленный нами репозиторий NodeSource) включены для автоматического обновления. Впоследствии можно также настроить автоматическую перезагрузку (если это приемлемо для вашего сервиса):
sudo dpkg-reconfigure unattended-upgrades
Детальная настройка unattended-upgrades — это отдельная обширная тема. Мы советуем ознакомиться с официальной документацией Ubuntu и настроить unattended-upgrades под вашу задачу как можно скорее после базовой настройки сервера.
Установка Node.js LTS

Хотя Ubuntu 24.04 включает Node.js в свои стандартные репозитории, лучше установить пакет из официального репозитория NodeSource — и обязательно версию с долгосрочной поддержкой.
Репозитории дистрибутивов Linux фокусируются на стабильности экосистемы в целом, поэтому версии пакетов могут значительно отставать от актуальных релизов. NodeSource специализируется исключительно на Node.js — их репозитории обновляются в течение 24 часов после официального релиза новых версий. Также в NodeSource четко обозначены LTS-ветки (например, node_20.x), что позволяет легко устанавливать и поддерживать именно эти версии. Текущие (Current) версии Node.js (с новейшими функциями) имеют короткий срок поддержки — всего 6 месяцев, в то время как LTS-релизы получают обновления безопасности и исправления критических ошибок в течение 30 месяцев. Для production-среды длительная поддержка — это обязательное требование.
Импорт GPG-ключа репозитория:
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
Ключ будет сохранён в /etc/apt/keyrings/ — это современный, безопасный каталог для ключей APT (альтернатива устаревшему /etc/apt/trusted.gpg.d/).
Создание файла источника APT:
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
В этой команде — URL репозитория для Node.js 20.x LTS. Если нужна другая LTS (например, 22.x), замените 20 на актуальный мажорный номер. Всегда используйте HTTPS.
Обновление локального кеша пакетов, чтобы APT загрузил метаданные из всех репозиториев, включая только что добавленный NodeSource:
sudo apt update
Установка Node.js и npm:
sudo apt install -y nodejs
Пакет nodejs из репозитория NodeSource включает в себя:
- саму среду выполнения Node.js (node);
- менеджер пакетов npm;
- основные системные зависимости.
Проверка установки:
node -v # Проверяет версию Node.js
npm -v # Версия npm
Тестирование работоспособности
Теперь, когда Node.js установлен, перейдём к проверке работоспособности среды. Начнём с создания минимального JavaScript-файла для демонстрации выполнения кода. Откройте терминал и выполните:
echo "console.log('Node.js успешно работает на Ubuntu 24.04!');" > hello.js
Эта команда создаёт в текущей директории небольшой файл hello.js (только одна строка кода).
Для запуска скрипта выполните:
node hello.js
Вы должны увидеть в терминале текст:
Node.js успешно работает на Ubuntu 24.04!
Это подтверждает, что система корректно распознаёт команду node, среда выполнения способна интерпретировать JavaScript-код, базовые механизмы ввода-вывода функционируют без ошибок, а пути установки настроены правильно.
Поскольку реальные проекты редко существуют без внешних зависимостей, перейдём к проверке npm. Создайте изолированную директорию для эксперимента:
mkdir test-project && cd test-project
Инициализируйте новый проект командой:
npm init -y
Ключ -y автоматически принимает значения по умолчанию, генерируя файл package.json — основной элемент любого Node.js-проекта. Этот файл хранит метаданные (имя, версию, описание), фиксирует зависимости и определяет пользовательские скрипты. Чтобы просмотреть структуру файла, откройте его командой:
cat package.json
Теперь установим веб-фреймворк Express как пример зависимости:
npm install express
npm обратится к центральному реестру пакетов, скачает последнюю стабильную версию Express со всеми её зависимостями и разместит их в директории test-project/node_modules/. Одновременно автоматически обновится package.json — в раздел «dependencies» добавится запись об Express, а также создастся или обновится файл package-lock.json, который фиксирует точные версии всех установленных пакетов. Такая локальная установка обеспечивает изоляцию зависимостей между проектами и предотвращает конфликты версий.
Пакеты можно устанавливать и глобально — с флагом -g (например, npm install -g some-package). Но глобальная установка создаёт несколько проблем: разные проекты могут требовать конфликтующие версии инструментов; зависимости не фиксируются в package.json, нарушая воспроизводимость окружения; глобальная установка часто требует sudo, что рискованно для безопасности; при переносе проекта информация о необходимости глобального пакета теряется.
Настройка продакшен-окружения
Запуск приложения от имени root-пользователя небезопасен. Создайте под эту задачу выделенного системного пользователя с минимально необходимыми правами:
sudo adduser --system --group appuser
Флаг --system создаёт пользователя без домашней директории и с заблокированным входом в систему, что важно для сервисных аккаунтов. Параметр --group одновременно создаёт группу с тем же именем и автоматически назначает в неё пользователя. Такой подход изолирует приложение от системных процессов и других сервисов.
Приложение должно располагаться в защищённой директории вне пользовательских каталогов. Оптимальные варианты:
- /opt/myapp для самостоятельных приложений;
- /srv/myapp для сервисов, обслуживающих данные;
- /var/lib/myapp для приложений с изменяемыми данными.
Создайте директорию:
sudo mkdir -p /opt/myapp
Затем назначьте владельца:
sudo chown -R appuser:appuser /opt/myapp
-R гарантирует, что все вложенные файлы и директории унаследуют права родительского каталога. Это обеспечивает приложению доступ к собственным файлам, но блокирует модификацию системных ресурсов.
Перед настройкой сервиса разместите код приложения в рабочей директории. Основные методы:
scp -r ./local-app user@server:/opt/myapp # для безопасного копирования по SSH
rsync -avz -e ssh ./local-app/ user@server:/opt/myapp/ # для синхронизации
sudo -u appuser git clone https://repo.url /opt/myapp # прямое клонирование репозитория
После передачи файлов перепроверьте права доступа:
ls -l /opt/myapp
Ручной запуск приложения через node index.js неприменим в продакшене, поэтому настроим systemd. Это обеспечит:
- автоматический запуск при загрузке системы;
- мониторинг состояния процесса в реальном времени;
- автоматический рестарт после сбоев;
- централизованное управление журналами через journald;
- контроль ресурсов (память, CPU, файловые дескрипторы).
Создайте файл конфигурации сервисного юнита:
sudo nano /etc/systemd/system/myapp.service
Его содержимое (замените пути на актуальные):
[Unit]
Description=My Node.js Production Application
After=network.target # Запускать после активации сети
[Service]
User=appuser # Непривилегированный пользователь
Group=appuser # Группа приложения
WorkingDirectory=/opt/myapp # Контекст выполнения
# Критически важная переменная среды
Environment=NODE_ENV=production
# Дополнительные переменные
Environment=PORT=3000
# Путь к Node.js и точке входа
ExecStart=/usr/bin/node /opt/myapp/index.js
# Стратегия восстановления после сбоев
Restart=always # Рестарт при любом завершении
RestartSec=10 # Пауза перед рестартом (в секундах)
# Интеграция с системным журналом
StandardOutput=syslog # Перенаправление stdout
StandardError=syslog # Перенаправление stderr
SyslogIdentifier=myapp # Идентификатор в журналах
# Ограничение ресурсов (опционально)
# LimitNOFILE=65535 # Максимум открытых файлов
# LimitNPROC=4096 # Максимум процессов
[Install]
WantedBy=multi-user.target # Уровень запуска
Здесь:
- User и Group гарантируют выполнение процесса с минимальными привилегиями в изолированном контексте.
- WorkingDirectory устанавливает корневую директорию для относительных путей и операций с файлами.
- Environment=NODE_ENV=production активирует продакшен-режим в фреймворках (кеширование шаблонов, оптимизации, подавление отладочной информации).
- ExecStart требует абсолютных путей к исполняемому файлу Node.js (проверьте путь через which node) и точке входа приложения.
- Restart=always с RestartSec=10 обеспечивает автоматическое восстановление работы после любых сбоев с 10-секундной паузой (для устранения временных проблем).
- SyslogIdentifier позволяет фильтровать журналы конкретного приложения в общем системном потоке.
- LimitNOFILE и LimitNPROC предотвращают исчерпание системных ресурсов одним процессом.
После создания конфигурации выполните:
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
Эти команды перезагружают конфигурацию systemd после изменений, активируют автозапуск при загрузке системы и немедленно запускают сервис.
Проверьте статус:
sudo systemctl status myapp
В выводе обращайте внимание на:
- строку Active: active (running), подтверждающую работу;
- PID процесса;
- время работы (uptime);
- последние записи журнала (особенно при статусе failed).
Для просмотра логов в реальном времени используйте:
sudo journalctl -u myapp -f
Команда выводит все сообщения стандартного вывода и ошибок с фильтрацией по имени сервиса (-u myapp). Ключ -f активирует режим отображения в реальном времени (аналог tail -f). Для поиска ошибок используйте:
sudo journalctl -u myapp -p err -b
Завершение настройки: сеть, мониторинг и логирование
До этого момента файрвол разрешал только SSH-доступ (порт 22). Теперь, когда приложение работает и готово принимать подключения, откроем и его порт:
sudo ufw allow 3000/tcp # Замените 3000 на порт приложения
Всегда явно указывайте протокол (/tcp или /udp) — большинство Node.js-приложений используют TCP. Для HTTP-сервисов открывайте порт только после настройки обратного прокси (Nginx/Apache), который добавит SSL/TLS-шифрование и защиту от прямого доступа.
Проверьте статус правил:
sudo ufw status numbered
Должны отображаться разрешения для SSH и вашего порта.
После открытия порта убедитесь, что приложение действительно принимает подключения:
sudo netstat -tulpn | grep :3000 # Проверка активных слушающих портов
В выводе:
- состояние LISTEN подтверждает, что приложение прослушивает порт;
- поле PID/Program name должно соответствовать PID вашего systemd-сервиса;
- адрес 0.0.0.0 означает прослушивание на всех интерфейсах; для внутренних сервисов лучше использовать 127.0.0.1.
Установите и используйте утилиту для мониторинга ресурсов, например htop:
sudo apt install htop -y && htop
В htop обращайте внимание на:
- процесс Node.js в списке (фильтрация: F4 → node);
- потребление памяти (колонка RES);
- нагрузку на CPU — длительная 100 % загрузка ядра указывает на проблему;
- количество потоков (LWP) — необычно высокие значения могут сигнализировать об ошибках.
Внедрите профессиональное логирование: хотя systemd журналирует stdout/stderr, для продакшен-приложений этого недостаточно — например, установите Pino, Winston или Bunyan. Специализированные логгеры сохраняют данные в машиночитаемом JSON-формате, что позволяет автоматизировать анализ и интеграцию с системами мониторинга, поддерживают уровни логирования (Debug, Info, Warn, Error), ротацию логов и транспорт данных (например, в Syslog, Elasticsearch или облачные сервисы).
Важно:
- Всегда устанавливайте NODE_ENV=production — это отключает отладочные логи в фреймворках.
- Избегайте логирования конфиденциальных данных (пароли, токены, PII).
- Настройте ротацию логов через logrotate для предотвращения заполнения диска.
- Для распределённых систем рассмотрите централизованное хранение логов (Loki, ELK).
Читайте в блоге:
- Лучшие инструменты мониторинга сервера на Ubuntu 24.04: Netdata, Glances, htop
- Как настроить автоматические обновления безопасности в Ubuntu 24.04 с помощью unattended-upgrades
- Автоматическая настройка VPS-сервера на Ubuntu 24.04 с помощью Cloud-init