Nginx 配置详解(入门到常用场景)

太微2025-04-17运维NginxWeb配置

Nginx 配置详解(入门到常用场景)

Nginx 常用作 HTTP 反向代理、静态资源、负载均衡、TLS 终结 等。配置文件一般为 nginx.conf,并可通过 include 引入 conf.d/*.conf 等片段。以下基于常见 Linux 部署路径说明(Windows 版结构类似,路径不同)。

配置层次结构

main(全局:用户、进程数、错误日志级别等)
├── events { ... }          # 连接处理模型(如 worker_connections)
└── http { ... }            # HTTP 相关
    ├── upstream { ... }  # 上游服务器组(负载均衡)
    ├── server { ... }      # 虚拟主机(站点)
    │   └── location { ... }# URL 路径匹配规则
    └── server { ... }
  • http:可包含多个 server,每个 server 通常对应一个域名或端口组合。
  • location:在同一 server 内按前缀或正则匹配 URI,最具体的匹配优先(规则见官方 location 文档)。

完整示例配置(带注解)

下面是一份「静态 SPA + 反向代理 API + 跨域头」合一的参考结构;实际部署时请按域名、路径、证书修改。# 后为注解。

# 运行用户,降低权限减小安全风险(视系统用户是否存在)
user  nginx;

# worker 进程数:auto 表示按 CPU 核数自动设置
worker_processes auto;

# 错误日志路径与级别:debug / info / notice / warn / error / crit / alert / emerg
error_log /var/log/nginx/error.log warn;

# 主进程 pid 文件,便于 systemd / 脚本管理
pid /run/nginx.pid;

events {
    # 每个 worker 最大并发连接数(不是并发用户数,含所有连接)
    worker_connections 1024;
    # Linux 上推荐开启,允许多个客户端请求合并处理(需系统支持)
    use epoll;
}

http {
    # 引入 MIME 类型与扩展名映射,浏览器才能正确识别 Content-Type
    include       /etc/nginx/mime.types;
    # 未匹配到的类型时的默认值
    default_type  application/octet-stream;

    # 日志格式名 main,后面 access_log 引用;含远程地址、时间、请求行、状态码等
    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 off;
    access_log /var/log/nginx/access.log main;

    # 开启高效文件传输,减少用户态与内核态拷贝
    sendfile        on;
    # 与 sendfile 配合,减少 TCP 包数量(部分场景)
    tcp_nopush      on;
    # 尽快发送小包,降低延迟(常与长连接场景权衡)
    tcp_nodelay     on;

    # 长连接超时(秒),超时后连接关闭
    keepalive_timeout 65;

    # 隐藏版本号,减少信息泄露(需编译包含该模块)
    server_tokens off;

    # 开启 gzip;对文本类响应压缩,减小体积
    gzip on;
    # 低于该字节不压缩,避免小响应压缩反而变大
    gzip_min_length 1024;
    # 压缩级别 1–9,越高 CPU 越重
    gzip_comp_level 5;
    # 参与压缩的 MIME 类型(按项目补充)
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    # 对代理响应也尝试压缩(若上游未压缩)
    gzip_proxied any;

    # 上游 API 集群名 backend,供 proxy_pass 使用
    upstream backend {
        # 第一台权重 2,简单加权轮询
        server 127.0.0.1:3000 weight=2;
        server 127.0.0.1:3001;
        # 与后端保持长连接池大小,减少建连开销(HTTP/1.1)
        keepalive 32;
    }

    server {
        # 监听 80 端口(HTTP)
        listen 80;
        # 匹配的域名,可写多个;不配则回退到 default server(视配置而定)
        server_name example.com www.example.com;

        # 前端构建产物根目录(Vue/React 打包后的 dist)
        root /var/www/app/dist;
        # 默认首页文件名
        index index.html;

        # ---------- 单页应用 SPA(History 模式)----------
        # 前端路由由 JS 处理,需保证「非文件」路径都回退到 index.html
        location / {
            # 依次尝试:URI 文件 → URI 目录 → 回退到 /index.html(单页入口)
            try_files $uri $uri/ /index.html;
        }

        # 静态资源单独缓存(可选):带 hash 的文件名可长期缓存
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
            # 缓存 7 天(浏览器侧);可按需调整
            expires 7d;
            # 可选:关闭该路径访问日志减轻磁盘压力
            access_log off;
            add_header Cache-Control "public, max-age=604800";
        }

        # ---------- API 反向代理 + 跨域 CORS ----------
        # 浏览器跨域时,若请求发到「当前站点域名 + /api」,由 Nginx 转发到后端并统一加 CORS 头
        location /api/ {
            # 去掉 /api 前缀转发到上游(末尾 / 表示替换 location 匹配部分)
            proxy_pass http://backend/;

            # 使用 HTTP/1.1,便于与 upstream keepalive 配合
            proxy_http_version 1.1;
            # 清空 Connection,配合 keepalive 复用连接
            proxy_set_header Connection "";

            # 把原始 Host 传给后端(多站点、后端校验域名时常用)
            proxy_set_header Host $host;
            # 客户端真实 IP(一层代理场景)
            proxy_set_header X-Real-IP $remote_addr;
            # 经过多级代理时的转发链
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # 原始协议 http/https,后端生成绝对链接、重定向时常用
            proxy_set_header X-Forwarded-Proto $scheme;

            # ----- CORS:允许跨域(按环境收紧,生产勿滥用 *)-----
            # 反射请求来源;生产建议改为固定白名单,例如:add_header Access-Control-Allow-Origin "https://app.example.com" always;
            add_header Access-Control-Allow-Origin $http_origin always;
            # 允许携带 Cookie 等凭证时后端需配合,且此处常为具体域名不能为 *
            add_header Access-Control-Allow-Credentials "true" always;
            # 允许的方法
            add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" always;
            # 允许前端自定义头;含 Content-Type、Authorization 等按需列出
            add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
            # 预检缓存时间(秒),减少 OPTIONS 次数
            add_header Access-Control-Max-Age 1728000 always;
            # 暴露给前端的响应头(按需)
            add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always;

            # OPTIONS 预检:直接返回 204,不转发到后端(也可由后端处理,二选一)
            if ($request_method = 'OPTIONS') {
                return 204;
            }
        }

        # 健康检查(可选):负载均衡或 K8s 探针用
        location = /health {
            return 200 'ok';
            add_header Content-Type text/plain;
        }
    }

    # HTTPS 示例(证书路径与域名请替换)
    # server {
    #     listen 443 ssl http2;
    #     server_name example.com;
    #     ssl_certificate     /etc/nginx/ssl/fullchain.pem;   # 证书链
    #     ssl_certificate_key /etc/nginx/ssl/privkey.pem;     # 私钥
    #     ssl_protocols       TLSv1.2 TLSv1.3;                 # 允许的 TLS 版本
    #     ssl_session_cache   shared:SSL:10m;                  # SSL 会话缓存
    #     ssl_session_timeout 10m;
    #     root /var/www/app/dist;
    #     index index.html;
    #     location / { try_files $uri $uri/ /index.html; }
    #     location /api/ { ... 同上 proxy + CORS ... }
    # }
}

注意: 若在同一 location 里使用 if ($request_method = 'OPTIONS') { return 204; },部分环境下 OPTIONS 响应可能不会带上外层的 add_header CORS 头(与 Nginx if 机制有关)。若预检失败,请把 CORS 相关 add_header 挪进该 if 块内重复写一遍,或单独写一个 location 专门匹配 OPTIONS 并返回 204 + 头。

关于 SPA 配置的说明

场景说明
History 模式必须用 try_files $uri $uri/ /index.html(或等价逻辑),否则直接访问 /user/1 会 404。
Hash 模式路由在 # 后,不经过服务器路径,一般只需 root + index不必 try_files 回退(仍建议统一回退,便于复制链接)。
静态资源js/css/图片 建议 长缓存 + 构建带 hash,更新时文件名变,避免缓存脏数据。

关于跨域 CORS 的说明

说明
谁负责 CORS通常由 后端 API 返回 Access-Control-*;若前端与 API 同域(同协议+域名+端口),不需要 CORS。只有「浏览器」对跨域请求会检查 CORS。
Nginx 加头反向代理 时由 Nginx 统一加 add_header,适合前后端分离、API 同源由 Nginx 转发到后端的架构。
Access-Control-Allow-Origin生产环境慎用 * 且带 Credentials 时浏览器会限制;常用 固定白名单$http_origin 白名单校验(需 map 或 Lua,上例为简化演示)。
预检 OPTIONSOPTIONSreturn 204 在 Nginx 结束(如上),或 不拦截 交给后端返回 CORS;不要两边重复加冲突头。
always 参数add_header ... always4xx/5xx 时也带上头,否则错误响应可能缺 CORS 头导致前端拿不到错误信息。

核心指令速查(简要)

worker_processes / worker_connections

worker_processes auto;
events {
    worker_connections 1024;
}

控制工作进程数每个进程最大连接数,影响并发能力。

http 块内的常用项(精简)

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    keepalive_timeout 65;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
}

upstreamproxy_set_header(精简)

upstream backend {
    server 127.0.0.1:3000 weight=2;
    server 127.0.0.1:3001;
    keepalive 32;
}

location / {
    proxy_pass http://backend;
    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_pass 末尾是否带 / 会影响 URI 拼接方式,改配置后务必 nginx -treload


日志与运维命令

access_log /var/log/nginx/access.log main;
error_log  /var/log/nginx/error.log warn;
nginx -t              # 检查配置语法
nginx -s reload       # 重载配置

小结

块/指令作用
http / server / location分层组织站点与路径
root / try_files静态根目录与 SPA 回退
proxy_pass + proxy_set_header反向代理与转发头
add_header + CORS 相关跨域响应头(注意预检与 always
gzip / sendfile传输与静态优化

生产环境还需关注:限流、缓存、安全头、限连接、与后端协议(HTTP/1.1、gRPC) 等。完整指令以官方文档为准:nginx.orgopen in new window

Last Updated 4/9/2026, 6:16:02 AM