Configuring a LaunchDaemon for a server process

I've developed a specialized web server in Swift using Vapor. I want to set it up to run reliably on macOS using a LaunchDaemon. It should start at boot and be restarted if it crashes. I'm having trouble finding a good guide to the latest flavor of launchctl, and how to use system domains.

This is my plist:

<?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>Debug</key>
	<true/>
	<key>Label</key>
	<string>com.latencyzero.FurnaceController</string>
	<key>Program</key>
	<string>/Users/rmann/Desktop/Run</string>
	<key>ProgramArguments</key>
	<array>
		<string>serve</string>
		<string>--hostname</string>
		<string>0.0.0.0</string>
		<string>--port</string>
		<string>80</string>
	</array>
	<key>KeepAlive</key>
	<true/>
	<key>Listeners</key>
	<dict>
		<key>SockServiceName</key>
		<string>http</string>
		<key>SockType</key>
		<string>tcp</string>
		<key>SockFamily</key>
		<string>IPv4</string>
	</dict>
</dict>
</plist>

And I'm trying to invoke it like this:

$ sudo enable system/com.latencyzero.FurnaceController

But nothing happens. If I try kickstart, I get an error:

$ sudo launchctl kickstart -p system/com.latencyzero.FurnaceController
Could not find service "com.latencyzero.FurnaceController" in domain for system
$ sudo launchctl kickstart -p uid/501/com.latencyzero.FurnaceController
Unrecognized target specifier.
Usage: launchctl kickstart [-k] [-p] <service-target>
        -k      Terminates the service if it is already running.
        -p      Prints the PID of the service that was started.
        -s      Starts the service suspended so that a debugger may attach.
<service-target> takes a form of <domain-target>/<service-id>.
Please refer to `man launchctl` for explanation of the <domain-target> specifiers.

Bootstrap also doesn't work as I'd expect:

$ sudo launchctl bootstrap system/com.latencyzero.FurnaceController
Usage: launchctl bootstrap <domain-target> [service-path, service-path2, ...]
<service-target> takes a form of <domain-target>/<service-id>.
Please refer to `man launchctl` for explanation of the <domain-target> specifiers.

The plist is in /Library/LaunchDaemons/com.latencyzero.FurnaceController.plist

I'd rather not have to launch this in a user domain, as I'm handing this app off to my client, and the fewer customization needed, the better.

Do you want your launchd daemon to launch on demand? That is:

  • The daemon is not running most of the time.

  • launchd monitors the daemon’s listener sockets on its behalf.

  • When a connection comes in, launchd launches the daemon.

  • The daemon checks in with launchd, starts monitoring the listening sockets for connections, immediately sees the connection that triggered the launch, and starts handling it.

This is the approach we recommend but it requires that your daemon be written to check in with launchd.


I'd rather not have to launch this in a user domain, as I'm handing this app off to my client, and the fewer customization needed, the better.

Have you look at the SMAppService API, new in macOS 13 beta?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Configuring a LaunchDaemon for a server process
 
 
Q