Improve local storage transitional behavior: auto-mount when host directory has existing data
Context
PR #700 made local storage opt-in via explicit disk definitions in app.toml. It included a transitional behavior: if any env var references /miren/data/local, the launcher auto-injects the local storage volume. This covers some apps, but we found that several of our own Garden apps (uptime-kuma, metrics, victoriametrics, tempo) don't reference the path in env vars — they hardcode it in shell scripts, config files, or Dockerfile symlinks. Those apps all broke on their next sandbox restart because the mount simply wasn't there.
We fixed our apps by adding explicit config (mirendev/infra#57), but external users will hit the same thing. The env var check is too narrow a heuristic.
Proposal
During sandbox setup, check whether the host-side local storage directory for the app (e.g., {DataPath}/data/local/{appID}) exists and is non-empty. If it is, auto-mount it into the container and emit a deploy-time warning like:
⚠️ This app has existing data in local storage but no
[[services.<svc>.disks]]definition. The data has been mounted automatically, but please add an explicit disk config to your app.toml — this automatic behavior will be removed in a future release.
This is a much better safety net than the env var check because it catches the actual dangerous case: an app that has data it would lose. It doesn't matter how the app references the path — if there's data on disk, we should mount it and tell the user to go explicit.
Why explicit matters
Making local storage explicit is necessary for multi-node scheduling. The scheduler needs to know which apps have node-local state so it can make safe decisions about placement. Implicit mounts hid this from the scheduler, which meant stateful apps could get scheduled to runners with no data.
Scope
This is explicitly a transitional behavior with a shelf life. Once we're confident users have migrated, we remove it. The warning in deploy output gives users a personalized nudge at exactly the right moment — way more effective than a broadcast announcement.
Related
- PR #700: Make local shared storage opt-in via disk provider
- MIR-944 (specsMatch pool reuse bug discovered during rollout)
- mirendev/infra#57: Our own Garden app fixes