Master Nginx: From Basics to Reverse Proxy, Load Balancing, and CORS

This comprehensive Nginx tutorial walks beginners through core concepts, installation commands, startup scripts, HTTP/HTTPS reverse‑proxy configurations, various load‑balancing strategies, multi‑webapp routing, static site serving, file server setup, and CORS handling with clear examples and code snippets.

21CTO
21CTO
21CTO
Master Nginx: From Basics to Reverse Proxy, Load Balancing, and CORS

Introduction

This project is a minimal Nginx tutorial aimed at helping beginners quickly get started with Nginx.

What is Nginx?

Nginx (engine x) is a lightweight web server, reverse proxy server, and mail (IMAP/POP3) proxy server.

What is a reverse proxy? A reverse proxy accepts client requests from the Internet, forwards them to internal servers, and returns the server responses to the clients.

Installation

See the detailed installation guide at https://github.com/dunwu/nginx-tutorial/blob/master/install-nginx.md .

Common Nginx commands:

nginx -s stop      # fast stop, may lose data
nginx -s quit      # graceful stop, saves state
nginx -s reload    # reload configuration
nginx -s reopen   # reopen log files
nginx -c filename # use a specific config file
nginx -t           # test config syntax only
nginx -v           # show version
nginx -V           # show version, compiler and configure options

You can create a startup.bat batch file on Windows to run these commands:

@echo off
rem if Nginx is already running and pid file exists, kill the process
nginx.exe -s stop
rem test config syntax
nginx.exe -t -c conf/nginx.conf
rem show version
nginx.exe -v
rem start with specified config
nginx.exe -c conf/nginx.conf

On Linux you can write a similar shell script.

HTTP Reverse Proxy

Basic configuration to proxy HTTP requests:

#user somebody;
worker_processes 1;
error_log D:/Tools/nginx-1.10.1/logs/error.log;
error_log D:/Tools/nginx-1.10.1/logs/notice.log notice;
error_log D:/Tools/nginx-1.10.1/logs/info.log info;
pid D:/Tools/nginx-1.10.1/logs/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include D:/Tools/nginx-1.10.1/conf/mime.types;
    default_type application/octet-stream;
    log_format main '[${remote_addr}] - [${remote_user}] [${time_local}] "${request}" ${status} ${body_bytes_sent} "${http_referer}" "${http_user_agent}" "${http_x_forwarded_for}"';
    access_log D:/Tools/nginx-1.10.1/logs/access.log main;
    rewrite_log on;
    sendfile on;
    keepalive_timeout 120;
    tcp_nodelay on;
    upstream zp_server1 {
        server 127.0.0.1:8089;
    }
    server {
        listen 80;
        server_name www.helloworld.com;
        index index.html;
        root D:_WorkspaceProjectgithubzpSpringNotesspring-securityspring-shirosrcmainwebapp;
        charset utf-8;
        proxy_connect_timeout 180;
        proxy_send_timeout 180;
        proxy_read_timeout 180;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarder-For $remote_addr;
        location / {
            proxy_pass http://zp_server1;
        }
        location ~ ^/(images|javascript|js|css|flash|media|static)/ {
            root D:_WorkspaceProjectgithubzpSpringNotesspring-securityspring-shirosrcmainwebappiews;
            expires 30d;
        }
        location /NginxStatus {
            stub_status on;
            access_log on;
            auth_basic "NginxStatus";
            auth_basic_user_file conf/htpasswd;
        }
        location ~ /.ht {
            deny all;
        }
    }
}

Steps to test:

Start the webapp ensuring the upstream port matches.

Add a DNS entry in C:\Windows\System32\drivers\etc\hosts like 127.0.0.1 www.helloworld.com.

Run startup.bat.

Visit http://www.helloworld.com in a browser.

HTTPS Reverse Proxy

HTTPS uses port 443 and requires SSL certificates.

server {
    listen 443 ssl;
    server_name www.helloworld.com;
    ssl_certificate cert.pem;
    ssl_certificate_key cert.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    location / {
        root /root;
        index index.html index.htm;
    }
}

Load Balancing

