It looks like brew doesn't support running "launch daemons" - it can only manage "launch agents" (this Apple documentation delves a bit into the difference between "agents" and "daemons", though - like most official Apple documentation - falls short of an actual spec), which means either run on boot as root or run on user login as a user.
But there is a way to have services running on boot as a user. I've solved my problem by:
- Run
brew services start gitlab-runner (without sudo) to cause brew to generate the ~/Library/LaunchAgents/homebrew.mxcl.gitlab-runner.plist file that defines the service. - Stop the service (
brew services stop gitlab-runner) - Move the file to
/Library/LaunchDaemons/homebrew.mxcl.gitlab-runner.plist - Edit the plist file to add the
UserName key:
<key>UserName</key> <string>myuser</string>
- Change ownership of the file to be owned by
root (otherwise Launchd won't start it): chown root /Library/LaunchDaemons/homebrew.mxcl.gitlab-runner.plist - reboot
The service would now start on boot and run under the user account specified in the daemon plist file.
Sample Use Case
In my use case, I'm using AWS mac1.metal "VM" to run the Gitlab runner, and I'm setting up the init script by setting the EC2 "user data" field to a bash script that can set up the Gitlab runner and start it automatically, and it looks something like this:
#!/bin/bash GITLAB_TOKEN=GET_THE_CI_TOKEN_FROM_SOMEWHERE # this script runs as root, so to use brew we need to run # a script as ec2-user: cat > /usr/local/bin/setup-ci.sh <<<'#!/bin/bash -x source .bash_profile brew upgrade brew update --auto-update brew install rbenv gitlab-runner rbenv init - bash >> .bash_profile source .bash_profile rbenv install 2.7.4 rbenv global 2.7.4 brew services start gitlab-runner sleep 10 # let the service settle before registering gitlab-runner register --non-interactive --url https://gitlab.com --registration-token "'"${GITLAB_TOKEN}"'" --executor shell --name mac-gitlab-runner --tag-list macos,ios --shell bash sleep 3 cat /Users/ec2-user/.gitlab-runner/config.toml # for debugging # update the plist file perl -lpe "m,RunAtLoad, and print \"\t<key>UserName</key><string>ec2-user</string>\"" ~/Library/LaunchAgents/homebrew.mxcl.gitlab-runner.plist > homebrew.mxcl.gitlab-runner.plist sudo mv homebrew.mxcl.gitlab-runner.plist /Library/LaunchDaemons/homebrew.mxcl.gitlab-runner.plist sudo /usr/sbin/chown root /Library/LaunchDaemons/homebrew.mxcl.gitlab-runner.plist # Try to stop service - it sometimes "fails", but we dont care about that brew services stop gitlab-runner || true ' chmod 755 /usr/local/bin/setup-ci.sh su - ec2-user -c /usr/local/bin/setup-ci.sh
After the launch complete, I reboot the EC2 instance and Gitlab runner comes up automatically, running as the ec2-user.