Running homebrewed Nginx with sudo and launchctl on MacOS X
Sometimes we need to run nginx server on the 80 port, but this can be possible only if run it with root privileges.
Updated on 9 January 2013 by Jim Cushing, jimothy [at] mac.com
Instead of moving the nginx bin and creating a shell-script to wrap nginx with sudo command we are able to keep nginx binary in place and use next .plist to start/stop it:
<?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>homebrew.mxcl.nginx</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/opt/nginx/sbin/nginx</string>
<string>-g</string>
<string>daemon off;</string>
</array>
<key>WorkingDirectory</key>
<string>/usr/local</string>
</dict>
</plist>
This is basically the stock Homebrew launch agent plist for Nginx, but I removed the “UserName” so it will run as root. I also put it in /Library/LaunchAgents/
(or in /Library/LaunchDaemons/
) rather than ~/Library/LaunchAgents/
.
I can start and stop nginx with launchctl now.
It turns out the need for the shell script was because of the Homebrew plist didn’t include “daemon off;”.
Here is the previous version of this little how-to
Root privileges we can get with the sudo
command.
This tip will work only if you configured your sudo command to prevent asking password for your user (or if you can configure it to prevent asking password only for next commands).
First of we need to rename original nginx
binary in /usr/local/Cellar/nginx/ve.rs.ion/sbin
directory to something like nginx_bin
:
$ cd /usr/local/Cellar/nginx/ve.rs.ion/sbin
$ mv nginx nginx_bin
Then we need to create bash script with the nginx
name in the sbin
directory:
$ vim nginx
# ... put contents in it (showed below)
$ chmod +x nginx
and put this content in it (change ‘ve.rs.ion’ with your nginx installed version):
#!/bin/bash
NGINX_BIN="/usr/local/Cellar/nginx/ve.rs.ion/sbin/nginx_bin"
function on_die() {
sudo $NGINX_BIN -s stop
exit 0
}
trap on_die TERM
sudo $NGINX_BIN $@ &
wait
Another thing we need to do is add daemon off;
string to nginx.conf file (placed in /usr/local/etc/nginx directory
). You can place it on the top of this file.
Next we can use next .plist
file, which you need to put into ~/Library/LaunchAgents/org.nginx.plist
file (don’t forget to replace ve.rs.ion
with your installed version number):
<?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>org.nginx</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/Cellar/nginx/ve.rs.ion/sbin/nginx</string>
</array>
<key>WorkingDirectory</key>
<string>/usr/local</string>
</dict>
</plist>
That’s all!
Now you can use launchctl
utility to load/unload your nginx server:
$ launchctl load -w ~/Library/LaunchAgents/org.nginx.plist
$ launchctl unload -w ~/Library/LaunchAgents/org.nginx.plist