Nginx Basics
Nginx (pronounced "engine-x") is a high-performance web server and reverse proxy used by a large share of the world's busiest sites. Unlike Apache, which spawns a thread per connection, nginx uses an event-driven, asynchronous architecture that handles thousands of concurrent connections with low memory usage.
Configuration lives in /etc/nginx/ — the main file is nginx.conf, and individual site configs go in /etc/nginx/sites-available/ with symlinks to /etc/nginx/sites-enabled/.
Server Blocks
A server block is nginx's equivalent of Apache's VirtualHost — it defines how nginx handles requests for a particular domain or IP. A minimal static site block:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}try_files tells nginx to look for a file matching the URI, then a directory, then return 404 if neither exists.
HTTPS with SSL Termination
With Let's Encrypt (via Certbot), enabling HTTPS is straightforward. After running Certbot, your config gains SSL directives and a redirect block:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}Reverse Proxy for Node.js
To proxy requests to a Node.js app running on port 3000:
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}The Upgrade and Connection headers are needed for WebSocket support.
Security Headers
Adding security headers to every response hardens your site against common attacks:
add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header X-XSS-Protection "1; mode=block"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Referrer-Policy "strict-origin-when-cross-origin";
HSTS (Strict-Transport-Security) tells browsers to only connect over HTTPS for the specified duration. Only enable it once HTTPS is fully configured — it is difficult to undo.
Gzip Compression
Enable gzip to reduce response sizes for text-based assets:
gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; gzip_min_length 256;
Rate Limiting
Protect against brute force and abuse:
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20 nodelay;
}Testing Your Config
Before reloading nginx, test the configuration syntax: nginx -t. An error in the config file will prevent nginx from reloading, and if you reload with a broken config, nginx continues serving traffic with the old config — but a restart (e.g., after a server reboot) will fail. Always run nginx -t before systemctl reload nginx.
Generating Configs
Nginx configs involve a lot of repetitive boilerplate. A generator handles the common patterns — reverse proxy, static site, PHP-FPM, SSL — and produces a correct starting point that you can refine. The DevHexLab Nginx Config Generator produces a complete server block for your chosen setup with SSL, gzip, and security headers included.