Notes
What is Nginx?
Nginx, pronounced engine x, is free, open source software. It can be a web server that serves files, a reverse proxy, a load balancer, and a cache. Often all at once.
Why is it so fast? A master process reads the configuration and starts a few worker processes, usually one per CPU core. Each worker runs an event loop, like we saw in episode four, juggling thousands of connections without waiting on any one of them. That means very little memory per connection.
- 1 master process: reads config
- a few worker processes
- (usually one per CPU core)
- each worker: an event loop,
- thousands of connections,
- never blocking on one
The config
Everything is set in one file, nginx.conf. It's made of nested blocks. An http block holds server blocks, one per website. Each server has location blocks: rules for different URLs.
http {
server { # one website
listen 80;
server_name algorung.com;
location / { # a URL rule
…
}
}
} 1 · Static files
Use one: static files. A location for /static, a root folder on disk, and an expires rule so browsers cache the files for thirty days. Nginx serves files like these extremely fast, without touching your application.
server {
location /static/ {
root /var/www;
expires 30d;
}
} 2 · HTTPS
Use two: HTTPS. The first server block listens on port 80 and redirects every request to the HTTPS address with a 301. The second listens on 443 with SSL, and points to the certificate and private key. Free certificates from Let's Encrypt plug in right here.
server {
listen 80;
server_name algorung.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/site.crt;
ssl_certificate_key /etc/ssl/site.key;
} 3 · Reverse proxy
Use three: reverse proxy. A location for /api, and proxy_pass sends those requests to the application server. The two header lines pass along the original host name and the client's real IP address, the X-Forwarded-For header from last episode.
location /api/ {
proxy_pass http://10.0.0.11:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
} 4 · Load balancing
Use four: load balancing. An upstream block names a group of servers. least_conn picks the server with the fewest active connections. The default is round robin. A backup server only gets traffic if the others are down. Then proxy_pass points at the group's name instead of one address.
If a server keeps failing, Nginx stops sending it traffic for a while: three failures in thirty seconds means skip it for thirty seconds. These are passive checks, based on real requests. Active health checks need the commercial version or a separate tool.
upstream app_servers {
least_conn;
server 10.0.0.11:8080;
server 10.0.0.12:8080;
server 10.0.0.13:8080 backup;
}
location /api/ {
proxy_pass http://app_servers;
} server 10.0.0.12:8080
max_fails=3 fail_timeout=30s;
3 failures in 30 s → skip it for 30 s
(active health checks: Nginx Plus,
or a separate checker) 5 · Extras
Use five: a few lines each for the extras. gzip on compresses responses. proxy_cache stores application responses, here for ten minutes. And limit_req allows each IP address about ten requests a second, with a small burst, which stops floods and scrapers.
gzip on;
proxy_cache my_cache;
proxy_cache_valid 200 10m;
limit_req_zone $binary_remote_addr
zone=perip:10m rate=10r/s;
limit_req zone=perip burst=20; Operating it
Running it day to day: nginx -t tests your config for mistakes before you apply it. nginx -s reload applies changes without dropping a single connection. And the access and error logs tell you what's happening.
nginx -t # test the config nginx -s reload # apply, no downtime access.log every request error.log what went wrong
The full picture
Put it together, and one Nginx in front of your app terminates HTTPS, serves static files, routes API calls, balances them across servers, caches, compresses, and rate limits. That's most of this series, in about forty lines of config.
Alternatives
Alternatives use the same ideas. HAProxy is a load balancing specialist. Envoy powers service meshes. Caddy gets HTTPS certificates automatically. Traefik configures itself from Docker and Kubernetes. And cloud load balancers do it with no servers to manage.
- HAProxy: load balancing specialist
- Envoy: service mesh, gRPC, observability
- Caddy: automatic HTTPS, simple config
- Traefik: auto-config from Docker / K8s
- Cloud LBs: managed, no servers to run