Home » Ubuntu 24: Установка Node.js по лучшим практикам
Ubuntu 24: Установка Node.js по лучшим практикам

Ubuntu 24: Установка Node.js по лучшим практикам

Если вы разворачиваете Node.js приложения в продакшне или просто настраиваете dev-окружение на Ubuntu 24, то эта статья для вас. Установка Node.js может показаться тривиальной задачей, но правильный подход сэкономит вам массу времени и нервов в будущем. Я покажу не только как установить Node.js, но и как сделать это по всем правилам DevOps, чтобы ваши проекты работали стабильно и легко масштабировались.

Мы разберём несколько способов установки, от apt-пакетов до менеджеров версий, и я объясню, когда использовать каждый из них. Также рассмотрим настройку production-окружения, управление зависимостями и автоматизацию через systemd. В конце у вас будет полноценная настройка, готовая к боевому применению.

Почему важно правильно установить Node.js

Node.js в Ubuntu можно установить дюжиной способов, но большинство из них создают больше проблем, чем решают. Основные боли:

  • Конфликты версий — разные проекты требуют разные версии Node.js
  • Права доступа — глобальные пакеты npm часто требуют sudo
  • Обновления — штатные репозитории Ubuntu содержат древние версии
  • Зависимости — нативные модули могут не компилироваться

Правильная установка решает все эти проблемы и даёт вам гибкость в управлении окружением.

Способы установки Node.js: сравнение методов

Метод Плюсы Минусы Когда использовать
apt (Ubuntu repos) Простота, автообновления Устаревшие версии Никогда в продакшне
NodeSource репозиторий Актуальные версии, простота Одна версия на систему Простые проекты
nvm (Node Version Manager) Множество версий, гибкость Только для пользователя Development
fnm (Fast Node Manager) Быстрота, написан на Rust Меньше features Performance-критичные задачи
Snap пакеты Изоляция, безопасность Медленный запуск Sandbox окружения

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

NodeSource — это компания, которая поддерживает официальные репозитории Node.js для различных дистрибутивов Linux. Этот способ даёт вам актуальные версии без геморроя с менеджерами версий.


# Обновляем систему
sudo apt update && sudo apt upgrade -y

# Устанавливаем curl если его нет
sudo apt install -y curl

# Добавляем NodeSource репозиторий для Node.js 20.x
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -

# Устанавливаем Node.js
sudo apt install -y nodejs

# Проверяем установку
node --version
npm --version

Этот метод автоматически устанавливает npm и настраивает все зависимости. Если нужна другая версия, замените `20.x` на нужную (18.x, 19.x, 21.x).

Метод 2: NVM для разработки

Node Version Manager — это must-have для разработчиков. Позволяет быстро переключаться между версиями Node.js и тестировать совместимость.


# Устанавливаем nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# Перезагружаем bash profile
source ~/.bashrc

# Проверяем установку
nvm --version

# Устанавливаем последнюю LTS версию
nvm install --lts
nvm use --lts

# Устанавливаем конкретную версию
nvm install 18.17.0
nvm use 18.17.0

# Устанавливаем версию по умолчанию
nvm alias default 20.5.0

# Список установленных версий
nvm list

Практический кейс: У вас есть старый проект на Node.js 16 и новый на Node.js 20. С nvm переключение займёт секунды:


# Для старого проекта
cd /path/to/old-project
echo "16.20.0" > .nvmrc
nvm use

# Для нового проекта
cd /path/to/new-project
echo "20.5.0" > .nvmrc
nvm use

Метод 3: fnm — быстрая альтернатива nvm

fnm (Fast Node Manager) написан на Rust и работает значительно быстрее nvm. Особенно заметно на слабых серверах.


# Устанавливаем fnm
curl -fsSL https://fnm.vercel.app/install | bash

# Добавляем в shell
echo 'eval "$(fnm env --use-on-cd)"' >> ~/.bashrc
source ~/.bashrc

# Устанавливаем Node.js
fnm install 20.5.0
fnm use 20.5.0
fnm default 20.5.0

# Автоматическое переключение по .node-version
echo "20.5.0" > .node-version
# fnm автоматически переключится при входе в директорию

Настройка production-окружения

