Fossil SCM
Added www/server/macos/service.md and then added macOS to the set of server OSes offered in www/server/index.html
Commit
e0ad4b48b5a7c5cecdf8938f8e81ef9570061e1eb039bf7b6914b0f2371d76bb
Parent
b5fefeec2373959…
2 files changed
+13
+122
+13
| --- www/server/index.html | ||
| +++ www/server/index.html | ||
| @@ -201,10 +201,22 @@ | ||
| 201 | 201 | <td class="doc"><a href="any/althttpd.md">✅</a></td> |
| 202 | 202 | <td class="doc"><a href="debian/nginx.md">✅</a></td> |
| 203 | 203 | <td class="doc"><a href="debian/service.md">✅</a></td> |
| 204 | 204 | </tr> |
| 205 | 205 | |
| 206 | + <tr> | |
| 207 | + <th class="host">macOS</th> | |
| 208 | + <td class="doc"><a href="any/none.md">✅</a></td> | |
| 209 | + <td class="doc">❌</td> | |
| 210 | + <td class="doc"><a href="any/stunnel.md">✅</a></td> | |
| 211 | + <td class="doc"><a href="any/cgi.md">✅</a></td> | |
| 212 | + <td class="doc"><a href="any/scgi.md">✅</a></td> | |
| 213 | + <td class="doc"><a href="any/althttpd.md">✅</a></td> | |
| 214 | + <td class="doc">❌</td> | |
| 215 | + <td class="doc"><a href="macos/service.md">✅</a></td> | |
| 216 | + </tr> | |
| 217 | + | |
| 206 | 218 | <tr> |
| 207 | 219 | <th class="host">Windows</th> |
| 208 | 220 | <td class="doc"><a href="windows/none.md">✅</a></td> |
| 209 | 221 | <td class="doc">❌</td> |
| 210 | 222 | <td class="doc"><a href="windows/stunnel.md">✅</a></td> |
| @@ -258,10 +270,11 @@ | ||
| 258 | 270 | "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service" |
| 259 | 271 | ]; |
| 260 | 272 | const matrix = { |
| 261 | 273 | "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ], |
| 262 | 274 | "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", YES ], |
| 275 | + "macOS": [ IFA, NO, IFA, IFA, IFA, IFA, NO, YES ], | |
| 263 | 276 | "Windows": [ YES, NO, YES, YES, NO, NO, "IIS", NO ], |
| 264 | 277 | } |
| 265 | 278 | const osNames = Object.keys(matrix).sort((e) => { |
| 266 | 279 | return e.toLowerCase() |
| 267 | 280 | }).map((longName, i) => { |
| 268 | 281 | |
| 269 | 282 | ADDED www/server/macos/service.md |
| --- www/server/index.html | |
| +++ www/server/index.html | |
| @@ -201,10 +201,22 @@ | |
| 201 | <td class="doc"><a href="any/althttpd.md">✅</a></td> |
| 202 | <td class="doc"><a href="debian/nginx.md">✅</a></td> |
| 203 | <td class="doc"><a href="debian/service.md">✅</a></td> |
| 204 | </tr> |
| 205 | |
| 206 | <tr> |
| 207 | <th class="host">Windows</th> |
| 208 | <td class="doc"><a href="windows/none.md">✅</a></td> |
| 209 | <td class="doc">❌</td> |
| 210 | <td class="doc"><a href="windows/stunnel.md">✅</a></td> |
| @@ -258,10 +270,11 @@ | |
| 258 | "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service" |
| 259 | ]; |
| 260 | const matrix = { |
| 261 | "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ], |
| 262 | "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", YES ], |
| 263 | "Windows": [ YES, NO, YES, YES, NO, NO, "IIS", NO ], |
| 264 | } |
| 265 | const osNames = Object.keys(matrix).sort((e) => { |
| 266 | return e.toLowerCase() |
| 267 | }).map((longName, i) => { |
| 268 | |
| 269 | DDED www/server/macos/service.md |
| --- www/server/index.html | |
| +++ www/server/index.html | |
| @@ -201,10 +201,22 @@ | |
| 201 | <td class="doc"><a href="any/althttpd.md">✅</a></td> |
| 202 | <td class="doc"><a href="debian/nginx.md">✅</a></td> |
| 203 | <td class="doc"><a href="debian/service.md">✅</a></td> |
| 204 | </tr> |
| 205 | |
| 206 | <tr> |
| 207 | <th class="host">macOS</th> |
| 208 | <td class="doc"><a href="any/none.md">✅</a></td> |
| 209 | <td class="doc">❌</td> |
| 210 | <td class="doc"><a href="any/stunnel.md">✅</a></td> |
| 211 | <td class="doc"><a href="any/cgi.md">✅</a></td> |
| 212 | <td class="doc"><a href="any/scgi.md">✅</a></td> |
| 213 | <td class="doc"><a href="any/althttpd.md">✅</a></td> |
| 214 | <td class="doc">❌</td> |
| 215 | <td class="doc"><a href="macos/service.md">✅</a></td> |
| 216 | </tr> |
| 217 | |
| 218 | <tr> |
| 219 | <th class="host">Windows</th> |
| 220 | <td class="doc"><a href="windows/none.md">✅</a></td> |
| 221 | <td class="doc">❌</td> |
| 222 | <td class="doc"><a href="windows/stunnel.md">✅</a></td> |
| @@ -258,10 +270,11 @@ | |
| 270 | "none", "inetd", "stunnel", "CGI", "SCGI", "althttpd", "proxy", "service" |
| 271 | ]; |
| 272 | const matrix = { |
| 273 | "any OS": [ YES, YES, YES, YES, YES, YES, NO, NO ], |
| 274 | "Debian or Ubuntu": [ IFA, IFA, IFA, IFA, IFA, IFA, "nginx", YES ], |
| 275 | "macOS": [ IFA, NO, IFA, IFA, IFA, IFA, NO, YES ], |
| 276 | "Windows": [ YES, NO, YES, YES, NO, NO, "IIS", NO ], |
| 277 | } |
| 278 | const osNames = Object.keys(matrix).sort((e) => { |
| 279 | return e.toLowerCase() |
| 280 | }).map((longName, i) => { |
| 281 | |
| 282 | DDED www/server/macos/service.md |
+122
| --- a/www/server/macos/service.md | ||
| +++ b/www/server/macos/service.md | ||
| @@ -0,0 +1,122 @@ | ||
| 1 | +# Serving via launchd on macOS | |
| 2 | + | |
| 3 | +[`launchd`][ldhome] is the default service management framework on macOS | |
| 4 | +[since the release of Tiger in 2005][wpa]. If you want a Fossil server | |
| 5 | +to launch in the background on a Mac, it’s the way Apple wants you to do | |
| 6 | +it. `launchd` is to macOS as `systemd` is to most modern Linux desktop | |
| 7 | +systems. (Indeed, `systemd` arguably reinvented the perfectly good, | |
| 8 | +pre-existing `launchd` wheel.) | |
| 9 | + | |
| 10 | +Unlike in [our `systemd` article](../debian/service.md), we’re not going | |
| 11 | +to show the per-user method here, because those so-called | |
| 12 | +[LaunchAgents][la] only start when a user is logged into the GUI, and | |
| 13 | +they stop when that user logs out. This does not strike us as proper | |
| 14 | +“server” behavior, so we’ll stick to system-level LaunchDaemons instead. | |
| 15 | + | |
| 16 | +However, we will still give two different configurations, just as in the | |
| 17 | +`systemd` article: one for a standalone HTTP server, and one using | |
| 18 | +socket activation. | |
| 19 | + | |
| 20 | +For more information on `launchd`, the single best ](launchd.inf.info). The next best is: | |
| 21 | + | |
| 22 | + $ man launchd.plist | |
| 23 | + | |
| 24 | +[la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/ | |
| 25 | +[ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html | |
| 26 | +[wpa]: https://en.wikipedia.org/wiki/Launchd | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | +## Standalone HTTP Server | |
| 31 | + | |
| 32 | +To configure `launchd` to start Fossil as a standalone HTTP server, | |
| 33 | +write the following as `com.example.dev. >WorkingDire | |
| 34 | +[`launchd`][ldhome] is t# Serving via launchd on /key> | |
| 35 | + <true/> | |
| 36 | + <dict> | |
| 37 | + <key>Labe <key>log</string> | |
| 38 | + <key>StandardHTTP</string> | |
| 39 | + ev.FossilHTTP</string> | |
| 40 | + <key>ring>/tmp/fossil-inf-info.log</string> | |
| 41 | + <# Serving via launchd on macOS | |
| 42 | + | |
| 43 | +[` <strin </array> | |
| 44 | + key>WorkingDirec <key>KeepAlive</key> | |
| 45 | + > | |
| 46 | + <key>KeepAeepAlive</key> | |
| 47 | + <true/> | |
| 48 | + > | |
| 49 | + <key>KeepA <key>S <string>/tmp/fossil-error.log</string> | |
| 50 | + /fossil-error.log</string> | |
| 51 | + <key <string>/tmp/fop/fossil-info.log</string> | |
| 52 | + # Serving via launchd on macOlaunchd on macOS | |
| 53 | + | |
| 54 | +[`launchd`]a launchd on macOS | |
| 55 | + | |
| 56 | +[`launchd`]es not strike us as proper | |
| 57 | +“> | |
| 58 | + <key>KeepAl/dict> | |
| 59 | + or, so we’ll stick to system-level LaunchDaemons instead. | |
| 60 | + | |
| 61 | +However, we will still give two different configurations, just as in the | |
| 62 | +`systemd` article: one for a standalone HTTP server, and one using | |
| 63 | +socket activation. | |
| 64 | + | |
| 65 | +For more information on `launchd`, the single best resource we’ve found | |
| 66 | +is [launchd.info](https://launchd.info). The next best is: | |
| 67 | + | |
| 68 | + $ man launchd.plist | |
| 69 | + | |
| 70 | +[la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/ | |
| 71 | +[ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html | |
| 72 | +[wpa]: https://en.wikipedia.org/wiki/Launchd | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | +## Standalone HTTP Server | |
| 77 | + | |
| 78 | +To configure `launchd` to start Fossil as a standalone HTTP server, | |
| 79 | +write the following as `com.example.dev.FossilHTTP.plist`:n macOS | |
| 80 | + | |
| 81 | +[`launchd`][ldhome] is the default service management framework on macOS | |
| 82 | +[s# S"http://www.apple.com/DT | |
| 83 | + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| 84 | +<plist version="1.0"> | |
| 85 | +<dict> | |
| 86 | + <key>Label</key> | |
| 87 | + <string>com.example.dev.FossilHTTP</string> | |
| 88 | + <key "http://www.apple.co<string>/usr/local/bin/fossil</string> | |
| 89 | + <string>server</string> | |
| 90 | + <string>--port</string> | |
| 91 | + <string>9000</string> | |
| 92 | + <string>repo.fossil</string> | |
| 93 | + </array> | |
| 94 | + <key>WorkingDirectory</key> | |
| 95 | + <string>/Users/you/museum</string> | |
| 96 | + <key>KeepAlive</key> | |
| 97 | + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| 98 | +<plist version="1.0"> | |
| 99 | +<dict> | |
| 100 | + <key>Label</key> | |
| 101 | + <string>com.example.dev.Fossil</string> | |
| 102 | + <key>StandardOutPath</key> | |
| 103 | + <string>/tmp/fossil-info.log</string> | |
| 104 | + <key>UserName</key> | |
| 105 | + <string>you</string> | |
| 106 | + <key>GroupName</key> | |
| 107 | + <string>staff</string> | |
| 108 | + <key>InitGroups</key> | |
| 109 | + <true/> | |
| 110 | +</dict> | |
| 111 | +</plist> | |
| 112 | +``` | |
| 113 | + | |
| 114 | +In this example, we’re assuming your development organization uses the | |
| 115 | +domain name “`dev.example.org`”, that your short macOS login name is | |
| 116 | +“`you`”, and that you store your Fossils in “`~/museum`”. Adjust these | |
| 117 | +elements of the plist file to suit your local situation. | |
| 118 | + | |
| 119 | +You might be wondering about the use of `UserName`: isn’t Fossil | |
| 120 | +supposed to drop privileges and enter [a `chroot(2)` | |
| 121 | +jail](../../chroot.md) when it’s started as root like this? Why do we | |
| 122 | +need |
| --- a/www/server/macos/service.md | |
| +++ b/www/server/macos/service.md | |
| @@ -0,0 +1,122 @@ | |
| --- a/www/server/macos/service.md | |
| +++ b/www/server/macos/service.md | |
| @@ -0,0 +1,122 @@ | |
| 1 | # Serving via launchd on macOS |
| 2 | |
| 3 | [`launchd`][ldhome] is the default service management framework on macOS |
| 4 | [since the release of Tiger in 2005][wpa]. If you want a Fossil server |
| 5 | to launch in the background on a Mac, it’s the way Apple wants you to do |
| 6 | it. `launchd` is to macOS as `systemd` is to most modern Linux desktop |
| 7 | systems. (Indeed, `systemd` arguably reinvented the perfectly good, |
| 8 | pre-existing `launchd` wheel.) |
| 9 | |
| 10 | Unlike in [our `systemd` article](../debian/service.md), we’re not going |
| 11 | to show the per-user method here, because those so-called |
| 12 | [LaunchAgents][la] only start when a user is logged into the GUI, and |
| 13 | they stop when that user logs out. This does not strike us as proper |
| 14 | “server” behavior, so we’ll stick to system-level LaunchDaemons instead. |
| 15 | |
| 16 | However, we will still give two different configurations, just as in the |
| 17 | `systemd` article: one for a standalone HTTP server, and one using |
| 18 | socket activation. |
| 19 | |
| 20 | For more information on `launchd`, the single best ](launchd.inf.info). The next best is: |
| 21 | |
| 22 | $ man launchd.plist |
| 23 | |
| 24 | [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/ |
| 25 | [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html |
| 26 | [wpa]: https://en.wikipedia.org/wiki/Launchd |
| 27 | |
| 28 | |
| 29 | |
| 30 | ## Standalone HTTP Server |
| 31 | |
| 32 | To configure `launchd` to start Fossil as a standalone HTTP server, |
| 33 | write the following as `com.example.dev. >WorkingDire |
| 34 | [`launchd`][ldhome] is t# Serving via launchd on /key> |
| 35 | <true/> |
| 36 | <dict> |
| 37 | <key>Labe <key>log</string> |
| 38 | <key>StandardHTTP</string> |
| 39 | ev.FossilHTTP</string> |
| 40 | <key>ring>/tmp/fossil-inf-info.log</string> |
| 41 | <# Serving via launchd on macOS |
| 42 | |
| 43 | [` <strin </array> |
| 44 | key>WorkingDirec <key>KeepAlive</key> |
| 45 | > |
| 46 | <key>KeepAeepAlive</key> |
| 47 | <true/> |
| 48 | > |
| 49 | <key>KeepA <key>S <string>/tmp/fossil-error.log</string> |
| 50 | /fossil-error.log</string> |
| 51 | <key <string>/tmp/fop/fossil-info.log</string> |
| 52 | # Serving via launchd on macOlaunchd on macOS |
| 53 | |
| 54 | [`launchd`]a launchd on macOS |
| 55 | |
| 56 | [`launchd`]es not strike us as proper |
| 57 | “> |
| 58 | <key>KeepAl/dict> |
| 59 | or, so we’ll stick to system-level LaunchDaemons instead. |
| 60 | |
| 61 | However, we will still give two different configurations, just as in the |
| 62 | `systemd` article: one for a standalone HTTP server, and one using |
| 63 | socket activation. |
| 64 | |
| 65 | For more information on `launchd`, the single best resource we’ve found |
| 66 | is [launchd.info](https://launchd.info). The next best is: |
| 67 | |
| 68 | $ man launchd.plist |
| 69 | |
| 70 | [la]: http://www.grivet-tools.com/blog/2014/launchdaemons-vs-launchagents/ |
| 71 | [ldhome]: https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html |
| 72 | [wpa]: https://en.wikipedia.org/wiki/Launchd |
| 73 | |
| 74 | |
| 75 | |
| 76 | ## Standalone HTTP Server |
| 77 | |
| 78 | To configure `launchd` to start Fossil as a standalone HTTP server, |
| 79 | write the following as `com.example.dev.FossilHTTP.plist`:n macOS |
| 80 | |
| 81 | [`launchd`][ldhome] is the default service management framework on macOS |
| 82 | [s# S"http://www.apple.com/DT |
| 83 | "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 84 | <plist version="1.0"> |
| 85 | <dict> |
| 86 | <key>Label</key> |
| 87 | <string>com.example.dev.FossilHTTP</string> |
| 88 | <key "http://www.apple.co<string>/usr/local/bin/fossil</string> |
| 89 | <string>server</string> |
| 90 | <string>--port</string> |
| 91 | <string>9000</string> |
| 92 | <string>repo.fossil</string> |
| 93 | </array> |
| 94 | <key>WorkingDirectory</key> |
| 95 | <string>/Users/you/museum</string> |
| 96 | <key>KeepAlive</key> |
| 97 | "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 98 | <plist version="1.0"> |
| 99 | <dict> |
| 100 | <key>Label</key> |
| 101 | <string>com.example.dev.Fossil</string> |
| 102 | <key>StandardOutPath</key> |
| 103 | <string>/tmp/fossil-info.log</string> |
| 104 | <key>UserName</key> |
| 105 | <string>you</string> |
| 106 | <key>GroupName</key> |
| 107 | <string>staff</string> |
| 108 | <key>InitGroups</key> |
| 109 | <true/> |
| 110 | </dict> |
| 111 | </plist> |
| 112 | ``` |
| 113 | |
| 114 | In this example, we’re assuming your development organization uses the |
| 115 | domain name “`dev.example.org`”, that your short macOS login name is |
| 116 | “`you`”, and that you store your Fossils in “`~/museum`”. Adjust these |
| 117 | elements of the plist file to suit your local situation. |
| 118 | |
| 119 | You might be wondering about the use of `UserName`: isn’t Fossil |
| 120 | supposed to drop privileges and enter [a `chroot(2)` |
| 121 | jail](../../chroot.md) when it’s started as root like this? Why do we |
| 122 | need |