Node.js развивается очень быстро, и каждый проект оказывается привязан к своей версии. Админ-панель, написанная пару лет назад, работает на старой версии, а новый проект на Next.js требует современную LTS. Если в системе через пакетный менеджер установлен один Node.js, держать оба проекта на одном сервере становится трудно. nvm, Node Version Manager, позволяет каждому пользователю хранить несколько версий Node.js в домашнем каталоге и переключаться между ними одной командой.
Как работает nvm
nvm — это обычный shell-скрипт, который скачивает версии Node.js в каталог ~/.nvm пользователя. При переключении он меняет только переменную PATH текущей сессии и не трогает системные файлы. Поэтому root-доступ для nvm не нужен, а настройки одного пользователя не влияют на другого. Обратная сторона: Node.js, установленный через nvm, виден только этому пользователю и только в сессии, где загружен nvm.
Установка nvm
Установка выполняется скриптом из официального репозитория на GitHub. Скрипт вызывается с номером версии, поэтому актуальный релиз сверьте с README репозитория nvm. В примере ниже указана v0.40.1.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm --version
Скрипт добавляет в ~/.bashrc несколько строк, загружающих nvm. Если nvm --version отвечает «command not found», закройте и снова откройте терминал или повторите source. В zsh строки попадают в ~/.zshrc.
Установка и переключение версий
Основных команд у nvm немного: посмотреть доступные версии, установить нужную, переключиться на неё и задать версию по умолчанию. Для production обычно выбирают LTS-версии с длительной поддержкой, потому что они дольше получают обновления безопасности.
nvm ls-remote --lts # доступные LTS-версии
nvm install --lts # последняя LTS
nvm install 18 # последняя 18.x
nvm use 18 # переключиться в текущей сессии
nvm alias default 20 # версия для новых сессий
nvm ls # установленные версии
node -v
nvm use действует только на открытый терминал. В новой сессии загружается версия, отмеченная как default. Удобно сделать версией по умолчанию самую востребованную на сервере, а на остальные переключаться по необходимости.
Файл .nvmrc: проект помнит свою версию
Не нужно держать в голове, какой проект на какой версии работает. Создайте в папке проекта файл .nvmrc с номером версии, и команда nvm use без параметров сама выберет нужную. Файл хранится в Git, и вся команда работает на одной версии.
cd /var/www/eski-panel
echo "18" > .nvmrc
nvm install # ставит версию из .nvmrc
nvm use # переключается на неё
Полезно также указать допустимый диапазон версий в поле engines файла package.json. nvm этим не управляет, но при установке на неподходящей версии появится предупреждение.
Работа с PM2, cron и systemd
Именно здесь возникает самая частая проблема. nvm загружается только в интерактивном shell, а задания cron и службы systemd ~/.bashrc не читают. В итоге в терминале всё работает, а скрипт в cron падает с ошибкой «node: command not found». Решение простое: в таких местах указывайте полный путь к Node.js.
nvm which 20
# /home/deploy/.nvm/versions/node/v20.x.x/bin/node
# в crontab
*/10 * * * * /home/deploy/.nvm/versions/node/v20.18.0/bin/node /var/www/misol-app/jobs/sync.js
v20.18.0 здесь лишь пример, точный путь возьмите из вывода nvm which. С PM2 проще: если установить PM2 в сессии с нужной версией, запущенные им приложения будут использовать её. Когда разным проектам нужны разные версии, в ecosystem-файле можно прописать точный путь в поле interpreter.
apps: [{
name: "eski-panel",
script: "index.js",
interpreter: "/home/deploy/.nvm/versions/node/v18.20.4/bin/node"
}]
После обновления Node.js может понадобиться заново выполнить pm2 startup, потому что в startup-скрипте прописан путь старой версии. PM2 сам предупредит об этом.
Практический пример: два проекта на одном VPS
Небольшая веб-студия в Самарканде держит на одном VPS два клиентских проекта. Первый — панель на Express для misol.uz, написанная в 2022 году; из-за старых пакетов она не работает на Node.js новее 18. Второй — новый сайт на Next.js для example.uz, которому нужен Node.js 20 или выше. Студия установила nvm пользователю deploy, поставила обе версии, положила .nvmrc в папку каждого проекта и прописала в ecosystem-файле PM2 свой путь к интерпретатору для каждого. Теперь обновление старой панели никак не задевает новый сайт.
Удаление лишних версий
Со временем в ~/.nvm скапливаются неиспользуемые версии и занимают место на диске. Перед удалением убедитесь, что ни одно приложение PM2 и ни одно задание cron не привязаны к этой версии.
nvm ls
nvm uninstall 16
nvm cache clear
Если вам важна свобода работать с несколькими версиями Node.js, возьмите VPS в кабинете sayt.uz и настройте nvm под своим пользователем. Такой подход не трогает системные пакеты, и каждый проект остаётся в своём окружении.