Nginx Tutorial

Nginx (pronounced “engine-x”) is a powerful, high-performance web server, reverse proxy, and load balancer.
This tutorial covers basic configurations for common use cases including redirects, port mapping, and SSL setup.

Introduction to Nginx

Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption. Originally created to solve the C10K problem (handling 10,000+ concurrent connections), it has grown to become one of the most popular web servers worldwide.

Official Documentation: https://nginx.org/en/docs/
Nginx Wiki: https://www.nginx.com/resources/wiki/

Installation

Nginx is available on most operating systems. Here are installation commands for common platforms:

For Ubuntu/Debian:

1
2
sudo apt update
sudo apt install nginx

For CentOS/RHEL:

1
2
sudo yum install epel-release
sudo yum install nginx

For macOS (using Homebrew):

1
brew install nginx

Docker Nginx Configuration

Default Directory Structure in Docker

Nginx directory structure in Docker containers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/etc/nginx/
├── nginx.conf # Main configuration file
├── modules/ # Modules directory
├── mime.types # MIME type definitions
├── fastcgi_params # FastCGI parameters
├── scgi_params # SCGI parameters
├── uwsgi_params # uWSGI parameters
├── conf.d/ # Custom configuration directory
│ └── default.conf # Default configuration
├── sites-available/ # Available sites (some versions)
└── sites-enabled/ # Enabled sites (some versions)

/var/www/html/ # Default document root
├── index.html # Default homepage
└── 50x.html # Error page

/var/log/nginx/ # Log directory
├── access.log # Access logs
└── error.log # Error logs

/var/cache/nginx/ # Cache directory

Basic Configuration Structure

Nginx configuration files are typically located in /etc/nginx/. The main configuration file is nginx.conf, but it’s common practice to create separate configuration files in /etc/nginx/conf.d/ or /etc/nginx/sites-available/ directories.

A basic server block looks like this:

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name example.com www.example.com;

location / {
root /var/www/html;
index index.html index.htm;
}
}

Redirect Examples

HTTP to HTTPS Redirect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name example.com www.example.com;

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

# Other SSL parameters...

location / {
root /var/www/html;
index index.html index.htm;
}
}

WWW to Non-WWW Redirect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}

server {
listen 80;
server_name example.com;

location / {
root /var/www/html;
index index.html index.htm;
}
}

URL Path Redirect

1
2
3
location /old-path {
return 301 /new-path;
}

Port Mapping (Reverse Proxy)

Nginx can proxy requests to applications running on different ports:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
server_name example.com;

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;
}
}

This configuration forwards requests to a service running on port 3000 (like a Node.js application).

SSL Configuration

Basic SSL Setup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
listen 443 ssl;
server_name example.com;

ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

# Strong SSL Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

# SSL Session parameters
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

# HSTS (optional, but recommended)
add_header Strict-Transport-Security "max-age=63072000" always;

location / {
root /var/www/html;
index index.html index.htm;
}
}

SSL with Let’s Encrypt

First, install Certbot:

1
sudo apt install certbot python3-certbot-nginx  # for Ubuntu/Debian

Then obtain and install the certificate:

1
sudo certbot --nginx -d example.com -d www.example.com

Certbot will automatically modify your Nginx configuration to use the new certificates.

Load Balancing

Nginx can distribute traffic across multiple servers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backend {
server backend1.example.com weight=3;
server backend2.example.com;
server backup1.example.com backup;
}

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;
}
}

Rate Limiting

Protect your servers from abuse with rate limiting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
http {
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

server {
listen 80;
server_name example.com;

location / {
limit_req zone=mylimit burst=20 nodelay;

# Your other configurations...
}
}
}

This limits a single IP to 10 requests per second with a burst of 20 requests.

Caching

Enable Cache

Enable caching to improve performance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;

server {
listen 80;
server_name example.com;

location / {
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_pass http://backend;
}
}
}

Disable Cache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;

# Disable Cache
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
add_header Pragma "no-cache";
add_header Expires 0;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

Gzip Compression

Enable Gzip to reduce bandwidth usage:

1
2
3
4
5
6
7
8
9
10
11
12
http {
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

# Other configurations...
}

Testing and Reloading Configuration

After making changes to your Nginx configuration, test it for syntax errors:

1
sudo nginx -t

If the test is successful, reload Nginx to apply the changes:

1
2
3
sudo systemctl reload nginx  # For systemd-based systems
# OR
sudo service nginx reload # For init.d-based systems

Cat nginx default.conf in Docker

1
docker run -it --rm nginx:alpine cat /etc/nginx/conf.d/default.conf

Nginx Tutorial
https://www.hardyhu.cn/2023/04/17/Nginx-Tutorial/
Author
John Doe
Posted on
April 17, 2023
Licensed under