Submit an issue View all issues Source
MIR-1275

Keep the on-$PATH miren CLI in sync with the self-managed server (consistent across docs, terraform, and binary)

Ready To Merge public
phinze phinze Opened Jun 29, 2026 Updated Jul 24, 2026

Our own clusters are meant to be as close to mainstream dogfood as possible — set up the way a normal user would by following the public install instructions. That makes this a product issue, not just an ops one.

The mainstream install path (download page → "Get the Miren CLI") tells you to drop the binary on $PATH and use it directly:

tar xzf miren-linux-arm64.tar.gz && sudo install -v -m 755 miren /usr/local/bin/
miren version

Our terraform mirrors that exactly — 50-miren-install.sh does install -m 755 /tmp/miren /usr/local/bin/miren with the comment "same as get-started docs." So far, consistent.

The break happens at upgrade time. miren server upgrade installs the server payload to /var/lib/miren/release/miren, points the systemd unit there, restarts, and health-checks — but it never advances the /usr/local/bin/miren that the docs told you to install and use. From then on the documented CLI on $PATH silently drifts away from the running server. Any mainstream user who installs per the docs and later upgrades ends up in this state; we just happened to surface it on our own cluster.

Concrete symptom from MIR-1274: the toys coordinator's running server was main:9d1c679 (/var/lib/miren/release/miren), while /usr/local/bin/miren was a stale build that didn't even have runner list or a working version — so SSHing in to debug gave a CLI that didn't match the server in front of you. There's also a latent robustness risk: the autoupdate cron drives upgrades with that frozen /usr/local/bin/miren (miren server upgrade --channel main), so a sufficiently old launcher could fail to perform a newer upgrade.

Since miren is all about self-managing a deploy, it should own getting a current CLI onto $PATH rather than leaving it to whatever bootstrapped the box. The fix should be consistent across all three surfaces so the documented path and the self-managed path tell the same story:

  • Binary behaviormiren server upgrade (and initial server install) maintains /usr/local/bin/miren in lockstep with the managed payload. Preference: make it a symlink to /var/lib/miren/release/miren. (Alternative: refresh-copy after a successful upgrade. Symlink is simpler and self-correcting; the one thing to weigh is that the launcher then is the file being replaced during upgrade — safe on Linux via atomic rename, but worth a deliberate look.)
  • Download page / docs — install instructions should match whatever model we land on, so a fresh install and a self-upgraded install converge on the same layout.
  • Our terraform — once the binary owns this, 50-miren-install.sh can stop being the thing that pins /usr/local/bin/miren; it just bootstraps.

Goal: a user (or one of our clusters) following mainstream instructions ends up with a CLI on $PATH that stays in sync with the server miren manages, with no divergence after the first upgrade.

Discovered while recreating the toys runners in MIR-1274.