概览
参考文档:nginx documentation
nginx是 HTTP 服务器和反向代理服务器,也提供内容缓存和负载均衡nginx统一承担以下职责:- 静态文件直接返回
- 其余请求转发给
127.0.0.1上的后端服务 - 对外只暴露
80/443 - TLS、压缩、限流、日志集中处理
- 后端只监听
127.0.0.1,不需要各自处理证书
flowchart LR C["客户端"] -->|"80/443"| N["nginx"] N -->|"静态文件"| S["/var/www"] N -->|"proxy_pass"| A["应用(127.0.0.1:8080)"] N -->|"proxy_pass"| B["另一个服务(127.0.0.1:9090)"]
快速开始
主配置
/etc/nginx/nginx.conf,include决定站点配置从哪里加载:nginxuser nginx; # 运行用户 worker_processes auto; # 工作进程数,auto 跟随 CPU 核数 error_log /var/log/nginx/error.log warn; # 错误日志与级别 pid /var/run/nginx.pid; # 主进程 PID 文件 events { worker_connections 1024; # 单个 worker 的最大连接数 } http { include /etc/nginx/mime.types; # MIME 类型映射 default_type application/octet-stream; # 未识别类型时的默认值 sendfile on; # 零拷贝发送文件 keepalive_timeout 65; # 长连接空闲超时 include /etc/nginx/conf.d/*.conf; # 站点配置入口 }- Debian/Ubuntu:
/etc/nginx/sites-enabled/* - RHEL 系 / Arch Linux:
/etc/nginx/conf.d/*.conf - Alpine Linux:
/etc/nginx/http.d/*.conf
- Debian/Ubuntu:
一个反向代理站点,写到
/etc/nginx/conf.d/app.example.com.conf:nginxserver { listen 80; # 对外监听端口 server_name app.example.com; # 匹配的域名 location / { proxy_pass http://127.0.0.1:8080; # 转发目标 proxy_set_header Host $host; # 保留原始 Host proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端 IP } }重载配置:
bashsudo nginx -t && sudo systemctl reload nginx # 先检查语法,通过后热重载静态站点,
Hugo构建产物在/var/www/blog:nginxserver { listen 80; server_name example.com; root /var/www/blog; # 构建产物目录 index index.html; # 默认首页 location / { try_files $uri $uri/ =404; # 依次尝试文件、目录,最后回退 404 } location ~* \.(css|js|png|jpg|woff2)$ { expires 30d; # 带文件名指纹的资源加长缓存 } }反向代理如果需要支持长连接,需要添加
map块将普通请求与长连接请求区分开:nginxmap $http_upgrade $connection_upgrade { default upgrade; # 有 Upgrade 头时透传 upgrade '' close; # 普通请求关闭连接升级 } server { listen 80; server_name app.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; # 长连接需要 1.1 proxy_set_header Upgrade $http_upgrade; # 透传 WebSocket 升级头 proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 1h; # 默认 60s 会掐断空闲连接 client_max_body_size 100m; # 默认 1m,上传大文件会 413 } }挂证书,
HTTP重定向到HTTPS:nginxserver { listen 80; server_name example.com; return 301 https://$host$request_uri; # 明文请求重定向到 HTTPS } server { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/certs/example.com.pem; # 证书链 ssl_certificate_key /etc/nginx/certs/example.com.key; # 私钥 location / { proxy_pass http://127.0.0.1:8080; } }
配置结构
- 站点配置子目录随发行版不同:
- Debian/Ubuntu:
sites-available/存配置,sites-enabled/放软链接启用 - RHEL 系:
conf.d/下放.conf文件,无需软链接 - Arch Linux:站点配置放在
conf.d/ - Alpine Linux:
http.d/放虚拟主机配置,conf.d/仅用于根上下文片段
- Debian/Ubuntu:
- 配置字段:
http:全局HTTP层参数http.server:一个listen+server_name组合对应一个站点http.server.location:站点内的路径规则,决定请求交给谁http.map:根据一个变量的值生成另一个变量,只能放在http层,基本形式为map $源变量 $目标变量 { 值 结果; ... }- 第一个参数是来源,比如
$http_upgrade - 第二个参数是生成的新变量名,比如
$connection_upgrade - 块内每行是"匹配值 结果",
default匹配其余情况,空字符串用''表示
- 第一个参数是来源,比如
location 语法
nginx
location = /exact { } # 精确匹配
location ^~ /static/ { } # 前缀匹配,命中后不再检查正则
location ~ \.php$ { } # 区分大小写的正则匹配
location ~* \.(jpg|png)$ { } # 不区分大小写的正则匹配
location /api/ { } # 普通前缀匹配- 匹配优先级从高到低:精确
=、^~前缀、正则~/~*、普通前缀;正则会按书写顺序取第一个匹配项 - 常用内部指令:
root:把 URI 直接拼到指定目录后面alias:用指定目录替换location匹配到的前缀try_files:按顺序尝试文件,全部失败时走最后的回退,比如=404或转发到后端proxy_pass:把请求转给上游,配合proxy_set_header传递真实 IP 与协议
常用命令
bash
nginx -t # 检查配置语法
nginx -T # 打印合并后的完整配置
nginx -s reload # 向主进程发送重载信号,等价于 systemctl reload nginx
nginx -s quit # 优雅退出静态站点
nginx
server {
listen 80;
server_name example.com;
root /var/www/blog; # 构建产物目录
index index.html; # 默认首页
location / {
try_files $uri $uri/ =404; # 依次尝试文件、目录,最后回退 404
}
location ~* \.(css|js|png|jpg|woff2)$ {
expires 30d; # 带文件名指纹的资源加长缓存
}
}反向代理
nginx
map $http_upgrade $connection_upgrade {
default upgrade; # 有 Upgrade 头时透传 upgrade
'' close; # 普通请求关闭连接升级
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1; # 长连接需要 1.1
proxy_set_header Upgrade $http_upgrade; # 透传 WebSocket 升级头
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 1h; # 默认 60s 会掐断空闲连接
client_max_body_size 100m; # 默认 1m,上传大文件会 413
}
}TLS
nginx
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri; # 明文请求重定向到 HTTPS
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/certs/example.com.pem; # 证书链
ssl_certificate_key /etc/nginx/certs/example.com.key; # 私钥
location / {
proxy_pass http://127.0.0.1:8080;
}
}- 证书来源有两种:
Let's Encrypt:certbot --nginx -d example.com自动签发并接管续期Cloudflare Origin CA:15年有效期,适合源站只接受Cloudflare回源的场景,生成方法见用 Cloudflare 配置 HTTPS