- Home »

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 — мощная технология, но она требует грамотного подхода к инфраструктуре.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.