Nginx 操作文档(入门到实战)

7 阅读5分钟

适用读者:从零基础到中级运维 / 后端工程师 覆盖平台:Linux(Ubuntu / CentOS)与 Windows 11 重点:反向代理、静态站点、HTTPS、负载均衡、性能调优


目录

  1. Nginx 是什么
  2. 安装
  3. 目录结构与常用命令
  4. 配置文件结构
  5. server 与 location
  6. 静态站点配置
  7. 反向代理
  8. 负载均衡
  9. HTTPS / TLS
  10. 常用功能片段
  11. 日志
  12. 性能调优
  13. 安全加固
  14. Docker 中使用 Nginx
  15. 常见问题排查
  16. 完整示例配置

1. Nginx 是什么

Nginx("engine x")是高性能 HTTP / 反向代理 / 邮件代理 服务器。

主要用途:

  • 静态文件服务器(HTML / JS / CSS / 图片 / 视频)
  • 反向代理(前端流量 → 后端应用,常配 Spring Boot、Node、Python 等)
  • 负载均衡(多个上游节点)
  • API 网关 / SSL 终结 / 限流 / 缓存

特点:事件驱动、单线程多 worker、内存占用小、配置简洁。


2. 安装

2.1 Ubuntu / Debian

sudo apt-get update
sudo apt-get install -y nginx
sudo systemctl enable --now nginx
nginx -v

2.2 CentOS / Rocky

sudo yum install -y epel-release
sudo yum install -y nginx
sudo systemctl enable --now nginx

2.3 官方仓库(Linux,版本最新)

sudo apt-get install -y curl gnupg2 ca-certificates lsb-release
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
  | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
  https://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | \
  sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt-get update && sudo apt-get install -y nginx

2.4 Windows

  1. 访问 nginx.org/en/download…,下载 stable 版 zip
  2. 解压到例如 C:\nginx
  3. 双击 nginx.exe 启动;浏览器访问 http://localhost
  4. 常用命令(在 C:\nginx 目录中以管理员 PowerShell / CMD 执行):
.\nginx.exe                  # 启动
.\nginx.exe -s stop          # 立即停止
.\nginx.exe -s quit          # 优雅停止
.\nginx.exe -s reload        # 重载配置
.\nginx.exe -s reopen        # 重新打开日志
.\nginx.exe -t               # 测试配置

Windows 版功能与稳定性都不如 Linux,生产强烈推荐 Linux;Windows 仅适合本地开发或对接 IIS 之外的场景。

2.5 Docker(推荐)

docker run -d --name web -p 80:80 nginx:1.27-alpine

详见第 14 节。


3. 目录结构与常用命令

3.1 默认目录(Ubuntu apt 安装)

/etc/nginx/                  配置目录
├── nginx.conf               主配置
├── conf.d/                  额外的 server 配置(推荐放这里)
├── sites-available/         可用站点(Debian/Ubuntu 风格)
├── sites-enabled/           已启用站点(软链到 available)
├── snippets/                可复用片段
├── modules-enabled/
└── mime.types
/var/log/nginx/              日志(access.log / error.log)
/var/www/html/               默认站点根目录
/usr/share/nginx/html/       某些发行版默认根目录

3.2 服务管理

sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx       # 推荐!热加载,不中断连接
sudo systemctl status nginx
sudo systemctl enable nginx       # 开机自启

sudo nginx -t                     # 测试配置(部署前必做)
sudo nginx -T                     # 测试并打印渲染后的完整配置
sudo nginx -s reload              # 等价于 systemctl reload
sudo nginx -s stop                # 强制停止
sudo nginx -s quit                # 优雅停止
sudo nginx -V                     # 版本 + 编译参数(看支持哪些模块)

3.3 修改配置后的标准流程

sudo nginx -t && sudo nginx -s reload

4. 配置文件结构

# /etc/nginx/nginx.conf

user www-data;                          # worker 进程用户
worker_processes auto;                  # 通常 = CPU 核数
pid /run/nginx.pid;
error_log /var/log/nginx/error.log warn;

events {
    worker_connections 1024;            # 单 worker 最大连接数
    use epoll;                          # Linux 高性能事件模型
    multi_accept on;
}

