Короткий ответ: на Ubuntu 24.04 mise ставится скриптом curl -fsSL https://mise.run | sh, затем в ~/.bashrc добавляется eval «$(~/.local/bin/mise activate bash)», после новой SSH-сессии ставится стек mise use -g node@lts java@temurin-25 python@3.14 uv@latest. PPA не используйте: он для Ubuntu 26.04 и новее. Текущий стабильный mise на момент гайда — v2026.9.6.
Зачем один менеджер вместо nvm, sdkman и pyenv
nvm знает только Node, sdkman — JVM, pyenv — Python. На одном VPS обычно нужны все три, плюс pnpm и uv. Каждый инструмент пишет в bashrc свой кусок PATH, и через месяц which node показывает не то, что вы ставили вчера. mise (документация: mise.jdx.dev) — один бинарь, один activate, одни shims. Глобально на сервере и локально в каталоге проекта.
Сервер должен быть уже приведён к нормальному виду: пользователь sudo, вход по ключу, UFW. Если это чистый VPS — сначала подготовка Ubuntu 24.04. mise ставьте под тем пользователем, от которого будут systemd-юниты, не под root «потому что так проще». Иначе node найдётся в интерактивном SSH и исчезнет в сервисе.
| Задача | Старый способ | Через mise |
|---|---|---|
| Node.js LTS | nvm или apt 18.19.1 | node@lts |
| Java / JDK | sdkman, apt, snap | java@temurin-25 |
| Python | pyenv, deadsnakes | python@3.14 |
| Пакетный менеджер Python | pipx вручную | uv@latest |
| Юнит systemd | shims в PATH | абсолютный путь из mise which |
Что понадобится
- Ubuntu 24.04 LTS (noble), проверка: lsb_release -a;
- пользователь с sudo, не обязательно root;
- исходящий HTTPS (UFW исходящие не режет);
- 10–15 минут и готовность открыть новую SSH-сессию после правки bashrc.
apt nodejs, nvm и PPA mise в этом гайде не участвуют. NodeSource тоже не нужен, если ставите Node через mise — это разобрано в установке Node.js. Команды копируйте целиком. После install без новой сессии node -v часто молчит — это не поломка установщика, вы просто ещё в старом shell.
mise не заменяет apt для nginx, postgresql и docker. Он закрывает языковые рантаймы: Node, JDK, Python, плюс инструменты вроде uv. Системные сервисы ОС по-прежнему ставятся пакетами Ubuntu; конфликт начинается только когда язык ставят и из apt, и из mise.
Шаг 1. Ставим бинарь mise
Официальный установщик кладёт бинарь в ~/.local/bin/mise. Запускайте его тем пользователем, которым будете работать:
curl -fsSL https://mise.run | sh
~/.local/bin/mise --version
Ожидание: строка с v2026.9.6 или той же линейкой 2026.9.x, которую выдал установщик. Если «No such file» — скрипт не дописал файл: повторите curl без прокси-ошибок, проверьте ls -l ~/.local/bin/mise.
Не ставьте пакет из PPA jdx на Ubuntu 24.04. Этот PPA рассчитан на Ubuntu 26.04 и новее; на noble он либо не ставится, либо даёт не тот канал. Канон для 24.04 — только https://mise.run.
Шаг 2. Активируем mise в bash
Бинарь есть, но новый SSH-заход его не подхватит, пока нет activate. Добавьте одну строку в ~/.bashrc:
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc
Проверьте, что строка одна, не десять копий после повторных попыток:
grep -n 'mise activate' ~/.bashrc
Должна быть ровно одна строка с mise activate bash. Дальше обязательно новая сессия: выйдите из SSH полностью и зайдите снова. source ~/.bashrc в том же окне часто хватает для ручной проверки, но вы не увидите типичных ошибок «в crontab/systemd нет bashrc». Канон — закрыть сессию и открыть новую.
Проверка сразу после входа:
command -v mise
mise --version
echo "$PATH" | tr ':' '\n' | head
command -v mise должен показать путь, PATH — содержать shims mise (~/.local/share/mise/shims) и ~/.local/bin. Если видите только /usr/bin — activate не сработал: вы в sh вместо bash, или зашли под другим пользователем, или bashrc не читается (неинтерактивный shell).
Шаг 3. Ставим рантаймы одной командой
Это канон стека для остальных гайдов серии:
mise use -g node@lts java@temurin-25 python@3.14 uv@latest
mise doctor
node -v
java -version
python --version
uv --version
Что должно получиться:
- Node.js LTS 24, на момент гайда latest этой линии — v24.21.0 (проверка: node -v);
- Temurin 25, не «голый» OpenJDK из java@25 — вендор в идентификаторе обязателен;
- Python 3.14 и uv как менеджер окружений.
mise use -g и ставит, и записывает глобальные версии. Голый mise install node@lts скачает архив, но не сделает его текущим: node -v останется системным или «command not found». Для Node отдельно — гайд по Node.js, для JDK — Java 21 и 25 через Temurin, для Python — Python 3.14, venv и uv.
Проверка mise doctor: не должно быть красных ошибок про activate и про конфликтующий PATH. Предупреждения про slow shell приемлемы, ошибки «mise not activated» — нет.
.tool-versions и mise.toml
Глобальные версии живут в конфиге пользователя (mise.toml в ~/.config/mise/). Каталог проекта может переопределить их двумя способами — выберите один и не мешайте оба без нужды.
Классический asdf-файл .tool-versions в корне проекта:
node lts
java temurin-25
python 3.14
Нативный mise.toml в том же каталоге:
[tools]
node = "lts"
java = "temurin-25"
python = "3.14"
uv = "latest"
Запись делается так:
cd ~/app
mise use node@lts java@temurin-21
Без -g mise пишет в текущий каталог. Зашли в ~/app — Temurin 21. Вышли в домашнюю — снова глобальный Temurin 25. Это правильный способ держать два проекта с разным JDK на одном VPS, без sdkman и без ручного JAVA_HOME.
Проверка:
mise current
mise ls
mise current показывает, что активно здесь и сейчас. Если java в проекте temurin-21, а дома temurin-25 — так и задумано.
systemd: только абсолютный путь, не shims
Shims mise (~/.local/share/mise/shims/node) работают в интерактивном bash после activate. У systemd нет вашего bashrc, нет eval activate и часто нет HOME так, как вы думаете. Юнит с ExecStart=/home/deploy/.local/share/mise/shims/node падает с «command not found» или берёт не ту версию.
Канон: спросить реальный бинарь и вставить его в юнит.
mise which node
mise which java
mise which python
Вывод — путь вида ~/.local/share/mise/installs/node/24.21.0/bin/node. Именно его копируйте в ExecStart=. Пользователь юнита (User=) должен быть тем, у кого этот путь существует: файлы в /root/.local не видны сервису User=deploy.
Не оборачивайте запуск в bash -lc «чтобы подхватился bashrc»: это скрывает поломку и ломается в Type=notify/forking. Нужен абсолютный путь из mise which.
Проверка, что фундамент стоит
mise --version
mise doctor
mise current
command -v node; node -v
command -v java; java -version
command -v python; python --version
command -v uv; uv --version
mise which node
type node
type node должен указывать на shim mise, mise which node — на реальный бинарь в installs. Если type node показывает /usr/bin/node — в системе остался apt-пакет 18.19.1 или nvm перебил PATH. Снимите пакет (sudo apt remove nodejs) только если вы его ставили сами и ничто системное от него не зависит; nvm вычищайте из bashrc.
Частые ошибки
- Не открыли новую сессию. mise —version работает по полному пути, а node — нет. Закройте SSH и зайдите снова, не ограничивайтесь source в том же окне как единственной проверкой.
- mise install без mise use. Архив лежит в installs, но глобальная версия не выбрана. Всегда mise use -g … для серверного стека.
- nvm в bashrc ниже или выше activate. nvm дописывает свой PATH последним и перебивает shims. Удалите nvm или оставьте mise activate самой последней строкой, затем новая сессия и type node.
- PPA на Ubuntu 24.04. Не подключайте. Канон — curl https://mise.run. PPA — для 26.04+.
- Юнит systemd на shim. Берите mise which. После смены major-версии (например новый LTS) обновите ExecStart: путь содержит номер вроде 24.21.0.
- Установка под root, запуск под deploy. У deploy нет ~/.local/share/mise. Ставьте mise тем же User=, что в юните.
FAQ
Чем mise лучше связки nvm + sdkman + pyenv?
Одним activate и одним списком версий. Не нужно помнить, какой менеджер за какой язык отвечает, и не нужно чинить порядок строк в bashrc. Для VPS с Node, Java и Python это меньше точек отказа.
Нужен ли PPA mise на Ubuntu 24.04?
Нет. На noble ставьте curl -fsSL https://mise.run | sh. PPA рассчитан на Ubuntu 26.04 и новее. Смешивать скрипт и PPA не нужно.
Почему после установки node -v пишет command not found?
Нет activate в текущей сессии либо сделали mise install без mise use. Добавьте eval activate в ~/.bashrc, откройте новую сессию, выполните mise use -g node@lts и снова node -v.
Можно ли в systemd вызывать команду mise?
Не как замену бинарю. В ExecStart указывайте абсолютный путь из mise which. mise exec в юните возможен, но тянет окружение и лишние зависимости; для сервиса нужен прямой путь к node или java.
Куда mise кладёт версии и можно ли их удалить?
Бинарь — ~/.local/bin/mise, установки — ~/.local/share/mise/installs, shims — ~/.local/share/mise/shims. Лишнюю версию снимает mise uninstall TOOL@version. Каталог installs руками лучше не чистить, пока юнит systemd ссылается на этот путь.