Skip to content

mise

Installs mise from the official APT repository and activates it system-wide. Three task files, each runnable with --tags: repository.yml (signing key + source), install.yml (the package), shell.yml (activation snippets).

Not the PPA and not curl | sh. One deviation from the upstream APT instructions: the key is installed ASCII-armoured at /etc/apt/keyrings/mise-archive-keyring.asc rather than dearmored, which APT reads natively and keeps the task idempotent.

amd64 and arm64 only — the repository publishes nothing else, and the role fails with a clear message rather than installing something unexpected.

- hosts: all
roles:
- role: mise
Terminal window
cd ansible
ansible-playbook -i inventory/proxmox.proxmox.yml playbooks/setup-mise.yml --limit arcane
ansible-playbook -i inventory/proxmox.proxmox.yml playbooks/setup_new_machine.yml --tags mise
VariableDefaultDescription
mise_version''Empty follows the repo; set to pin an exact APT version
mise_package_statelatestUpgrades every run; present installs and leaves it
mise_configure_shelltrueWrite the activation snippets
mise_remove_conflicting_sourcestrueDelete other source files for the same URL
mise_apt_repo_urlhttps://mise.jdx.dev/debBase repository URL
mise_apt_repo_distributionstableSuite
mise_apt_repo_componentsmainComponents
mise_apt_sources_file/etc/apt/sources.list.d/mise.listSources file written
mise_apt_key_urlhttps://mise.jdx.dev/gpg-key.pubUpstream signing key
mise_apt_keyring_path/etc/apt/keyrings/mise-archive-keyring.ascWhere the key lands (signed-by)
mise_profile_script/etc/profile.d/mise.shPOSIX activation snippet
mise_fish_conf_dir/etc/fish/conf.dFish snippet directory (fish hosts only)

mise_version wins over mise_package_state — a pin implies present.

extrepo enable mise, the other route the upstream docs describe, writes a second source for the same URL under a different key. APT then refuses to read its source list at all, so every apt call on the host fails:

E: Conflicting values set for option Signed-By regarding source https://mise.jdx.dev/deb/ stable:
/var/lib/extrepo/keys/mise.asc != /etc/apt/keyrings/mise-archive-keyring.asc

The role scans /etc/apt/sources.list.d for other files mentioning mise.jdx.dev and removes them first, before any other APT task — on a host already mid-conflict, anything ordered earlier would hit the same error. mise_remove_conflicting_sources: false turns that into an explanatory failure. An entry written straight into /etc/apt/sources.list is not detected; remove it by hand.

Two system-wide snippets, so no per-user rc file is touched:

PathWritten whenContents
/etc/profile.d/mise.shalwaysmise activate for interactive bash/zsh, mise activate bash --shims otherwise
/etc/fish/conf.d/mise.fishfish installedSame split, fish syntax

The split matters: mise activate installs a prompt hook — what makes tool versions follow a cd — in bash/zsh syntax a dash login shell would choke on. Non-interactive shells get --shims, which only prepends the shim directory to PATH.

  • /etc/profile.d is read by login shells only. ssh host '<cmd>', cron and systemd units do not source it — use bash -lc '...' or the shims directly. Fish is unaffected.
  • Existing sessions keep their old environment until re-login.
  • Tools are per-user. This role installs the binary and turns activation on. Installing a tool (mise use -g node@22) is still a per-account action.
Terminal window
mise doctor # checks activation, shims and config
mise use -g node@22
mise upgrade # upgrades installed tools, not mise itself

mise self-update is disabled for APT installs. Upgrade with apt upgrade mise or re-run this role.

SymptomCause
mise: command not found over ssh host '<cmd>'Expected — non-login shell. See activation above.
Conflicting values set for option Signed-ByAnother source declares the same repo; re-run the role.
NO_PUBKEY on apt updateKey missing or truncated. Re-run with --tags apt-repo.
Unsupported architectureNot amd64/arm64. Install another way; do not work around the guard.
Tools do not switch on cdActivation fell back to shims — check the shell is interactive and restarted.