http {
    include       /etc/nginx/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 /var/log/nginx/access.log main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;                  # 隐藏版本号

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

    # 引入子配置
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

层级:maineventshttpserverlocation


5. server 与 location

5.1 server 块

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;     # 域名(可多个,可通配 *.example.com)

    root /var/www/example;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

listen 常见写法

listen 80;                  # 所有 IP:80
listen 127.0.0.1:80;        # 仅本机
listen 80 default_server;   # 默认 server(请求未匹配任何 server_name 时走它)
listen 443 ssl http2;       # HTTPS + HTTP/2
listen 443 ssl;
http2 on;                   # nginx 1.25+ 推荐写法

5.2 location 匹配优先级

修饰符含义优先级
=精确匹配1(最高)
^~前缀匹配,命中后不再正则2
~ / ~*正则(区分 / 不区分大小写)3
/普通前缀匹配4
location = /favicon.ico { access_log off; log_not_found off; }
location ^~ /static/    { expires 30d; }
location ~* \.(jpg|png|gif|webp)$ { expires 7d; }
location ~ \.php$       { fastcgi_pass 127.0.0.1:9000; }
location /              { try_files $uri $uri/ /index.html; }

6. 静态站点配置

6.1 普通静态站点

server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    # 静态资源长缓存
    location ~* \.(?:css|js|woff2?|ttf|otf|svg|png|jpg|jpeg|gif|webp|ico)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
}

6.2 SPA(Vue / React)

前端路由刷新后 404 的标准修复:

server {
    listen 80;
    server_name app.example.com;
    root /var/www/spa;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;       # 关键:fallback 到 index.html
    }

    # index.html 不缓存,否则发版后老用户拿不到新版本
    location = /index.html {
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }

    location ~* \.(?:css|js|woff2?|png|jpg|svg)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
    }
}

7. 反向代理

7.1 最小反向代理

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;        # 注意结尾斜杠的差异
        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;
    }
}

7.2 关于 proxy_pass 末尾斜杠

location /api/ {
    proxy_pass http://backend;       # 请求 /api/users → 转发为 /api/users
}
location /api/ {
    proxy_pass http://backend/;      # 请求 /api/users → 转发为 /users(去掉了 /api/)
}

加斜杠 = 替换前缀;不加 = 拼接。容易踩坑,记牢这个规则。

7.3 完整代理参数(推荐基线)

location / {
    proxy_pass         http://app_upstream;
    proxy_http_version 1.1;

    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;
    proxy_set_header   X-Forwarded-Host  $host;

    proxy_connect_timeout 5s;
    proxy_send_timeout    60s;
    proxy_read_timeout    60s;

    proxy_buffering on;
    proxy_buffers 8 16k;
    proxy_buffer_size 16k;

    # WebSocket 必备
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

# 配合 WebSocket 的 connection_upgrade 变量
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

7.4 大文件上传

client_max_body_size 100m;
client_body_buffer_size 256k;
proxy_request_buffering off;       # 大文件直连后端,不在 nginx 缓冲

8. 负载均衡

8.1 上游池 upstream

upstream app_upstream {
    # 算法(默认轮询):
    # ip_hash;                # 同 IP 每次到同一节点
    # least_conn;             # 最少连接
    # hash $request_uri consistent;

    server 10.0.0.11:8080 weight=3;
    server 10.0.0.12:8080 weight=1;
    server 10.0.0.13:8080 backup;            # 主节点都挂了才用
    server 10.0.0.14:8080 max_fails=3 fail_timeout=30s;

    keepalive 32;                            # 与后端的长连接池
}

server {
    listen 80;
    location / {
        proxy_pass http://app_upstream;
        proxy_http_version 1.1;
        proxy_set_header Connection "";      # 配合 keepalive
    }
}

8.2 健康检查

开源版仅被动检查(max_fails / fail_timeout)。 主动健康检查需要 Nginx Plus 或第三方模块(如 nginx_upstream_check_module)。

8.3 四层(TCP/UDP)负载均衡

需要在主配置(不是 http 块内)加 stream:

stream {
    upstream mysql_pool {
        server 10.0.0.21:3306;
        server 10.0.0.22:3306;
    }
    server {
        listen 3306;
        proxy_pass mysql_pool;
    }
}

9. HTTPS / TLS

9.1 自签证书(仅测试)

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/self.key \
  -out /etc/nginx/ssl/self.crt \
  -subj "/CN=localhost"

9.2 Let's Encrypt(生产免费)

sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run        # 测试自动续期

certbot 会自动改 Nginx 配置加上 ssl 段。

9.3 推荐 HTTPS 配置

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;          # 强制跳 HTTPS
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;                                       # nginx 1.25+
    server_name example.com www.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 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

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

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 5s;

    # HSTS(确认全站 HTTPS 后再开)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    root /var/www/example;
    index index.html;
}

