Picture of Brian Love wearing black against a dark wall in Portland, OR.

Brian Love

Learning Nginx on OS X

In this post I am going to take a quick dive into the Nginx web server.

I have long been a big fan of Apache’s HTTP web server. It’s powerful, versatile, and free. For the most part, the website that I have worked on are not mega websites, so I have never run into performance issues using Apache (or IIS for that matter). However, I still wanted to play with nginx. What is it? It’s a web server, and much more:

Nginx (pronounced engine-x) is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server.

So, let’s dive in…

Installing Nginx on OS X

The easiest way to install nginx on OS X is to use homebrew.

$ brew update
$ brew install nginx

Well, that was easy. :)

Starting Nginx

This is also just as easy as the installation. Just run the nginx command (with no options) as root.

$ sudo nginx

You can also use the following commands to tell nginx to stop or reload:

$ sudo nginx -s stop
$ sudo nginx -s reload

So, where is everything?

Here is a quick rundown of the default paths:

After starting nginx we can make sure it is working by loading the default page. The server listens on port 8080 by default, so browse to http://localhost:8080 and you should see the screen shot below.

Screenshot showing Nginx welcome page

Change Webroot and Port

The first thing I wanted to do was to update the webroot and the listening port of nginx. To do this we need to modify the nginx.conf file and reload the server.

http {
  ...

  server {
    listen 80;
    server_name  localhost;

    location / {
      root /www;
      
}

Here are the most important settings to understand first:

Restart nginx and then load up http://localhost in the browser.

Virtual Host

OK, now that we have localhost running, what about setting up multiple virtual hosts in nginx. Here is an example from the Nginx primer written by Martin Fjordvald.

server {
  listen          80;
  server_name     domain.com *.domain.com;
  return          301 $scheme://www.domain.com$request_uri;
}

server {
  listen          80;
  server_name     www.domain.com;

  index           index.html;
  root            /home/domain.com;
}

Here, Martin is defining two servers:

Also we should note the two variables that Martin used:

You can view a full list of variables in the nginx documentation.

html > server > location

One important thing to understand is that all configuration is inherited in this way: html > server > location. This also means that any configuration value set at the location level will take precedence over the value set in the server or html block.

In general I think of the request cycle as follows.

Directory Listing

When I first loaded up a directory without an index file (such as index.html) in my browser, I received a 403 Forbidden error.

Screenshot showing Nginx 403 Forbidden

The reason for the 403 error is that nginx doesn’t have access to the file index.html, well, since it doesn’t exist. Which, is a bit confusing.

Why doesn’t nginx return a 404? Well, it’s because the default server configuration doesn’t specify to show a 404. We can simply uncomment the following line to do an internal proxy to the /404.html file.

error_page  404  /404.html

In my case, to get started, I wanted to simply allow nginx to show a directory listing of the files in my webroot. To do this, I just added the autoindex on configuration to the root location.

location / {
  autoindex on
}

Now when I fire up http://localhost I can see a listing of all my files.

Screenshot showing directory index listing

Well, that’s it for now. Next step will be to set up a revere proxy to server PHP files via fastcgi and setting up search engine friendly URLs.