nginx

Updated: 29 January 2025

Before getting started you’ll need to install nginx which can be done on the nginx website. Additionally these notes mostly take a walk through the beginner’s guide as well as this NGINX Crash Course

Overview

nginx is an HTTP web server, reverse proxy, and a bunch of other related technologies

nginx consists of a single masster process and serveral workers. The master processs reads configuration and manages worker processes. The root nginx config is named nginx.conf and can be found in one of the default config directories

You can see the help menu using:

Terminal window
1
nginx -h

Basic lifecycle commands

If you run into issues with some of the nginx commands try running them with sudo

Starting and stopping the nginx service (this depends on your installation)

Terminal window
1
brew services start nginx # start nginx service
2
3
brew services stop nginx # stop nginx service
4
5
brew services restart nginx # restart nginx service

And some other basic commands for interacting with nginx using the nginx installation:

Terminal window
1
nginx -s stop # fast shutdown
2
3
nginx -s quit # graceful shutdown
4
5
nginx -s reload # reload config
6
7
nginx -s reopen # reopen log files

Config file

The nginx config consists of modules that are controlled by directives. Directives can be a semicolon or block delimited. Some block directives can have other blocks within them, these are called contexts. Any directive placed outside of a context are considered to be within the main context

You should be able to find the link to the default config file by doing nginx -h and looking at the -c option’s description

Comments use #

The default config looks like this:

nginx.conf

1
#user nobody;
2
worker_processes 1;
3
4
#error_log logs/error.log;
5
#error_log logs/error.log notice;
6
#error_log logs/error.log info;
7
8
#pid logs/nginx.pid;
9
10
11
events {
12
worker_connections 1024;
13
}
14
15
16
http {
17
include mime.types;
18
default_type application/octet-stream;
19
20
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
21
# '$status $body_bytes_sent "$http_referer" '
22
# '"$http_user_agent" "$http_x_forwarded_for"';
23
24
#access_log logs/access.log main;
25
26
sendfile on;
27
#tcp_nopush on;
28
29
#keepalive_timeout 0;
30
keepalive_timeout 65;
31
32
#gzip on;
33
34
server {
35
listen 8080;
36
server_name localhost;
37
38
#charset koi8-r;
39
40
#access_log logs/host.access.log main;
41
42
location / {
43
root html;
44
index index.html index.htm;
45
}
46
47
#error_page 404 /404.html;
48
49
# redirect server error pages to the static page /50x.html
50
#
51
error_page 500 502 503 504 /50x.html;
52
location = /50x.html {
53
root html;
54
}
55
56
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
57
#
58
#location ~ \.php$ {
59
# proxy_pass http://127.0.0.1;
60
#}
61
62
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
63
#
64
#location ~ \.php$ {
65
# root html;
66
# fastcgi_pass 127.0.0.1:9000;
67
# fastcgi_index index.php;
68
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
69
# include fastcgi_params;
70
#}
71
72
# deny access to .htaccess files, if Apache's document root
73
# concurs with nginx's one
74
#
75
#location ~ /\.ht {
76
# deny all;
77
#}
78
}
79
80
81
# another virtual host using mix of IP-, name-, and port-based configuration
82
#
83
#server {
84
# listen 8000;
85
# listen somename:8080;
86
# server_name somename alias another.alias;
87
88
# location / {
89
# root html;
90
# index index.html index.htm;
91
# }
92
#}
93
94
95
# HTTPS server
96
#
97
#server {
98
# listen 443 ssl;
99
# server_name localhost;
100
101
# ssl_certificate cert.pem;
102
# ssl_certificate_key cert.key;
103
104
# ssl_session_cache shared:SSL:1m;
105
# ssl_session_timeout 5m;
106
107
# ssl_ciphers HIGH:!aNULL:!MD5;
108
# ssl_prefer_server_ciphers on;
109
110
# location / {
111
# root html;
112
# index index.html index.htm;
113
# }
114
#}
115
include servers/*;
116
}

Serving Static Content

Replace the above file with this to end up with the minimal config below:

1
worker_processes 1;
2
3
events {
4
worker_connections 1024;
5
}
6
7
http {
8
server {
9
location / {
10
root data/www;
11
}
12
13
location /images/ {
14
root data;
15
}
16
}
17
}

The root path can also be an absolute path instead of relative to the configured prefix path

After modifying the config, you can use nginx to verify the configuration:

1
nginx -t

Next, we can add the following files to the nginx --prefix directory which can be found with nginx -V:

1
data
2
├── images
3
│   └── image.jpg
4
└── www
5
└── index.html

You can then reload your config with:

Terminal window
1
nginx -s reload

In the above config we have not set a port for our server, this means that the server we have is listening on port 80 and can be accessed at http://localhost:80, the image can be reached from http://localhost:80/images/image.jpg

An nginx config can have multiple server blocks which can listen on different ports. In the config we have above the evaluation of the route is processed by:

  1. Looking at the URI and comparing it to the one in the location
  2. nginx selects the longest matching locaiton
  3. The URI is then appended to the root to resolve the final path on the file system

Aliasing

In the event we don’t want the URI to be appended to our path we can use an alias, so for example we can make it so that /hello points to the index as well:

1
location /hello {
2
alias data/www;
3
}

Try Files

In the event the requested file is not found we can provide some fallbacks that can be looked at instead using try_files:

1
location /images/ {
2
root data;
3
try_files /images/image.jpg /images/index.html =404;
4
}

In the above config, try_files will check the given files in order, if none of those exist, it will return a 404

Regex locations

Locations can also use a regex, for example using the /count route:

1
location ~* /count/[0-9] {
2
root data/www;
3
try_files /index.html =404;
4
}

The above will make it so that we fallback to the index.html file if it exists when given any URI that matches the regex

Redirects

Redirect allow us to tell the requestor to visit another URL instead, redirects are done simply via the return with some status and path

1
location /redirectme {
2
return 307 /images/image.jpg;
3
}

Rewrites

Rewrites allow us to send the response from one path to another, this works by providing some regexes and replacements:

1
rewrite ^/number/(\w+) /count/$1;
2
3
location ~* /count/[0-9] {
4
root data/www;
5
try_files /index.html =404;
6
}

That will rewrite the response from /number/<NUM> to /count/<NUM> and handle the count location as seen above

Proxying

Setting up a proxy server can be done using the proxy_pass. For example we can add a server listening on port 8080 to the http block we have that proxies any requests to the image location to the server we have on port 80

1
server {
2
listen 8080;
3
4
location / {
5
proxy_pass http://localhost:80/images/;
6
}
7
}

Reloading nginx with nginx -s reload should apply the configuration and you should be able to view an image at http://localhost:8080/image.jpg

Mime Types

By default nginx doesn’t serve content with the appropriate mime types, we can configure this by defining a types block within the http context, for example we can define a custom mime type for some made up formats:

1
types {
2
text/html html;
3
text/alpha abc;
4
text/numeric 123;
5
}

There are also a bunch of builtin mime types. We can find these in the mime.types file inside of the nginx config directory

The default mime.types file can be included into our existing config by using include with the path to the file we want to include:

1
http {
2
include mime.types;
3
4
# ... other stuff
5
}

Load Balancing

Load balancing can be done by specifying some URLs in an upstream block along with a name, and we can then reference that name using a location with a proxy_pass:

1
http {
2
3
upstream mybackendserver {
4
server 123.0.0.1:8081;
5
server 123.0.0.2:8082;
6
server 123.0.0.3:8083;
7
}
8
9
server {
10
location / {
11
proxy_pass http://mybackendserver/;
12
}
13
}
14
}