10. 常用功能片段

10.1 重定向

return 301 https://$host$request_uri;
return 302 /maintenance.html;
rewrite ^/old/(.*)$ /new/$1 permanent;

10.2 防盗链

location ~* \.(jpg|png|gif|mp4)$ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) { return 403; }
}

10.3 限流(Rate Limit)

http {
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}

server {
    location /api/ {
        limit_req zone=api_limit burst=20 nodelay;
        limit_conn conn_limit 5;
        proxy_pass http://backend;
    }
}

10.4 IP 黑白名单

location /admin/ {
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny  all;
    proxy_pass http://admin;
}

10.5 基本鉴权(Basic Auth)

sudo apt-get install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd admin
location /private/ {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

10.6 CORS

location /api/ {
    if ($request_method = OPTIONS) {
        add_header Access-Control-Allow-Origin  "$http_origin" always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
        add_header Access-Control-Allow-Credentials "true" always;
        add_header Access-Control-Max-Age 86400;
        return 204;
    }
    add_header Access-Control-Allow-Origin "$http_origin" always;
    add_header Access-Control-Allow-Credentials "true" always;
    proxy_pass http://backend;
}

10.7 gzip / brotli 压缩

gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_types
    text/plain text/css text/xml application/json
    application/javascript application/xml+rss
    image/svg+xml font/woff2;

10.8 缓存代理结果

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
    location / {
        proxy_cache app_cache;
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_pass http://backend;
    }
}

10.9 简单维护页

location / {
    return 503;
}
error_page 503 @maintenance;
location @maintenance {
    root /var/www/maintenance;
    try_files /index.html =503;
}

11. 日志

11.1 自定义日志格式

log_format json_combined escape=json '{'
    '"time_local":"$time_iso8601",'
    '"remote_addr":"$remote_addr",'
    '"x_forwarded_for":"$http_x_forwarded_for",'
    '"request":"$request",'
    '"status":$status,'
    '"body_bytes_sent":$body_bytes_sent,'
    '"request_time":$request_time,'
    '"upstream_response_time":"$upstream_response_time",'
    '"http_referer":"$http_referer",'
    '"http_user_agent":"$http_user_agent"'
'}';

access_log /var/log/nginx/access.log json_combined;

11.2 按域名分文件

server {
    server_name api.example.com;
    access_log /var/log/nginx/api.access.log main;
    error_log  /var/log/nginx/api.error.log  warn;
}

11.3 日志轮转

Linux 通常装好就有 /etc/logrotate.d/nginx,默认每天切割保留 14 天。可按需修改。


12. 性能调优

12.1 worker

worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 10240;
    use epoll;
    multi_accept on;
}

理论最大并发 ≈ worker_processes * worker_connections / 2(反代场景每个连接占 2 个 fd)。

系统层面也要调:

# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

# /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535

12.2 keepalive

http {
    keepalive_timeout 65;
    keepalive_requests 1000;
}

upstream backend {
    server 10.0.0.11:8080;
    keepalive 64;
}
location / {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}

12.3 sendfile / 缓冲

sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_body_buffer_size 16k;
client_max_body_size 100m;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;

12.4 静态资源压缩 + 缓存

见 10.7、6.2 节。


13. 安全加固

# 隐藏版本号
server_tokens off;
# 隐藏 server 头(需要 ngx_headers_more 模块)
# more_clear_headers 'Server';

# 安全响应头
add_header X-Content-Type-Options    "nosniff" always;
add_header X-Frame-Options           "SAMEORIGIN" always;
add_header Referrer-Policy           "strict-origin-when-cross-origin" always;
add_header Permissions-Policy        "geolocation=(), microphone=()" always;
# add_header Content-Security-Policy "default-src 'self'" always;     # 视项目而定

