How do I start nginx on port 80 at OS X login?

24,020

Solution 1

I found an easier approach was to create add plist file in /Library/LaunchDaemons/

sudo vi /Library/LaunchDaemons/org.nginx.nginx.plist

Or, if you want it to launch on login, you can put it in ~/Library/LaunchAgents/, the same plist file. This will allow you to access the launchd launchctl command from your username without the need to call sudo.

and insert the following (be sure to update the path to your nginx install, and the username to your username):

<?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>nginx</string>
    <key>Program</key>
    <string>/usr/local/Cellar/nginx/1.6.2/bin/nginx</string>
    <key>KeepAlive</key>
    <true/>
    <key>NetworkState</key>
    <true/>
    <key>LaunchOnlyOnce</key>
    <true/>
    <key>UserName</key>
    <string>yourusername</string>
</dict>
</plist>

Solution 2

I got here because I was running into the same problem. My solution was similar to Rich's above, except I used the Homebrew nginx startup script:

sudo cp /usr/local/opt/nginx/homebrew.mxcl.nginx.plist /Library/LaunchDaemons/

For reference, here is what that homebrew.mxcl.nginx.plist looks like:

<?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>UserName</key>
    <string>root</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/sbin/nginx</string>
    </array>
    <key>WorkingDirectory</key>
    <string>/usr/local</string>
  </dict>
</plist>

I have 2 aliases added to my $HOME/.profile for making it easier to start and stop nginx.

# Nginx needs to bind to port 80 so must run as /Library/LaunchDaemon with sudo
alias start-nginx='sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.nginx.plist'
alias stop-nginx='sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.nginx.plist'

My problem was that for some reason nginx wasn't starting up properly initially. I just had to run the stop-nginx to unload it, and then re-start it again with start-nginx.

Solution 3

Not an exact answer to your question, but might come close enough: you can redirect port 80 to port 8080, using the packetfilter pf (tested on OS X 10.9). Add the following line to your /etc/pf.conf (it should come above the filtering rules):

rdr pass on lo0 inet proto tcp from any to any port http -> localhost port 8080

An explanation of (most of) the elements of this line can be found here.

For more information, see https://superuser.com/a/521803 and http://www.openbsd.org/faq/pf/index.html, though the latter seems to describe a newer version of pf, in which the given line would be written differently.

Solution 4

I took inspiration from the Pow server and made a plist that sets up port forwarding. It forwards port 80 to port 8080, and port 443 to port 8443. This way I can run nginx under a normal user, and all my connections transparently work.

The plist is here: https://gist.github.com/stefansundin/f0ad99195333480157ce67e97c8d28c7

Share:
24,020

Related videos on Youtube

Bryson
Author by

Bryson

Updated on September 18, 2022

Comments

  • Bryson
    Bryson over 1 year

    I installed Nginx using homebrew and after completing the installation the following message was displayed:

    In the interest of allowing you to run `nginx` without `sudo`, the default
    port is set to localhost:8080.
    
    If you want to host pages on your local machine to the public, you should
    change that to localhost:80, and run `sudo nginx`. You'll need to turn off
    any other web servers running port 80, of course.
    
    You can start nginx automatically on login running as your user with:
      mkdir -p ~/Library/LaunchAgents
      cp #{prefix}/org.nginx.nginx.plist ~/Library/LaunchAgents/
      launchctl load -w ~/Library/LaunchAgents/org.nginx.nginx.plist
    
    Though note that if running as your user, the launch agent will fail if you
    try to use a port below 1024 (such as http's default of 80.)
    

    But I want Nginx, on port 80, running at login and I don't want to have to open terminal and type in sudo nginx to do it. I want it to load from a plist file like Redis and PostgreSQL do.

    I moved the plist to /Library/LaunchAgents/ from the user folder equivalent and changed its ownership, also tried setting the user directive in the nginx.conf file and still the same error message in Console.app:

    nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

    (along with another message telling me that since nginx was being run without super-user privileges, the user directive was being ignored)

    • risyasin
      risyasin over 9 years
      Be sure your plist file has "root:wheel" ownership when you move it in any of LaunchDaemons folders. otherwise launchctl won't run it beacuse of "dubious ownership".
  • Spiff
    Spiff about 12 years
    This is a useful answer, but technically it starts nginx at boot, not login. If @Bryson really only wants it running after he logs into a certain GUI account, then this is not quite the right answer. But I suspect he really wants it running as soon as the machine has booted, even if the GUI is waiting at Login Window, rather than waiting until he actually logs in.
  • Andrei
    Andrei about 11 years
    Alternative: lunchy restart nginx, see github.com/mperham/lunchy
  • hobbes3
    hobbes3 about 11 years
    I added it to ~/Library/LaunchAgents/ and I get the following errors in Console: 3/30/13 9:39:24.047 AM com.apple.launchd.peruser.501[884]: (nginx) Unknown key for boolean: NetworkState 3/30/13 9:39:24.047 AM com.apple.launchd.peruser.501[884]: (nginx) Ignored this key: UserName 3/30/13 9:39:24.047 AM com.apple.launchd.peruser.501[884]: (nginx) Ignored this key: UserName. I changed Program string to /usr/local/Cellar/nginx/1.2.7/sbin/nginx if that matters.
  • hobbes3
    hobbes3 about 11 years
    Actually I just took the original homebrew.mxcl.nginx.plist, changed UserName to root, then sudo chown root, and ran sudo launchctl load -w and it worked.
  • Pitarou
    Pitarou about 10 years
    Can I just check -- you have a .plist in ~/Library/LaunchAgents/ (so it's for one user only), but it starts as root? I've never seen that possibility mentioned in the documentation, and when I tried it on Mavericks it failed.
  • getWeberForStackExchange
    getWeberForStackExchange over 9 years
    @hobbes3 @rich-kroll Almost a year later but KeepAlive can either be true, or set to a dict that contains NetworkState. So the example above should say <key>KeepAlive</key><dict><key>NetworkState</key><true/></di‌​ct> (note that I replaced KeepAlive's true with the dictionary containing NetworkState). Source: developer.apple.com/library/mac/documentation/Darwin/Referen‌​ce/…