= macOS Service (launchd) This option installs OliveTin as a launchd service, so it runs in the background and starts automatically. This is the macOS equivalent of running OliveTin as a Linux systemd service or a xref:install/windows_service.adoc[Windows service]. If you just want to run OliveTin as a regular application, follow the xref:install/macos.adoc[macOS install] instructions instead. Before continuing, complete the xref:install/macos.adoc[macOS install] steps (download, extract, and clear the Gatekeeper quarantine) and confirm OliveTin starts correctly by running `./OliveTin`. == Choose LaunchAgent or LaunchDaemon launchd offers two ways to run a background service: * *LaunchAgent* - runs as your user and starts when you log in. No root required. Best for a desktop Mac. * *LaunchDaemon* - runs as root and starts at boot, before any user logs in. Best for a headless, always-on Mac. Follow one complete flow below. Both use the same plist structure; only the install locations and `launchctl` domain differ. == Service definition Create a file named `app.olivetin.olivetin.plist` with the contents below. [IMPORTANT] launchd does *not* expand `~`, so every path in the plist must be absolute. Replace `YOUR_USERNAME` with the output of `whoami` when using the LaunchAgent paths. [source,xml] ---- Label app.olivetin.olivetin ProgramArguments /Users/YOUR_USERNAME/Library/Application Support/OliveTin/OliveTin -configdir /Users/YOUR_USERNAME/Library/Application Support/OliveTin WorkingDirectory /Users/YOUR_USERNAME/Library/Application Support/OliveTin KeepAlive RunAtLoad StandardOutPath /Users/YOUR_USERNAME/Library/Logs/OliveTin/olivetin.log StandardErrorPath /Users/YOUR_USERNAME/Library/Logs/OliveTin/olivetin.log ---- For a LaunchDaemon, use the same keys but substitute the paths shown in the table: [cols="1,1,1"] |=== | Plist entry | LaunchAgent | LaunchDaemon | Binary (`ProgramArguments[0]`) | `/Users/YOUR_USERNAME/Library/Application Support/OliveTin/OliveTin` | `/usr/local/bin/OliveTin` | `-configdir` and `WorkingDirectory` | `/Users/YOUR_USERNAME/Library/Application Support/OliveTin` | `/usr/local/etc/OliveTin` | `StandardOutPath` / `StandardErrorPath` | `/Users/YOUR_USERNAME/Library/Logs/OliveTin/olivetin.log` | `/usr/local/var/log/olivetin.log` |=== `WorkingDirectory` makes the relative `webui` and `var` folders resolve inside the config directory, `KeepAlive` restarts OliveTin if it exits (like systemd's `Restart=always`), and `RunAtLoad` starts it as soon as the service is loaded. [NOTE] OliveTin looks for `config.yaml` in the directory given by the `-configdir` flag. The plist passes `-configdir` explicitly so the service does not depend on the process working directory alone. [NOTE] `launchctl bootstrap`/`bootout` replace the deprecated `launchctl load`/`unload`. == LaunchAgent (per-user) === Install the files Run these from the extracted archive directory: [source,shell] ---- # Create the application folder and a place for logs mkdir -p ~/Library/Application\ Support/OliveTin/var mkdir -p ~/Library/Logs/OliveTin # Copy in the binary, your config, and the bundled web UI cp OliveTin ~/Library/Application\ Support/OliveTin/ cp config.yaml ~/Library/Application\ Support/OliveTin/ cp -R webui ~/Library/Application\ Support/OliveTin/ ---- This gives you the following layout, all owned by your user: [source] ---- ~/Library/Application Support/OliveTin/ ├── OliveTin # the binary ├── config.yaml # your configuration ├── webui/ # the web interface assets (shipped in the archive) └── var/ # runtime data OliveTin writes (logs, etc.) ~/Library/Logs/OliveTin/olivetin.log # service stdout/stderr ---- === Register and start [source,shell] ---- cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist ---- === Verify Open http://localhost:1337 in a browser. If the page does not load, check the service log: [source,shell] ---- tail -f ~/Library/Logs/OliveTin/olivetin.log ---- === Stop and disable [source,shell] ---- launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist ---- === Restart after a change After editing `config.yaml` or replacing the binary, restart the service so the change takes effect: [source,shell] ---- launchctl kickstart -k gui/$(id -u)/app.olivetin.olivetin ---- If you changed the *plist* itself, `kickstart` is not enough - boot the service out and back in so launchd re-reads it (`bootstrap` errors if the service is still loaded): [source,shell] ---- launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist ---- == LaunchDaemon (system-wide) === Install the files Run these from the extracted archive directory: [source,shell] ---- sudo mkdir -p /usr/local/bin /usr/local/etc/OliveTin/var /usr/local/var/log sudo cp OliveTin /usr/local/bin/OliveTin sudo cp config.yaml /usr/local/etc/OliveTin/ sudo cp -R webui /usr/local/etc/OliveTin/ ---- This gives you the following layout: [source] ---- /usr/local/bin/OliveTin /usr/local/etc/OliveTin/ ├── config.yaml ├── webui/ └── var/ /usr/local/var/log/olivetin.log # service stdout/stderr ---- === Register and start [source,shell] ---- sudo cp app.olivetin.olivetin.plist /Library/LaunchDaemons/ sudo chown root:wheel /Library/LaunchDaemons/app.olivetin.olivetin.plist sudo launchctl bootstrap system /Library/LaunchDaemons/app.olivetin.olivetin.plist ---- === Verify Open http://localhost:1337 in a browser. If the page does not load, check the service log: [source,shell] ---- tail -f /usr/local/var/log/olivetin.log ---- === Stop and disable [source,shell] ---- sudo launchctl bootout system /Library/LaunchDaemons/app.olivetin.olivetin.plist ---- === Restart after a change After editing `config.yaml` or replacing the binary, restart the service so the change takes effect: [source,shell] ---- sudo launchctl kickstart -k system/app.olivetin.olivetin ---- If you changed the *plist* itself, `kickstart` is not enough - boot the service out and back in so launchd re-reads it (`bootstrap` errors if the service is still loaded): [source,shell] ---- sudo launchctl bootout system /Library/LaunchDaemons/app.olivetin.olivetin.plist sudo launchctl bootstrap system /Library/LaunchDaemons/app.olivetin.olivetin.plist ---- include::partial$install/post_generic.adoc[]