Skip to content

feat(autostart): add LaunchDaemon support for headless macOS servers#4984

Open
resker wants to merge 1 commit into
lima-vm:masterfrom
resker:feature/launchdaemon-support
Open

feat(autostart): add LaunchDaemon support for headless macOS servers#4984
resker wants to merge 1 commit into
lima-vm:masterfrom
resker:feature/launchdaemon-support

Conversation

@resker
Copy link
Copy Markdown

@resker resker commented May 15, 2026

Closes #4983

Summary

Adds limactl autostart enable --condition=boot to register a Lima instance
as a system-level LaunchDaemon. The VM starts at boot without requiring a user
login session, enabling headless macOS server deployments.

Also unifies the existing start-at-login functionality under the new
limactl autostart command and deprecates limactl start-at-login.

Commands

# Start at user login (LaunchAgent on macOS, systemd user service on Linux)
limactl autostart enable k3s

# Start at system boot, before any user login (macOS only, prompts for sudo)
limactl autostart enable --condition=boot k3s

# Remove registration (auto-detects which type is installed)
limactl autostart disable k3s

Design

Privilege model: limactl itself stays non-root (the existing root check
is not bypassed). The --condition=boot path execs sudo internally for
exactly two operations — writing to /Library/LaunchDaemons/ and running
launchctl bootstrap system — and prompts for a password once at install time.

UserName plist key: launchd runs the daemon process as the specified user
(defaulting to $USER), so the Lima instance runs under the correct user's
home directory and config without requiring that user to be logged in.

Runtime: the daemon plist calls limactl start <instance> --foreground,
consistent with the existing LaunchAgent approach. Normal limactl start/stop
continues to work; no privileged runtime operations are needed.

Changes

  • pkg/autostart/launchd/io.lima-vm.daemon.INSTANCE.plist — daemon plist template
  • pkg/autostart/launchd/launchd.goGetDaemonPlistPath, DaemonServiceNameFrom, DaemonTemplate
  • pkg/autostart/managers.goextraTemplateVars field on TemplateFileBasedManager
  • pkg/autostart/managers_darwin.goDaemonManager(userName string) constructor
  • pkg/autostart/managers_linux.go, managers_others.goDaemonManager stubs
  • cmd/limactl/autostart.golimactl autostart command group (cross-platform)
  • cmd/limactl/autostart_darwin.go — macOS: login → LaunchAgent, boot → LaunchDaemon
  • cmd/limactl/autostart_others.go — non-macOS: login only, boot returns unsupported error
  • cmd/limactl/start-at-login.go — marked deprecated
  • cmd/limactl/main.go — register autostart subcommand
  • website/content/en/docs/usage/autostart.md — new documentation subpage

Testing

  • Unit tests added for GetDaemonPlistPath, DaemonServiceNameFrom, and daemon plist rendering
  • Manually tested on Apple Silicon Mac Mini (macOS 26, arm64) running a k3s instance
  • VM started automatically after reboot with the LaunchDaemon installed
  • HA (Home Assistant in k3s) confirmed healthy post-reboot

Notes

  • --condition=boot is macOS only; other platforms return an unsupported error
  • Developed with AI assistance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license and I have signed off all commits per the DCO.

@resker resker force-pushed the feature/launchdaemon-support branch from f2ca93d to 0c20526 Compare May 15, 2026 03:22
Comment thread cmd/limactl/daemon.go Outdated
Comment thread website/content/en/docs/security/_index.md
Comment thread website/content/en/docs/usage/_index.md Outdated
Comment thread cmd/limactl/autostart.go Outdated
Comment thread website/content/en/docs/usage/autostart.md
Comment thread cmd/limactl/start-at-login.go Outdated
@resker resker marked this pull request as ready for review May 15, 2026 04:02
@AkihiroSuda
Copy link
Copy Markdown
Member

@resker May I confirm that your commits were DCO-signed by you human, not by a bot?
Asking because the commits were pushed extremely quickly after my review 🙂

Comment thread website/content/en/docs/releases/deprecated.md Outdated
@resker
Copy link
Copy Markdown
Author

resker commented May 15, 2026

@resker May I confirm that your commits were DCO-signed by you human, not by a bot? Asking because the commits were pushed extremely quickly after my review 🙂

@AkihiroSuda - yes, confirmed... I am not now nor have I ever been a bot :-) The turnaround assisted by AI tools (everything reviewed and submitted by me though).

@AkihiroSuda
Copy link
Copy Markdown
Member

@resker May I confirm that your commits were DCO-signed by you human, not by a bot? Asking because the commits were pushed extremely quickly after my review 🙂

@AkihiroSuda - yes, confirmed... I am not now nor have I ever been a bot :-) The turnaround assisted by AI tools (everything reviewed and submitted by me though).

Sorry for doubting you 😅
You are very productive!

@AkihiroSuda AkihiroSuda added this to the v2.2.0 milestone May 15, 2026
Copy link
Copy Markdown
Member

@AkihiroSuda AkihiroSuda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM after squashing commits.

WIll merge after the release of v2.1.2

@AkihiroSuda
Copy link
Copy Markdown
Member

@resker Could you squash the commits?

Adds `limactl autostart enable --condition=boot` to register a Lima instance
as a system-level LaunchDaemon. The VM starts at boot without requiring a user
login session, enabling headless macOS server deployments.

Also unifies the existing start-at-login functionality under the new
`limactl autostart` command and deprecates `limactl start-at-login`.

- pkg/autostart/launchd: add DaemonManager, plist template, and helpers
- pkg/autostart/managers.go: add extraTemplateVars field
- pkg/autostart/managers_darwin.go: DaemonManager constructor
- pkg/autostart/managers_{linux,others}.go: unsupported stubs
- cmd/limactl/autostart.go: cross-platform autostart command group
- cmd/limactl/autostart_darwin.go: login → LaunchAgent, boot → LaunchDaemon
- cmd/limactl/autostart_others.go: login only, boot returns unsupported error
- cmd/limactl/start-at-login.go: marked deprecated
- website/content/en/docs/usage/autostart.md: new documentation page

Signed-off-by: Robert Esker <resker@gmail.com>
@resker resker force-pushed the feature/launchdaemon-support branch from 65d8aa2 to f3b3abb Compare June 6, 2026 01:10
@resker
Copy link
Copy Markdown
Author

resker commented Jun 6, 2026

@AkihiroSuda - Squashed ( the lints check seems to be a network error in the link-checker).

Should #5086 and #5088 (follow up refinements to this) be tagged impact/changelog / milestone v2.2.0 as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: LaunchDaemon support for headless macOS servers

2 participants