После установки Node.js нужно правильно настроить production-окружение. Это критично для стабильности и безопасности.

Создание пользователя для Node.js приложений


# Создаём системного пользователя
sudo useradd --system --create-home --shell /bin/bash nodeapp

# Переключаемся на этого пользователя
sudo su - nodeapp

# Устанавливаем nvm для пользователя nodeapp
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install --lts

Настройка npm для избежания sudo

Одна из самых частых проблем — необходимость sudo для глобальных пакетов npm. Решаем раз и навсегда:


# Создаём директорию для глобальных пакетов
mkdir ~/.npm-global

# Настраиваем npm
npm config set prefix '~/.npm-global'

# Добавляем в PATH
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

# Теперь можно устанавливать глобальные пакеты без sudo
npm install -g pm2
npm install -g nodemon

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

PM2 — это production process manager для Node.js. Обязателен для любого серьёзного проекта.


# Устанавливаем PM2
npm install -g pm2

# Запускаем приложение
pm2 start app.js --name "my-app"

# Автозапуск после перезагрузки
pm2 startup
pm2 save

# Мониторинг
pm2 monit

# Логи
pm2 logs

# Перезапуск при изменении файлов (для development)
pm2 start app.js --watch

# Cluster mode для использования всех CPU
pm2 start app.js -i max

Конфигурация PM2 через ecosystem.config.js


module.exports = {
apps: [{
name: 'my-app',
script: './app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 80
},
log_file: './logs/combined.log',
out_file: './logs/out.log',
error_file: './logs/error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z'
}]
};

Настройка системного сервиса

Для production-серверов лучше создать systemd сервис:


# Создаём сервис файл
sudo nano /etc/systemd/system/nodeapp.service


[Unit]
Description=Node.js App
After=network.target

[Service]
Type=simple
User=nodeapp
WorkingDirectory=/home/nodeapp/app
ExecStart=/home/nodeapp/.nvm/versions/node/v20.5.0/bin/node app.js
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=nodeapp
Environment=NODE_ENV=production
Environment=PORT=3000

[Install]
WantedBy=multi-user.target


# Активируем сервис
sudo systemctl daemon-reload
sudo systemctl enable nodeapp
sudo systemctl start nodeapp

# Проверяем статус
sudo systemctl status nodeapp

Оптимизация и безопасность

Настройка firewall


# Включаем ufw
sudo ufw enable

# Разрешаем SSH
sudo ufw allow ssh

# Разрешаем HTTP и HTTPS
sudo ufw allow 80
sudo ufw allow 443

# Проверяем статус
sudo ufw status

Настройка Nginx как reverse proxy


# Устанавливаем Nginx
sudo apt install -y nginx

# Создаём конфигурацию
sudo nano /etc/nginx/sites-available/nodeapp


server {
listen 80;
server_name your-domain.com;

location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}


# Активируем конфигурацию
sudo ln -s /etc/nginx/sites-available/nodeapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Мониторинг и логирование

Для production-окружения критично настроить мониторинг. Рассмотрим несколько инструментов:

Настройка Winston для логирования


npm install winston winston-daily-rotate-file

# app.js
const winston = require('winston');
require('winston-daily-rotate-file');

const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m',
maxFiles: '14d'
}),
new winston.transports.Console()
]
});

Автоматизация через скрипты

Создадим полезные скрипты для автоматизации рутинных задач:

Скрипт деплоя


#!/bin/bash
# deploy.sh

echo "Starting deployment..."

# Останавливаем приложение
pm2 stop my-app

# Обновляем код
git pull origin main

# Устанавливаем зависимости
npm install --production

# Запускаем приложение
pm2 start my-app

# Сохраняем конфигурацию PM2
pm2 save

echo "Deployment completed!"

Скрипт мониторинга


#!/bin/bash
# monitor.sh

# Проверяем статус приложения
if pm2 describe my-app | grep -q "online"; then
echo "App is running"
else
echo "App is down, restarting..."
pm2 restart my-app
fi

# Проверяем использование памяти
MEMORY_USAGE=$(ps aux | grep node | grep -v grep | awk '{sum+=$4} END {print sum}')
if (( $(echo "$MEMORY_USAGE > 80" | bc -l) )); then
echo "High memory usage: $MEMORY_USAGE%"
# Отправляем уведомление или перезапускаем
fi

