Nginx 配置详解(入门到常用场景)
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,上例为简化演示)。 |
| 预检 OPTIONS | OPTIONS 可 return 204 在 Nginx 结束(如上),或 不拦截 交给后端返回 CORS;不要两边重复加冲突头。 |
always 参数 | add_header ... always 在 4xx/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;
}
upstream 与 proxy_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 -t 再 reload。
日志与运维命令
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.org。
