Install Trigger Client on macOS

macOS 12 (Monterey) or newer, Intel / Apple Silicon

Application location: /opt/trigger_cl

1 Deploy the Trigger Client to /opt/trigger_cl

Create the install directory, copy the binary and config.ini into it, and mark the executable runnable. launchd will launch it from exactly this path.


sudo mkdir -p /opt/trigger_cl
sudo cp trigger_cl config.ini /opt/trigger_cl/
sudo chmod +x /opt/trigger_cl/trigger_cl
    
2 Point the client at the server

Edit config.ini and fill in the [server] section. These two lines are the only required change before first start.


sudo nano /opt/trigger_cl/config.ini

# in section [server] set
ip = trigger.itperfectservice.com
port = 9000
    
3 Generate the device key

Export a per-host key file and print the matching key string. Both are needed to pair this machine with the mobile app.


sudo /opt/trigger_cl/trigger_cl --export-bin /opt/trigger_cl/key.bin
sudo /opt/trigger_cl/trigger_cl --show-key
    
4 Register the key on your Android device

Hand the key material to your phone: the binary file onto the device, the printed string into your account. From now on the phone can issue commands to this host.

  1. Copy key.bin to your Android device.
  2. In the Trigger mobile app, add it under your account.
  3. Save the printed KEY-XXXXXXXXXXXXX string — it identifies this host in the mobile UI.
5 Install the LaunchDaemon plist

Write the launchd plist that keeps the binary alive at boot. root:wheel ownership and mode 644 are what launchctl requires before it will load a system daemon.


sudo tee /Library/LaunchDaemons/com.trigger.cl.plist > /dev/null <<'EOF'
<?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>com.trigger.cl</string>

  <key>ProgramArguments</key>
  <array>
    <string>/opt/trigger_cl/trigger_cl</string>
  </array>

  <key>WorkingDirectory</key>
  <string>/opt/trigger_cl</string>

  <key>RunAtLoad</key>
  <true/>

  <key>KeepAlive</key>
  <true/>

  <key>ThrottleInterval</key>
  <integer>10</integer>

  <key>StandardOutPath</key>
  <string>/var/log/trigger_cl.log</string>

  <key>StandardErrorPath</key>
  <string>/var/log/trigger_cl.log</string>
</dict>
</plist>
EOF
sudo chown root:wheel /Library/LaunchDaemons/com.trigger.cl.plist
sudo chmod 644 /Library/LaunchDaemons/com.trigger.cl.plist
    
6 Load the daemon

launchctl bootstrap registers the plist in the system domain and starts the daemon immediately. KeepAlive takes over from there and restarts it if it exits.


sudo launchctl bootstrap system /Library/LaunchDaemons/com.trigger.cl.plist
    
7 Verify it is running

launchctl list shows the loaded label with its PID and last exit status. The log file aggregates stdout and stderr for both normal output and crashes.


sudo launchctl list | grep trigger
sudo tail -f /var/log/trigger_cl.log
    
8 Managing the daemon later

These three commands cover the whole lifecycle: restart, stop/unload, load/start. launchd has no systemctl restart equivalent — kickstart -k is the idiomatic way to bounce it.

sudo launchctl kickstart -k system/com.trigger.cl   # restart
sudo launchctl bootout   system/com.trigger.cl   # stop & unload
sudo launchctl bootstrap system /Library/LaunchDaemons/com.trigger.cl.plist   # load & start