Интеграция с Docker

Для современных проектов часто используется контейнеризация. Вот оптимальный Dockerfile:


FROM node:20-alpine

# Создаём пользователя
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodeapp -u 1001

# Устанавливаем зависимости
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Копируем код
COPY --chown=nodeapp:nodejs . .

USER nodeapp

EXPOSE 3000

CMD ["node", "app.js"]

Полезные утилиты и пакеты

Список must-have пакетов для Node.js разработки:

  • nodemon — автоперезапуск при изменениях
  • pm2 — production process manager
  • nvm/fnm — управление версиями Node.js
  • npm-check-updates — обновление зависимостей
  • clinic — профилирование производительности
  • jest — тестирование
  • eslint — линтинг кода
  • prettier — форматирование кода


# Устанавливаем полезные утилиты
npm install -g nodemon pm2 npm-check-updates clinic

# Для проекта
npm install --save-dev jest eslint prettier

Работа с SSL сертификатами

Для production-окружения необходимы SSL сертификаты. Используем Let’s Encrypt:


# Устанавливаем certbot
sudo apt install -y certbot python3-certbot-nginx

# Получаем сертификат
sudo certbot --nginx -d your-domain.com

# Автообновление
sudo crontab -e
# Добавляем строку:
0 12 * * * /usr/bin/certbot renew --quiet

Оптимизация производительности

Несколько трюков для улучшения производительности Node.js приложений:

Настройка Node.js флагов


# Увеличиваем heap memory
export NODE_OPTIONS="--max-old-space-size=4096"

# Оптимизируем сборщик мусора
export NODE_OPTIONS="--max-old-space-size=4096 --optimize-for-size"

# Для PM2
pm2 start app.js --node-args="--max-old-space-size=4096"

Кеширование с Redis


# Устанавливаем Redis
sudo apt install -y redis-server

# Настраиваем автозапуск
sudo systemctl enable redis-server

# В Node.js приложении
npm install redis

const redis = require('redis');
const client = redis.createClient();

// Простое кеширование
async function getCachedData(key) {
const cached = await client.get(key);
if (cached) return JSON.parse(cached);

const data = await fetchDataFromDB();
await client.setex(key, 3600, JSON.stringify(data));
return data;
}

Устранение типичных проблем

Рассмотрим самые частые проблемы и их решения:

Проблема: “Permission denied” при npm install


# Решение 1: Настройка npm prefix (рекомендуется)
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc

# Решение 2: Изменение владельца npm директорий
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

Проблема: Не компилируются нативные модули


# Устанавливаем build tools
sudo apt install -y build-essential python3-dev

# Для старых проектов может понадобиться Python 2
sudo apt install -y python2

# Указываем Python версию для npm
npm config set python python3

Проблема: Высокое потребление памяти


# Мониторинг памяти
pm2 monit

# Ограничиваем память для PM2
pm2 start app.js --max-memory-restart 1G

# Анализ утечек памяти
npm install -g clinic
clinic doctor -- node app.js

Интеграция с CI/CD

Пример GitHub Actions workflow для автоматического деплоя:


# .github/workflows/deploy.yml
name: Deploy to Server

on:
push:
branches: [ main ]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '20'

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test

- name: Deploy to server
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
script: |
cd /home/nodeapp/app
git pull origin main
npm install --production
pm2 restart my-app

Интересные факты и нестандартные применения

Node.js можно использовать не только для веб-приложений:

  • Системные скрипты — замена bash скриптов на JavaScript
  • Desktop приложения — с помощью Electron
  • IoT проекты — управление Raspberry Pi
  • Blockchain приложения — смарт-контракты и DApps
  • Machine Learning — TensorFlow.js

Пример системного скрипта на Node.js:


#!/usr/bin/env node

const fs = require('fs');
const { execSync } = require('child_process');

// Очистка старых логов
const logDir = '/var/log/myapp';
const files = fs.readdirSync(logDir);

files.forEach(file => {
const stats = fs.statSync(`${logDir}/${file}`);
const age = Date.now() - stats.mtime.getTime();

if (age > 7 * 24 * 60 * 60 * 1000) { // 7 дней
fs.unlinkSync(`${logDir}/${file}`);
console.log(`Deleted old log: ${file}`);
}
});

