This guide explains how to configure nginx through a series of examples I’ve encountered. Links to the nginx docs are provided if you’d like to read more.
The location and structure of the nginx config files may vary depending on how you installed nginx. The main config file should typically be /etc/nginx/nginx.conf
, but usually you won’t need to modify that file. Instead, you should use a folder of site config files (often /etc/nginx/sites-enabled/
) to isolate per-website configuration from the main nginx config, even if you’re only using nginx to host a single website. You can find this for your installation by looking for a line inside the http {
block in nginx.conf
that looks like:
include /etc/nginx/sites-enabled/*;
In the following sections, each config sample that starts with server {
represents the contents of a file in that site config folder. You can name site config files however you want, and they conventionally end with .conf
.
server {
listen 80;
server_name example.com;
root /var/www/example;
}
This will serve the contents of the folder /var/www/example
in response to requests for example.com
. For instance, requesting http://example.com/path/to/page.html
will return the contents of /var/www/example/path/to/page.html
, or an error page if the file doesn’t exist.
There are a variety of options you can add to change this behavior, if you’d like:
The listen
option sets the port of the server, but it can also be used to bind to a specific address and/or enable IPv6; see the listen documentation for details.
To make nginx serve multiple websites from one installation, you can add more server {
blocks (optionally in different files) as long as each of them has a different server_name
so nginx can tell them apart. You can specify multiple server_name
s at once and even use wildcards; see the server_name documentation for details.
server {
listen 80;
server_name nkorth.com;
root /var/www/nkorth;
index index.html index.htm;
location = /favicon.ico {
log_not_found off;
}
location / {
autoindex on;
}
location /cgi-bin/ {
gzip off;
index index.py index.html index.htm;
}
location /projects/ {
alias /var/www/proj;
autoindex on;
}
}
Use location
blocks to change the configuration for different paths in a website. Nginx finds the most specific (longest) location block that matches the requested path, and its contents will override any duplicate configuration options in the enclosing server
block (eg. index
in the above example.) See the location docs for more details including regular expression matching.
Explanation of each block:
location = favicon.ico
=
before the match string causes the location block to match only the exact path /favicon.ico
, instead of matching all paths that start with it. Using =
when possible can speed up complex configs, because nginx can stop there if it matches instead of checking every location for the longest match.location /
autoindex on
in the server block instead of using a location block, but then I would have to add autoindex off
to override it in other location blocks. This way, I can just put autoindex on
in only the blocks that need autoindex.location /cgi-bin/
index
option from the server block. (Note that this isn’t a complete cgi-bin config; see below for a complete example.)location /projects/
alias
option here is related to root
, but can only be used inside a location block. Use it when you have a folder name that doesn’t match the URL you want.root
, the full URL path is appended to the root
value to determine the file path. Eg. if I used root
instead of alias
here, when requesting /projects/thing.txt
the file path would be /var/www/proj/projects/thing.txt
.alias
, only the path after the location match is appended to the value of alias
to determine the file path. Eg. when requesting /projects/thing.txt
, the file path is /var/www/proj/thing.txt
.server {
listen 80;
server_name www.example.com;
location / {
return 301 $scheme://example.com$request_uri;
}
}
(todo)
location /netbox/ {
proxy_pass http://localhost:8002/netbox/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 512M;
}
location /netbox/static/ {
alias /mnt/apps/netbox/static/;
access_log off;
expires 2w;
}
location /netbox/media/ {
alias /mnt/apps/netbox/media/;
access_log off;
expires 2w;
}
This is an example of reverse proxying a Django app. Follow the deployment instructions for your web app, then use proxy_pass
to point nginx at its local server so you can host it in a subdirectory of your website. In this case, the Django WSGI server doesn’t handle static files (and nginx can do it faster anyway); in this case use more location blocks with root
or alias
as needed.
server {
listen 80;
server_name netbox.nkorth.com;
location / {
proxy_pass http://localhost:8002/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
client_max_body_size 512M;
}
location /static/ {
alias /mnt/apps/netbox/static/;
access_log off;
expires 2w;
}
location /media/ {
alias /mnt/apps/netbox/media/;
access_log off;
expires 2w;
}
}
If you want to host your web app on a subdomain but you only have one IP address, you can reverse proxy it through your existing nginx server using a config like this example. Just like any other server
block, nginx will use the server_name
to distinguish it from your other websites.
location /cgi-bin/ {
alias /var/www/cgi-bin;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_filename;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
You’ll need to install fcgiwrap. The paths /var/run/fcgiwrap.socket
and /etc/nginx/fastcgi_params
correspond to its defaults from the Ubuntu/Debian package.
Enabling fastcgi_intercept_errors
causes nginx to handle 4xx and 5xx errors.
If your scripts need partial output (eg. for progress bars), add gzip off
and fastcgi_buffering off
.