macos_service.adoc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. = macOS Service (launchd)
  2. 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.
  3. 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`.
  4. == Choose LaunchAgent or LaunchDaemon
  5. launchd offers two ways to run a background service:
  6. * *LaunchAgent* - runs as your user and starts when you log in. No root required. Best for a desktop Mac.
  7. * *LaunchDaemon* - runs as root and starts at boot, before any user logs in. Best for a headless, always-on Mac.
  8. Follow one complete flow below. Both use the same plist structure; only the install locations and `launchctl` domain differ.
  9. == Service definition
  10. Create a file named `app.olivetin.olivetin.plist` with the contents below.
  11. [IMPORTANT]
  12. 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.
  13. [source,xml]
  14. ----
  15. <?xml version="1.0" encoding="UTF-8"?>
  16. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  17. <plist version="1.0">
  18. <dict>
  19. <key>Label</key>
  20. <string>app.olivetin.olivetin</string>
  21. <key>ProgramArguments</key>
  22. <array>
  23. <string>/Users/YOUR_USERNAME/Library/Application Support/OliveTin/OliveTin</string>
  24. <string>-configdir</string>
  25. <string>/Users/YOUR_USERNAME/Library/Application Support/OliveTin</string>
  26. </array>
  27. <key>WorkingDirectory</key>
  28. <string>/Users/YOUR_USERNAME/Library/Application Support/OliveTin</string>
  29. <key>KeepAlive</key>
  30. <true/>
  31. <key>RunAtLoad</key>
  32. <true/>
  33. <key>StandardOutPath</key>
  34. <string>/Users/YOUR_USERNAME/Library/Logs/OliveTin/olivetin.log</string>
  35. <key>StandardErrorPath</key>
  36. <string>/Users/YOUR_USERNAME/Library/Logs/OliveTin/olivetin.log</string>
  37. </dict>
  38. </plist>
  39. ----
  40. For a LaunchDaemon, use the same keys but substitute the paths shown in the table:
  41. [cols="1,1,1"]
  42. |===
  43. | Plist entry | LaunchAgent | LaunchDaemon
  44. | Binary (`ProgramArguments[0]`)
  45. | `/Users/YOUR_USERNAME/Library/Application Support/OliveTin/OliveTin`
  46. | `/usr/local/bin/OliveTin`
  47. | `-configdir` and `WorkingDirectory`
  48. | `/Users/YOUR_USERNAME/Library/Application Support/OliveTin`
  49. | `/usr/local/etc/OliveTin`
  50. | `StandardOutPath` / `StandardErrorPath`
  51. | `/Users/YOUR_USERNAME/Library/Logs/OliveTin/olivetin.log`
  52. | `/usr/local/var/log/olivetin.log`
  53. |===
  54. `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.
  55. [NOTE]
  56. 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.
  57. [NOTE]
  58. `launchctl bootstrap`/`bootout` replace the deprecated `launchctl load`/`unload`.
  59. == LaunchAgent (per-user)
  60. === Install the files
  61. Run these from the extracted archive directory:
  62. [source,shell]
  63. ----
  64. # Create the application folder and a place for logs
  65. mkdir -p ~/Library/Application\ Support/OliveTin/var
  66. mkdir -p ~/Library/Logs/OliveTin
  67. # Copy in the binary, your config, and the bundled web UI
  68. cp OliveTin ~/Library/Application\ Support/OliveTin/
  69. cp config.yaml ~/Library/Application\ Support/OliveTin/
  70. cp -R webui ~/Library/Application\ Support/OliveTin/
  71. ----
  72. This gives you the following layout, all owned by your user:
  73. [source]
  74. ----
  75. ~/Library/Application Support/OliveTin/
  76. ├── OliveTin # the binary
  77. ├── config.yaml # your configuration
  78. ├── webui/ # the web interface assets (shipped in the archive)
  79. └── var/ # runtime data OliveTin writes (logs, etc.)
  80. ~/Library/Logs/OliveTin/olivetin.log # service stdout/stderr
  81. ----
  82. === Register and start
  83. [source,shell]
  84. ----
  85. cp app.olivetin.olivetin.plist ~/Library/LaunchAgents/
  86. launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
  87. ----
  88. === Verify
  89. Open http://localhost:1337 in a browser. If the page does not load, check the service log:
  90. [source,shell]
  91. ----
  92. tail -f ~/Library/Logs/OliveTin/olivetin.log
  93. ----
  94. === Stop and disable
  95. [source,shell]
  96. ----
  97. launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
  98. ----
  99. === Restart after a change
  100. After editing `config.yaml` or replacing the binary, restart the service so the change takes effect:
  101. [source,shell]
  102. ----
  103. launchctl kickstart -k gui/$(id -u)/app.olivetin.olivetin
  104. ----
  105. 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):
  106. [source,shell]
  107. ----
  108. launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
  109. launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/app.olivetin.olivetin.plist
  110. ----
  111. == LaunchDaemon (system-wide)
  112. === Install the files
  113. Run these from the extracted archive directory:
  114. [source,shell]
  115. ----
  116. sudo mkdir -p /usr/local/bin /usr/local/etc/OliveTin/var /usr/local/var/log
  117. sudo cp OliveTin /usr/local/bin/OliveTin
  118. sudo cp config.yaml /usr/local/etc/OliveTin/
  119. sudo cp -R webui /usr/local/etc/OliveTin/
  120. ----
  121. This gives you the following layout:
  122. [source]
  123. ----
  124. /usr/local/bin/OliveTin
  125. /usr/local/etc/OliveTin/
  126. ├── config.yaml
  127. ├── webui/
  128. └── var/
  129. /usr/local/var/log/olivetin.log # service stdout/stderr
  130. ----
  131. === Register and start
  132. [source,shell]
  133. ----
  134. sudo cp app.olivetin.olivetin.plist /Library/LaunchDaemons/
  135. sudo chown root:wheel /Library/LaunchDaemons/app.olivetin.olivetin.plist
  136. sudo launchctl bootstrap system /Library/LaunchDaemons/app.olivetin.olivetin.plist
  137. ----
  138. === Verify
  139. Open http://localhost:1337 in a browser. If the page does not load, check the service log:
  140. [source,shell]
  141. ----
  142. tail -f /usr/local/var/log/olivetin.log
  143. ----
  144. === Stop and disable
  145. [source,shell]
  146. ----
  147. sudo launchctl bootout system /Library/LaunchDaemons/app.olivetin.olivetin.plist
  148. ----
  149. === Restart after a change
  150. After editing `config.yaml` or replacing the binary, restart the service so the change takes effect:
  151. [source,shell]
  152. ----
  153. sudo launchctl kickstart -k system/app.olivetin.olivetin
  154. ----
  155. 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):
  156. [source,shell]
  157. ----
  158. sudo launchctl bootout system /Library/LaunchDaemons/app.olivetin.olivetin.plist
  159. sudo launchctl bootstrap system /Library/LaunchDaemons/app.olivetin.olivetin.plist
  160. ----
  161. include::partial$install/post_generic.adoc[]