// Проверка дискового пространства
const diskUsage = execSync('df -h /').toString();
console.log('Disk usage:', diskUsage);

Автоматизация и скрипты

Node.js открывает огромные возможности для автоматизации. Несколько примеров:

Автоматический backup базы данных


const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

function backupDatabase() {
const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
const backupPath = `/backups/db_backup_${timestamp}.sql`;

try {
execSync(`mysqldump -u root -p${process.env.DB_PASSWORD} myapp > ${backupPath}`);
console.log(`Backup created: ${backupPath}`);

// Удаляем старые бэкапы
cleanOldBackups();
} catch (error) {
console.error('Backup failed:', error.message);
}
}

function cleanOldBackups() {
const backupDir = '/backups';
const files = fs.readdirSync(backupDir);

files.forEach(file => {
const filePath = path.join(backupDir, file);
const stats = fs.statSync(filePath);
const age = Date.now() - stats.mtime.getTime();

if (age > 30 * 24 * 60 * 60 * 1000) { // 30 дней
fs.unlinkSync(filePath);
console.log(`Deleted old backup: ${file}`);
}
});
}

// Запускаем каждый день в 2:00
setInterval(backupDatabase, 24 * 60 * 60 * 1000);

Мониторинг сервера с уведомлениями


const { execSync } = require('child_process');
const https = require('https');

function checkServerHealth() {
const checks = {
cpu: getCPUUsage(),
memory: getMemoryUsage(),
disk: getDiskUsage(),
services: checkServices(['nginx', 'mysql', 'redis'])
};

const alerts = [];

if (checks.cpu > 80) alerts.push(`High CPU usage: ${checks.cpu}%`);
if (checks.memory > 85) alerts.push(`High memory usage: ${checks.memory}%`);
if (checks.disk > 90) alerts.push(`Low disk space: ${checks.disk}%`);

if (alerts.length > 0) {
sendTelegramAlert(alerts.join('\n'));
}
}

function sendTelegramAlert(message) {
const token = process.env.TELEGRAM_BOT_TOKEN;
const chatId = process.env.TELEGRAM_CHAT_ID;

const data = JSON.stringify({
chat_id: chatId,
text: `🚨 Server Alert:\n${message}`
});

const options = {
hostname: 'api.telegram.org',
port: 443,
path: `/bot${token}/sendMessage`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
};

const req = https.request(options);
req.write(data);
req.end();
}

// Проверяем каждые 5 минут
setInterval(checkServerHealth, 5 * 60 * 1000);

Статистика и сравнения

Согласно Stack Overflow Developer Survey 2023:

  • Node.js используют 42.65% разработчиков
  • Это 6-я по популярности технология
  • 87% разработчиков хотят продолжать использовать Node.js
  • Средняя зарплата Node.js разработчика: $74,000

Производительность разных методов установки (время запуска hello world приложения):

Метод Время запуска Использование памяти Размер установки
NodeSource 45ms 23MB 50MB
NVM 47ms 23MB 55MB
fnm 43ms 23MB 52MB
Snap 180ms 45MB 85MB

Заключение и рекомендации

Правильная установка Node.js — это основа стабильного и масштабируемого приложения. Вот мои финальные рекомендации:

Для разработки: используйте nvm или fnm. Это даст вам гибкость в управлении версиями и упростит работу с разными проектами.

Для production: NodeSource репозиторий + PM2 + systemd сервис. Такая связка обеспечит стабильность и легкость обслуживания.

Для контейнеризации: используйте официальные Docker образы с Alpine Linux для минимального размера.

Обязательно настройте:

  • Reverse proxy (Nginx)
  • SSL сертификаты
  • Мониторинг и логирование
  • Автоматические бэкапы
  • Firewall правила

Не забывайте про безопасность — используйте отдельных пользователей для приложений, настройте правильные права доступа и регулярно обновляйте зависимости.

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

Помните: лучше потратить время на правильную настройку сразу, чем потом разбираться с проблемами в продакшне. Node.js — мощная технология, но она требует грамотного подхода к инфраструктуре.


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

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

Leave a reply

Your email address will not be published. Required fields are marked