Nginx Guide: From Installation to Production Configuration
Nginx is a high-performance, event-driven web server and reverse proxy used by millions of sites. This guide walks through installation, core configuration directives, and common deployment patterns.
Installation
# Debian/Ubuntu
sudo apt update
sudo apt install nginx
sudo systemctl enable --now nginx
# RHEL/CentOS/Fedora
sudo dnf install nginx
sudo systemctl enable --now nginx
# Verify
curl -I http://localhost
Configuration Structure
The main configuration file is /etc/nginx/nginx.conf. It uses a nested
block structure:
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 256;
# Limit upload size
client_max_body_size 50m;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Server Blocks (Virtual Hosts)
Each site gets its own server block, typically in
/etc/nginx/sites-available/:
# /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# Static assets with long cache
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# Deny access to hidden files
location ~ /\. {
deny all;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t # test configuration syntax
sudo systemctl reload nginx
Reverse Proxy with proxy_pass
Forward requests to an application server:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
SSL/TLS Configuration
Terminate TLS at Nginx (see also the dedicated SSL/TLS Setup guide):
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
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;
root /var/www/example.com/html;
location / {
try_files $uri $uri/ =404;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
The try_files Directive
try_files checks paths in order and falls back to the last argument:
# Serve file, then directory index, then pass to app
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Single-page application -- always serve index.html
location / {
try_files $uri /index.html;
}
Gzip Compression
Compression reduces bandwidth significantly for text-based assets:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 4;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
application/xml
image/svg+xml;
Common Troubleshooting
# Test configuration for syntax errors
sudo nginx -t
# View error log
sudo tail -f /var/log/nginx/error.log
# Check which process owns port 80
sudo ss -tlnp | grep :80
Return to the Web Servers hub or continue to Apache Guide and SSL/TLS Setup.