Вітаю! Я Kernelka, і сьогодні покажу, як швидко та безпечно підняти локальне середовище для Node.js у Linux: встановимо NVM, підключимо Yarn, запустимо допоміжні сервіси в Docker та оформимо автозапуск вашого застосунку через systemd. Це надійна база для щоденної роботи і продакшн-подібного девелопменту 💻

Що ви отримаєте

Після цього гайда ви матимете акуратний стек для розробка на Linux: - NVM для керування версіями Node.js; - Yarn як сучасний пакетний менеджер; - Docker для баз даних та сервісів (без сміття в системі); - systemd для автозапуску і моніторингу процесу як сервісу.

Передумови: пакети та права

Оновіть систему та встановіть корисні інструменти. Все робимо у звичному терміналі Linux.

sudo apt update && sudo apt install -y \
  curl git build-essential ca-certificates

Крок 1. Встановлення NVM і Node.js

NVM дає змогу мати кілька версій nodejs в Linux і легко між ними перемикатися.

# Встановлення NVM (перевірте актуальну версію на https://github.com/nvm-sh/nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Підключаємо NVM у поточну сесію
export NVM_DIR="$HOME/.nvm"
source "$NVM_DIR/nvm.sh"

# Ставимо LTS-версію Node.js
nvm install --lts

# Перевіряємо
node -v
npm -v

За потреби ви завжди можете встановити іншу версію:

nvm install 20
nvm use 20

Крок 2. Yarn: corepack або npm

Якщо ваша Node.js ≥ 16.10, краще вмикати Yarn через corepack (офіційний спосіб):

corepack enable
corepack prepare yarn@stable --activate
yarn -v

Альтернатива через npm (для старіших Node.js):

npm i -g yarn
yarn -v

Крок 3. Швидкий демо-проєкт

Створимо мінімальний HTTP-сервер та скрипт старту.

mkdir -p ~/apps/myapp && cd ~/apps/myapp

# package.json зі стартовим скриптом
tee package.json > /dev/null <<'EOF'
{
  "name": "myapp",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "start": "node index.js"
  }
}
EOF

# Простий сервер на Node.js
tee index.js > /dev/null <<'EOF'
const http = require('http');
const port = process.env.PORT || 3000;
http.createServer((req, res) => {
  res.end('Hello from Node.js on Linux!');
}).listen(port, () => console.log('Listening on', port));
EOF

# Перевірка локально
yarn start

Відкрийте http://localhost:3000 — має працювати.

Крок 4. Docker для сервісів (наприклад, Postgres)

Щоб не бруднити систему, підніматимемо залежності у контейнерах. Це класичний сценарій для Docker на Linux.

# Швидке встановлення Docker (офіційний скрипт)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker  # оновить групи без перезавантаження сесії

docker --version

# Піднімемо Postgres
docker run -d --name pg \
  -e POSTGRES_PASSWORD=secret \
  -p 5432:5432 \
  -v pgdata:/var/lib/postgresql/data \
  postgres:16

docker ps

Тепер ваша апка може підключатися до БД на localhost:5432.

Крок 5. Автозапуск через systemd

Оформимо наш Node.js-процес у сервіс systemd. Важливий момент: NVM — це скрипт ініціалізації середовища, тож у ExecStart ми явно його підключимо.

# Створюємо systemd unit. Замініть YOURUSER на ваш логін у системі
sudo tee /etc/systemd/system/myapp.service > /dev/null <<'EOF'
[Unit]
Description=My Node.js app (Yarn) via NVM
After=network.target docker.service

[Service]
Type=simple
User=YOURUSER
WorkingDirectory=/home/YOURUSER/apps/myapp
Environment=NODE_ENV=production PORT=3000
# Підключаємо nvm і стартуємо апку через yarn
ExecStart=/bin/bash -lc 'source /home/YOURUSER/.nvm/nvm.sh && yarn start'
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target
EOF

# Активуємо сервіс
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service

# Дивимось логи сервісу
journalctl -u myapp.service -f

Готово! Ваша апка переживе перезавантаження системи та автоматично підніметься.

Альтернативні способи

  • Менеджери версій: fnm або asdf — швидші/універсальніші альтернативи NVM.
  • Процес-менеджери: pm2 з інтеграцією в systemd (pm2 startup) — зручно для авто-відновлення та логів.
  • Повна контейнеризація: збілдити образ вашої апки та керувати всім через docker compose. Мінімум різниць між девом і продом.
  • Планувальник задач: замість cron використовуйте cron та systemd timers для періодичних скриптів (більш надійно та з журналами).

GUI-спосіб

  • VS Code: встановіть розширення ESLint, Prettier, Docker; відкрийте проєкт і керуйте контейнерами з панелі Docker.
  • Docker Desktop або Portainer: зручний GUI для контейнерів (статуси, логи, рестарти).
  • Cockpit (серверна панель): модуль systemd для керування сервісами через веб-інтерфейс.

FAQ

Yarn не знаходиться у systemd-сервісі

Проблема з оточенням. У unit-файлі обов'язково підключіть NVM через bash -lc і source ~/.nvm/nvm.sh, як у прикладі вище.

Сервіс падає з помилкою EADDRINUSE

Порт зайнято іншим процесом. Перевірте:

sudo lsof -i :3000

Змініть PORT у unit-файлі або зупиніть конфліктний процес.

Docker каже "permission denied" без sudo

Додайте себе в групу docker і перезайдіть у сесію (або newgrp docker):

sudo usermod -aG docker $USER
newgrp docker

npm/yarn глобальні пакети ставляться в /usr/local і ламаються права

Використовуйте NVM (він ставить усе в домашню директорію користувача), або перейдіть на corepack для Yarn. Це типова пастка у nodejs в Linux.

Як зробити періодичні задачі без cron?

Створіть systemd timer — сучасна альтернатива cron: логи через journalctl, залежності від сервісів, гнучкий графік. Це якраз про cron та systemd timers.

Порада від Kernelka

Тримайте проєкт максимально самодостатнім: версії Node.js зафіксуйте у .nvmrc, середовище — у .env (не комітьте в репозиторій), залежності — у Docker. Так у вас менше «воно в мене працює» і більше стабільності 🚀

Підсумок

  • Встановили NVM і LTS Node.js для керованого середовища.
  • Увімкнули Yarn через corepack (або через npm для старіших Node.js).
  • Створили мінімальний HTTP-сервер і перевірили запуск.
  • Підняли Postgres у Docker без сміття в системі.
  • Оформили автозапуск застосунку як сервіс systemd з підключенням NVM.
  • Згадали альтернативи: fnm/asdf, pm2, повну контейнеризацію і systemd timers.