|
|
@@ -4,41 +4,21 @@ This option installs OliveTin as a launchd service, so it runs in the background
|
|
|
|
|
|
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`.
|
|
|
|
|
|
-== 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/
|
|
|
-----
|
|
|
+== Choose LaunchAgent or LaunchDaemon
|
|
|
|
|
|
-This gives you the following layout, all owned by your user:
|
|
|
+launchd offers two ways to run a background service:
|
|
|
|
|
|
-[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.)
|
|
|
+* *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.
|
|
|
|
|
|
-~/Library/Logs/OliveTin/olivetin.log # service stdout/stderr
|
|
|
-----
|
|
|
+Follow one complete flow below. Both use the same plist structure; only the install locations and `launchctl` domain differ.
|
|
|
|
|
|
-=== Create the service definition
|
|
|
+== Service definition
|
|
|
|
|
|
Create a file named `app.olivetin.olivetin.plist` with the contents below.
|
|
|
|
|
|
[IMPORTANT]
|
|
|
-launchd does *not* expand `~`, so the paths must be absolute. Replace `YOUR_USERNAME` with the output of `whoami` in every path.
|
|
|
+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]
|
|
|
----
|
|
|
@@ -73,118 +53,161 @@ launchd does *not* expand `~`, so the paths must be absolute. Replace `YOUR_USER
|
|
|
</plist>
|
|
|
----
|
|
|
|
|
|
-`WorkingDirectory` makes the relative `webui` and `var` folders resolve inside the application folder, `KeepAlive` restarts OliveTin if it exits (like systemd's `Restart=always`), and `RunAtLoad` starts it as soon as the service is loaded.
|
|
|
+For a LaunchDaemon, use the same keys but substitute the paths shown in the table:
|
|
|
|
|
|
-=== Register and start the service
|
|
|
+[cols="1,1,1"]
|
|
|
+|===
|
|
|
+| Plist entry | LaunchAgent | LaunchDaemon
|
|
|
|
|
|
-[source,shell]
|
|
|
-----
|
|
|
-cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
|
|
|
-launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
|
|
|
-----
|
|
|
+| 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, which defaults to the current directory. The service definition below passes `-configdir /usr/local/etc/OliveTin` explicitly.
|
|
|
+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.
|
|
|
|
|
|
-== Choose LaunchAgent or LaunchDaemon
|
|
|
+[NOTE]
|
|
|
+`launchctl bootstrap`/`bootout` replace the deprecated `launchctl load`/`unload`.
|
|
|
|
|
|
-launchd offers two ways to run a background service:
|
|
|
+== LaunchAgent (per-user)
|
|
|
|
|
|
-* *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.
|
|
|
+=== Install the files
|
|
|
|
|
|
-== Create the service definition
|
|
|
+Run these from the extracted archive directory:
|
|
|
|
|
|
-Create a file named `app.olivetin.olivetin.plist` with the following contents. Adjust the two paths if you installed OliveTin elsewhere.
|
|
|
-sudo cp -R webui /usr/local/etc/OliveTin/
|
|
|
+[source,shell]
|
|
|
----
|
|
|
+# Create the application folder and a place for logs
|
|
|
+mkdir -p ~/Library/Application\ Support/OliveTin/var
|
|
|
+mkdir -p ~/Library/Logs/OliveTin
|
|
|
|
|
|
-[NOTE]
|
|
|
-OliveTin looks for `config.yaml` in the directory given by the `-configdir` flag, which defaults to the current directory. The service definition below passes `-configdir /usr/local/etc/OliveTin` explicitly, and sets `WorkingDirectory` so the `webui` and `var` folders resolve there.
|
|
|
+# 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/
|
|
|
+----
|
|
|
|
|
|
-=== Create the service definition
|
|
|
+This gives you the following layout, all owned by your user:
|
|
|
|
|
|
-Create a file named `app.olivetin.olivetin.plist` with the following contents. Adjust the paths if you installed OliveTin elsewhere.
|
|
|
+[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.)
|
|
|
|
|
|
-[source,xml]
|
|
|
+~/Library/Logs/OliveTin/olivetin.log # service stdout/stderr
|
|
|
----
|
|
|
-<?xml version="1.0" encoding="UTF-8"?>
|
|
|
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
|
-<plist version="1.0">
|
|
|
-<dict>
|
|
|
- <key>Label</key>
|
|
|
- <string>app.olivetin.olivetin</string>
|
|
|
|
|
|
- <key>ProgramArguments</key>
|
|
|
- <array>
|
|
|
- <string>/usr/local/bin/OliveTin</string>
|
|
|
- <string>-configdir</string>
|
|
|
- <string>/usr/local/etc/OliveTin</string>
|
|
|
- </array>
|
|
|
+=== Register and start
|
|
|
|
|
|
- <key>WorkingDirectory</key>
|
|
|
- <string>/usr/local/etc/OliveTin</string>
|
|
|
+[source,shell]
|
|
|
+----
|
|
|
+cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
|
|
|
+launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
|
|
|
+----
|
|
|
|
|
|
- <key>KeepAlive</key>
|
|
|
- <true/>
|
|
|
+=== Verify
|
|
|
|
|
|
- <key>RunAtLoad</key>
|
|
|
- <true/>
|
|
|
+Open http://localhost:1337 in a browser. If the page does not load, check the service log:
|
|
|
|
|
|
- <key>StandardOutPath</key>
|
|
|
- <string>/usr/local/var/log/olivetin.log</string>
|
|
|
- <key>StandardErrorPath</key>
|
|
|
- <string>/usr/local/var/log/olivetin.log</string>
|
|
|
-</dict>
|
|
|
-</plist>
|
|
|
+[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
|
|
|
----
|
|
|
|
|
|
-`KeepAlive` restarts OliveTin if it exits (like systemd's `Restart=always`), and `RunAtLoad` starts it as soon as the service is loaded.
|
|
|
+=== Restart after a change
|
|
|
|
|
|
-=== Register and start the service
|
|
|
+After editing `config.yaml` or replacing the binary, restart the service so the change takes effect:
|
|
|
|
|
|
[source,shell]
|
|
|
----
|
|
|
-mkdir -p /usr/local/var/log
|
|
|
-cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
|
|
|
-launchctl load ~/Library/LaunchAgents/app.olivetin.olivetin.plist
|
|
|
+launchctl kickstart -k gui/$(id -u)/app.olivetin.olivetin
|
|
|
----
|
|
|
|
|
|
-To stop and disable it:
|
|
|
+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 unload ~/Library/LaunchAgents/app.olivetin.olivetin.plist
|
|
|
+launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
|
|
|
+launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
|
|
|
----
|
|
|
|
|
|
-=== As a LaunchDaemon (system-wide, at boot)
|
|
|
+== LaunchDaemon (system-wide)
|
|
|
+
|
|
|
+=== Install the files
|
|
|
+
|
|
|
+Run these from the extracted archive directory:
|
|
|
|
|
|
[source,shell]
|
|
|
----
|
|
|
-sudo launchctl kickstart -k system/app.olivetin.olivetin
|
|
|
+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/
|
|
|
----
|
|
|
|
|
|
-sudo launchctl bootstrap system /Library/LaunchDaemons/app.olivetin.olivetin.plist
|
|
|
+This gives you the following layout:
|
|
|
+
|
|
|
+[source]
|
|
|
----
|
|
|
+/usr/local/bin/OliveTin
|
|
|
+/usr/local/etc/OliveTin/
|
|
|
+├── config.yaml
|
|
|
+├── webui/
|
|
|
+└── var/
|
|
|
|
|
|
-[NOTE]
|
|
|
-`bootstrap`/`bootout` replace the deprecated `launchctl load`/`unload`. The domain target for a LaunchDaemon is `system`.
|
|
|
+/usr/local/var/log/olivetin.log # service stdout/stderr
|
|
|
+----
|
|
|
|
|
|
-To stop and disable it:
|
|
|
+=== Register and start
|
|
|
|
|
|
[source,shell]
|
|
|
----
|
|
|
-sudo launchctl bootout system /Library/LaunchDaemons/app.olivetin.olivetin.plist
|
|
|
+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
|
|
|
+=== 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. To restart in place:
|
|
|
+After editing `config.yaml` or replacing the binary, restart the service so the change takes effect:
|
|
|
|
|
|
[source,shell]
|
|
|
----
|
|
|
@@ -199,13 +222,4 @@ sudo launchctl bootout system /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
|
|
|
-----
|
|
|
-
|
|
|
include::partial$install/post_generic.adoc[]
|