NGINX

Installation

  • Ubuntu: sudo apt-get install nginx (likely already installed)

Configuration

Nginx config is similar to that of Apache in that you specify the setup using a collection of directives that provide certain contexts.

One important thing to note is that the entire Nginx server config begins with the /etc/nginx/nginx.conf file. This basically means that, as you add virtual hosts, your configurations will essentially be appended to this base config file. Nginx also make use of an “include”-like functionality for importing components from certain files, encouraging separated configs where possible.

Basic Virtual Host Config

# could be any virtual host config file in /etc/nginx/sites-available/

# ('server' is actual syntax used here)
server {
    # specify port to listen on
    listen 8000;
    listen [::]:8000; # for IPv6 addresses

    server_name www.example.com; # defaults to all addresses

    root /usr/share/nginx/html; # default HTML root location
    index index.html; # index file to server by default
    
    # specifies how nginx should serve files
    # location directive matches all urls (unless overloaded later)
    location / {
        # try matching given uri (at root dir) and serving matching file
        # if no file is found, try serving a directory with the uri name
        # if this fails, finally return a 404 Not Found page
        try_files $uri $uri/ =404;
    }
}

Basic Reverse Proxy Config (gunicorn WSGI)

# uses standard virtual host config, but defines separate "upstream" directive
# for app to be proxied, and filters out non-matching hostnames (explicit to allow
# for 444, otherwise not needed)

# defines reverse proxy app settings (for use later)
upstream app {
    # unix domain socket setups
    server unix:/path/to/socket.sock;

    # for TCP config
    server 192.168.1.9:8000; # or localhost
}

server {
    # match any host that was not picked up by another directive, prevents spoofing
    listen 80 default_server;
    return 444;
}

server {
    listen 80;
    server_name example.com;

    # set path for static files
    root /path/to/static/files;

    # match static files if available, else proxy app
    location / {
        try_files $uri @proxy_app
    }

    location @proxy_app {
        # proxy host is preserved by default
        proxy_redirect off;

        # this set of headers replicates necessary ProxyPassReverse functionality
        # that is, ensures redirects at proxy are mapped to proper public URL
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # imitate Apache ProxyPreserveHost
        proxy_set_header Host $host;

        # proxy request to app
        proxy_pass http://app;
        # can also specify IP:port of proxy server directly
        # proxy_pass http://127.0.0.1:5000
        # and same with unix sockets
    }
}

Rewrite Rules

# REDIRECT RULES
RedirectMatch ^/$ https://samgriesemer.com
RedirectMatch ^/nn$ https://samgriesemer.com/projects/nn
RedirectMatch ^/r$ https://samgriesemer.com/static/research/files/avme.pdf

Activating Virtual Hosts

Nginx does not have a command like Apache’s a2enmod for enabling sites. You simply create a symlink betwen your config file in the sites-available/ folder and sites-enabled/ folder: ln -s /etc/nginx/sites-available/<host>.conf /etc/nginx/sites-enabled/ (make sure to use full absolute paths!)

Additional Commands

  • Test config syntax: sudo nginx -t
  • Restart server: sudo service nginx restart
  • Nginx access log files: cat /var/log/nginx/access.log
  • To send the host information (similar to proxy_preserve_host from Apache), we can set proxy_set_header Host $host;. However there is no reason to do this explicitly unless necessary, as it’s the default.
  • server_name or no specified server_name will result in Nginx matching the first directive in the config file