# 拒绝可疑 method
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) { return 405; }

# 屏蔽常见探测路径
location ~ /\.(?:git|env|svn|hg) { deny all; }
location ~ ~$                    { deny all; }

其他建议:

  • 用专门的低权限用户(user www-data;
  • 关掉不必要的模块(编译时)
  • 后端只监听内网;前置 Nginx 监听公网
  • 配 fail2ban 自动封 IP
  • 定期 nginx -V 跟版本,及时升级 CVE

14. Docker 中使用 Nginx

14.1 命令式

docker run -d --name web \
  -p 80:80 -p 443:443 \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v $(pwd)/conf.d:/etc/nginx/conf.d:ro \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -v $(pwd)/certs:/etc/nginx/certs:ro \
  -v $(pwd)/logs:/var/log/nginx \
  --restart=unless-stopped \
  nginx:1.27-alpine

热更新配置:

docker exec web nginx -t && docker exec web nginx -s reload

14.2 Compose 示例

services:
  nginx:
    image: nginx:1.27-alpine
    ports: ["80:80","443:443"]
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./certs:/etc/nginx/certs:ro
      - ./html:/usr/share/nginx/html:ro
      - ./logs:/var/log/nginx
    restart: unless-stopped
    healthcheck:
      test: ["CMD","wget","-q","--spider","http://localhost/"]
      interval: 30s
      timeout: 5s
      retries: 3

14.3 K8s 中作为 Ingress Controller

参见 Kubernetes操作手册.md 第 9 节。Nginx 也常被部署为独立的 Deployment 提供网关能力。


15. 常见问题排查

现象排查
改配置不生效nginx -t 确认语法;nginx -s reload;浏览器强刷或换无痕
502 Bad Gateway后端没起、端口错、proxy_pass 写错;error.log 看 connect failed
504 Gateway Timeout后端慢,调大 proxy_read_timeout
413 Request Entity Too Large调大 client_max_body_size
静态文件 403目录权限;SELinux;/var/www 父目录 nginx 用户没 x 权限
拿到的 $remote_addr 是 LB 内网 IP$http_x_forwarded_for 或配 set_real_ip_from / real_ip_header
HTTPS 浏览器警告证书域名不匹配;中间证书没拼到 fullchain;时间不对
WebSocket 连不上缺少 Upgrade / Connection 头和 proxy_http_version 1.1
跨域失败看 OPTIONS 预检是否被代理拦截;CORS 头是否丢失
长连接没生效后端 keepalive 没开;Connection 头没清空

real_ip 配置示例:

set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
real_ip_header   X-Forwarded-For;
real_ip_recursive on;

16. 完整示例配置

16.1 单站点 + HTTPS + 反代后端 + SPA + 静态资源

# /etc/nginx/conf.d/example.conf

upstream api_backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTP → HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS 主站
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name example.com www.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_session_cache shared:SSL:10m;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;

    client_max_body_size 50m;

    root /var/www/example/dist;
    index index.html;

    # API 反代
    location /api/ {
        proxy_pass         http://api_backend/;     # 注意末尾 /,会去掉 /api/ 前缀
        proxy_http_version 1.1;
        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;
        proxy_set_header   Connection        "";
        proxy_read_timeout 60s;
    }

    # WebSocket
    location /ws/ {
        proxy_pass         http://api_backend;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade    $http_upgrade;
        proxy_set_header   Connection $connection_upgrade;
        proxy_set_header   Host       $host;
        proxy_read_timeout 3600s;
    }

    # 静态资源缓存
    location ~* \.(?:css|js|woff2?|ttf|svg|png|jpg|jpeg|gif|webp|ico)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # SPA fallback
    location / {
        try_files $uri $uri/ /index.html;
    }
    location = /index.html {
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }

    # 屏蔽敏感文件
    location ~ /\.(?:git|env|svn|hg) { deny all; }
}
sudo nginx -t && sudo nginx -s reload

配套阅读:Docker操作手册.mdDockerCompose操作手册.mdKubernetes操作手册.md;进阶请看 Nginx生产化手册.md