精通 Nginx 配置:核心指令详解
理解你最常用的 Nginx 指令:http、server、location、proxy_pass、try_files、gzip、TLS 以及服务重载。
掌握 Nginx 配置:核心指令详解
一旦你理解了每条指令允许出现的位置,Nginx 配置就会变得容易得多。如果你的 proxy_pass、root 或 try_files 规则放错了上下文,Nginx 可能会拒绝配置,或者以你意想不到的方式处理请求。
本指南将带你了解在提供静态文件、反向代理应用、启用压缩以及安全重载更改时,你会用到的核心指令。
Nginx 配置结构
在 Linux 发行版中,Nginx 配置文件通常位于 /etc/nginx/ 目录下。主文件通常是 /etc/nginx/nginx.conf,它通常会包含来自 /etc/nginx/conf.d/ 的文件。Debian 和 Ubuntu 发行版通常使用 sites-available/ 和 sites-enabled/ 目录;许多其他发行版则不使用。
配置是分层的,组织成块或指令。关键的块包括:
events:配置连接处理。http:包含 HTTP 范围的设置和虚拟服务器。server:为某个端口和主机名定义一个虚拟服务器。location:选择如何处理匹配的请求 URI。
指令是控制 Nginx 行为的键值对。它们可以是全局的,也可以嵌套在块内。
核心指令详解
http 块
http 块包含全局应用于 HTTP 流量的配置。你将在此处定义 Web 服务器的通用设置。
include:此指令允许你包含其他配置文件,有助于模块化你的设置。它通常用于分离不同网站或应用程序的配置。http { include mime.types; default_type application/octet-stream; # 从 conf.d 目录包含服务器配置 include /etc/nginx/conf.d/*.conf; }log_format:为 Nginx 访问和错误日志定义自定义日志格式。这对于详细日志记录和分析至关重要。http { 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; error_log /var/log/nginx/error.log; # ... 其他 http 指令 }sendfile:通过允许内核直接从磁盘向客户端发送文件,绕过用户空间,从而优化文件传输。为了性能,设置为on。http { sendfile on; # ... }tcp_nopush和tcp_nodelay:这些指令调整 HTTP 响应的 TCP 行为。tcp_nopush通常与sendfile一起使用以优化数据包发送,而tcp_nodelay有助于避免 keepalive 连接上的延迟。http { tcp_nopush on; tcp_nodelay on; # ... }
server 块
每个 server 块定义一个虚拟服务器,允许 Nginx 在同一台服务器上处理针对不同域名或 IP 地址的请求。
listen:指定服务器将监听传入连接的 IP 地址和/或端口。server { listen 80; listen [::]:80; server_name example.com www.example.com; # ... }server_name:定义服务器的名称。Nginx 使用它来匹配传入请求的Host头。server { listen 80; server_name mydomain.org *.mydomain.org; # ... }root:设置文档根目录。Nginx 通过将请求 URI 附加到此目录来构建文件路径。server { listen 80; server_name localhost; root /var/www/html; index index.html index.htm; # ... }index:指定请求目录时要提供的默认文件。server { # ... index index.html index.htm default.html; # ... }error_page:为特定的 HTTP 状态码定义自定义错误页面。server { # ... error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; internal; } # ... }
location 块
location 块用于匹配请求 URI,并决定 Nginx 如何处理它们。你可以在此处为应用程序的不同部分配置路由。
匹配 URI:Location 可以匹配精确字符串、前缀或正则表达式。精确匹配使用
=,正则表达式使用~或~*,普通前缀按 URI 前缀匹配。location /images/ { # 针对以 /images/ 开头的请求的指令 } location = /favicon.ico { # 精确匹配 /favicon.ico } location ~ \.php$ { # 正则匹配以 .php 结尾的文件 }proxy_pass:将请求转发到上游服务器。注意尾部斜杠,因为它会改变 Nginx 重写匹配前缀的方式。location /api/ { proxy_pass http://backend-service: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; }alias:将 location 映射到文件系统路径,而不附加完整的原始 URI。它通常用于存储在主文档根目录之外的静态资源。location /static/ { alias /var/www/app/assets/; }使用
alias时,对于目录映射,请确保 location 和路径都包含尾部斜杠。alias将匹配的 location 前缀替换为别名路径,而root则将 URI 附加到根路径。try_files:按指定顺序检查文件是否存在,并提供找到的第一个文件,或者返回指定的代码/URI。location / { try_files $uri $uri/ /index.html; }这对于单页应用程序很常见。如果请求的文件或目录不存在,Nginx 将提供
index.html,以便客户端路由器可以处理该路径。
安全与性能指令
ssl_certificate和ssl_certificate_key:配置 HTTPS 所必需的。这些指令指向你的 SSL 证书和私钥文件。server { listen 443 ssl; server_name secure.example.com; ssl_certificate /etc/letsencrypt/live/secure.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/secure.example.com/privkey.pem; # ... 其他 SSL 设置 }gzip:为选定的响应类型启用或禁用 gzip 压缩。它通常可以减少文本资源的传输大小,但应避免压缩已经压缩过的文件,例如大多数图片。http { gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # ... }expires:控制静态资源的缓存头。对于带有指纹的文件,使用较长的缓存生命周期;对于在部署之间保持相同 URL 的文件,使用较短的生命周期。location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public"; }
常用 Nginx 命令
为了管理 Nginx 并应用配置更改,你会经常使用以下命令:
测试配置:检查 Nginx 配置文件中是否存在语法错误。
sudo nginx -t重载配置:优雅地重载 Nginx 配置,而不会断开活动连接。
sudo systemctl reload nginx # 或 sudo service nginx reload重启 Nginx:停止然后启动 Nginx 服务。
sudo systemctl restart nginx # 或 sudo service nginx restart检查状态:显示 Nginx 服务的当前状态。
sudo systemctl status nginx # 或 sudo service nginx status
一个最小的工作示例
此示例从磁盘提供单页应用,并将 API 请求代理到应用服务器:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:3000/;
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;
}
location / {
try_files $uri $uri/ /index.html;
}
}
每次重载前运行 sudo nginx -t。这一个习惯可以在语法错误导致停机之前捕获它们。
要点
大多数 Nginx 错误源于上下文和路径处理。将 HTTP 范围的设置放在 http 中,主机特定的规则放在 server 中,URI 路由放在 location 中,并在重载前使用 nginx -t 测试每个更改。