On macOS I have several servers set up to run via a user account called "server". From my main user account, I can start them manually with the following commands, one after the other, and everything works fine, after first issuing su server:
nginx
httpd
tmux new -d -s navidrome 'cd ~/server/navidrome/ && ./navidrome'
In order to make everything start at boot with the correct user, I created a shell script containing the exact same commands above (except su server), set chmod +x and added it to launchctl with this .plist file saved in /Library/LaunchDaemons:
<?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>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:</string>
</dict>
<key>Label</key>
<string>com.startup</string>
<key>Program</key>
<string>/Users/server/server/scripts/server-startup.sh</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>LaunchOnlyOnce</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/server-startup.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/server-startup.stderr</string>
<key>UserName</key>
<string>server</string>
<key>GroupName</key>
<string>staff</string>
<key>InitGroups</key>
<true/>
</dict>
</plist>
When I boot the machine and log into my main user account, I can see all relevant processes in Activity Monitor, running as the correct "server" user. However, I'm getting permission issues (AH00132 in Apache, and access errors in the navidrome log), which I do not get when starting them manually.
All errors are identical in the log:
[Sat May 13 16:20:47.606359 2023] [core:error] [pid 400] (1)Operation not permitted: [client 192.168.1.2:49683] AH00132: file permissions deny server access: /Volumes/myvolume/etc
If, still from my main account, I su into the "server" account and issue e.g. httpd -k stop and then httpd (similarly for the other servers), everything is behaving normally again.
All the errors refer to a folder on an external USB volume of which "server" is the owner (I ran chown -R server /Volumes/volume/folder on it), and which doesn't give any errors when launching the servers manually.
I know most of this can be handled differently by adding everything to launchctl but I'd like to know the reason for why this isn't working. What is missing from the script in order to make it run the commands as the "server" user, exactly as if I was running it from the Terminal?