Master Nginx: From Basic Commands to Advanced Reverse Proxy & Load Balancing
This tutorial explains what Nginx is, how reverse proxy works, common Nginx commands, and provides step‑by‑step configuration examples for simple reverse proxy, load balancing, multiple webapps, HTTPS, static sites, file servers, and CORS handling.
Overview
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 Internet connection requests, forwards them to internal servers, and returns the response to the client, acting as the external entry point.
Usage
Common Nginx commands:
<code>nginx -s stop # fast stop, may not save state
nginx -s quit # graceful stop, saves state
nginx -s reload # reload after configuration change
nginx -s reopen # reopen log file
nginx -c filename # specify a configuration file
nginx -t # test configuration syntax only
nginx -v # show Nginx version
nginx -V # show version, compiler and configure parameters</code>To avoid typing commands each time, create a
startup.batin the Nginx installation directory:
<code>@echo off
rem If Nginx is already running and a pid file exists, kill the process
nginx.exe -s stop
rem Test configuration syntax
nginx.exe -t -c conf/nginx.conf
rem Show version information
nginx.exe -v
rem Start Nginx with a specific configuration
nginx.exe -c conf/nginx.conf</code>On Linux, a similar shell script can be used.
Nginx Configuration Practice
Goal: implement a simple HTTP reverse proxy without complex settings.
<code># 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:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp;
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:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;
expires 30d;
}
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
}
location ~ \.ht {
deny all;
}
}
}
</code>Test steps:
Start the webapp, ensuring the port matches the upstream server.
Add a DNS entry
127.0.0.1 www.helloworld.comto the hosts file.
Run
startup.batto launch Nginx.
Visit
http://www.helloworld.comin a browser.
Load Balancing Configuration
Example with three backend servers and weighted distribution:
<code>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;
}
}
}
</code>Multiple Webapp Configuration
Separate upstream blocks for product, admin, and finance services, routing based on URL path:
<code>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 {
# default to product
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; }
}
}
</code>HTTPS Reverse Proxy Configuration
Listen on port 443 with SSL certificates and standard proxy settings:
<code>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;
}
}
</code>Static Site Configuration
Serve a static site from
/app/distwith gzip compression:
<code>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;
}
}
}
</code>File Server Setup
Enable directory listing and serve files from
/share/fson port 9050:
<code>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;
}
</code>Cross‑Origin Solution
Two approaches: CORS (setting response headers) and JSONP. Nginx can implement CORS via an include file.
<code># enable-cors.conf
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"; }
</code> <code># main server block
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;
}
}
</code>All configurations above demonstrate how to use Nginx for reverse proxy, load balancing, HTTPS, static content, file serving, and CORS handling.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.