Example using weighted round‑robin across three Linux servers:

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;
    upstream load_balance_server {
        server 192.168.1.11:80 weight=5;
        server 192.168.1.12:80 weight=1;
        server 192.168.1.13:80 weight=6;
    }
    server {
        listen 80;
        server_name www.helloworld.com;
        location / {
            root /root;
            index index.html index.htm;
            proxy_pass http://load_balance_server;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_connect_timeout 90;
            proxy_send_timeout 90;
            proxy_read_timeout 90;
            proxy_buffer_size 4k;
            proxy_buffers 4 32k;
            proxy_busy_buffers_size 64k;
            client_max_body_size 10m;
            client_body_buffer_size 128k;
        }
    }
}

Supported strategies (shown as code snippets):

# round robin
upstream bck_testing_01 { server 192.168.250.220:8080; server 192.168.250.221:8080; server 192.168.250.222:8080; }

# weighted round robin
upstream bck_testing_01 { server 192.168.250.220:8080 weight=3; server 192.168.250.221:8080; server 192.168.250.222:8080; }

# least connections
upstream bck_testing_01 { least_conn; server 192.168.250.220:8080; server 192.168.250.221:8080; server 192.168.250.222:8080; }

# weighted least connections
upstream bck_testing_01 { least_conn; server 192.168.250.220:8080 weight=3; server 192.168.250.221:8080; server 192.168.250.222:8080; }

# ip_hash
upstream bck_testing_01 { ip_hash; server 192.168.250.220:8080; server 192.168.250.221:8080; server 192.168.250.222:8080; }

# hash by request URI
upstream bck_testing_01 { hash $request_uri; server 192.168.250.220:8080; server 192.168.250.221:8080; server 192.168.250.222:8080; }

Multiple Webapp Routing

When a site hosts several independent webapps (e.g., finance, product, admin), each runs on a different port and Nginx proxies based on URL context:

http {
    upstream product_server { server www.helloworld.com:8081; }
    upstream admin_server   { server www.helloworld.com:8082; }
    upstream finance_server { server www.helloworld.com:8083; }
    server {
        listen 80;
        server_name www.helloworld.com;
        location / { proxy_pass http://product_server; }
        location /product/ { proxy_pass http://product_server; }
        location /admin/   { proxy_pass http://admin_server; }
        location /finance/ { proxy_pass http://finance_server; }
    }
}

Static Site

Serve a static site from /app/dist:

worker_processes 1;

events { worker_connections 1024; }

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    gzip on;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png;
    gzip_vary on;
    server {
        listen 80;
        server_name static.zp.cn;
        location / {
            root /app/dist;
            index index.html;
        }
    }
}

Add to hosts: 127.0.0.1 static.zp.cn and browse to the domain.

File Server

Simple file server with directory listing:

autoindex on;
autoindex_exact_size on;
autoindex_localtime on;

server {
    charset utf-8,gbk;
    listen 9050 default_server;
    listen [::]:9050 default_server;
    server_name _;
    root /share/fs;
}

CORS Handling

Enable CORS via an include file enable-cors.conf:

# allow origin list
set $ACAO '*';
if ($http_origin ~* (www.helloworld.com)$) { set $ACAO $http_origin; }
if ($cors = "trueget") {
    add_header 'Access-Control-Allow-Origin' "$http_origin";
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'OPTIONS') { set $cors "${cors}options"; }
if ($request_method = 'GET')     { set $cors "${cors}get"; }
if ($request_method = 'POST')    { set $cors "${cors}post"; }

Include it in the server block for API routes:

upstream front_server { server www.helloworld.com:9000; }
upstream api_server   { server www.helloworld.com:8080; }

server {
    listen 80;
    server_name www.helloworld.com;
    location ~ ^/api/ {
        include enable-cors.conf;
        proxy_pass http://api_server;
        rewrite "^/api/(.*)$" /$1 break;
    }
    location ~ ^/ {
        proxy_pass http://front_server;
    }
}

With these configurations, Nginx can serve as a reverse proxy, load balancer, static file server, file server, and CORS gateway.

Author: dunwu

Link: https://github.com/dunwu/nginx-tutorial

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CORSNginxreverse proxyHTTPSload-balancingweb-server
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.