Nginx Introduction
What Nginx is, installing it, and how its configuration file structure is organized.
What Nginx is
Nginx (pronounced "engine-x") is a piece of software that can act as three different things depending on how it's configured:
- A web server — it can serve static files (HTML, CSS, JS, images) directly off disk, extremely fast, with a small memory footprint per connection.
- A reverse proxy — it can sit in front of an application server (PHP-FPM, Node.js, a Java app) and forward requests to it, adding TLS termination, compression, and buffering along the way.
- A load balancer — it can distribute incoming requests across a pool of backend servers.
Most real deployments use Nginx for more than one of these roles at once: it terminates HTTPS, serves static assets directly, and proxies everything else to an application server behind it — all from the same config file. This tutorial focuses on the practical config syntax for all three roles; if you want the underlying architectural concepts (why reverse proxies and load balancers exist, load balancing algorithms, caching strategies), see the System Design track's page on load balancing and caching.
Installing Nginx
On Debian/Ubuntu:
sudo apt update
sudo apt install nginx
sudo systemctl enable --now nginx
On RHEL/CentOS/Amazon Linux:
sudo yum install nginx
sudo systemctl enable --now nginx
Once installed, Nginx starts serving a default welcome page on port 80 immediately. Useful commands for managing the running service:
sudo systemctl status nginx # check it's running
sudo systemctl restart nginx # full restart (drops connections briefly)
sudo systemctl reload nginx # reload config with zero downtime
sudo nginx -t # test config syntax before reloading — always run this first
nginx -t is worth calling out on its own: it validates your configuration file syntax without applying it, so you catch a typo before reloading breaks the live server.
Config file structure
The main configuration file is /etc/nginx/nginx.conf. It defines a small number of nested contexts (blocks), each scoping directives that apply within it:
# /etc/nginx/nginx.conf (simplified)
user www-data;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
events {}— controls how Nginx handles connections at a low level (e.g.worker_connections, the max simultaneous connections per worker process).http {}— the context for everything HTTP/HTTPS-related. Almost all the configuration you'll actually write lives insidehttp, directly or through an included file.server {}— nested insidehttp, oneserverblock represents one virtual host — typically one domain (or one domain + port combination).location {}— nested insideserver, alocationblock matches a URL path and defines how requests to that path are handled.
In practice, you rarely edit nginx.conf itself. Distro packages split real site configuration into separate files:
- Debian/Ubuntu: individual site configs go in
/etc/nginx/sites-available/, and are activated by symlinking into/etc/nginx/sites-enabled/. - RHEL/CentOS/Amazon Linux: site configs go directly in
/etc/nginx/conf.d/*.conf.
# Debian/Ubuntu: enable a site
sudo ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Common mistakes
- Editing
nginx.confdirectly for site-specific config instead of adding a file undersites-available/conf.d— this makes config sprawl and multi-site management much harder to reason about. - Running
systemctl restartafter every config change instead ofnginx -tfollowed byreload— restart drops active connections, reload doesn't. - Forgetting to symlink a new config into
sites-enabled(Debian/Ubuntu) and wondering why the site "doesn't exist." - Not running
nginx -tbefore reloading — a syntax error inreloadcan leave the old config running, or in some failure modes stop Nginx from serving at all.