Nginx速查表:命令、配置片段和错误修复
Debian 12和Ubuntu 24.04上Nginx日常操作的快速参考。按任务组织,快速找到所需内容。完整指南请参阅VPS上的Nginx管理。
如何管理Nginx服务?
使用systemctl通过systemd控制Nginx,或使用nginx -s直接发送信号。Systemctl是现代Debian和Ubuntu上的标准方式。原生nginx -s命令通过PID文件直接与主进程通信。两种方式都可以。Systemctl更适合自动化和开机启动持久化。
信号与命令对照
| 操作 | systemctl命令 | nginx -s等效命令 | Unix信号 | 对worker的影响 |
|---|---|---|---|---|
| 启动 | sudo systemctl start nginx |
(不适用) | - | 主进程启动,生成worker |
| 停止(优雅) | sudo systemctl stop nginx |
sudo nginx -s quit |
SIGQUIT | worker完成当前请求后退出 |
| 停止(立即) | sudo systemctl kill nginx |
sudo nginx -s stop |
SIGTERM | worker断开连接并退出 |
| 重载配置 | sudo systemctl reload nginx |
sudo nginx -s reload |
SIGHUP | 新worker使用新配置启动。旧worker完成请求后退出。无连接丢失。 |
| 重新打开日志 | (非内置) | sudo nginx -s reopen |
SIGUSR1 | worker重新打开日志文件描述符。用于日志轮转之后。 |
| 开机启动+立即启动 | sudo systemctl enable --now nginx |
(不适用) | - | 创建开机启动链接,立即启动 |
| 禁用+停止 | sudo systemctl disable --now nginx |
(不适用) | - | 移除开机启动链接,立即停止 |
enable --now使Nginx在重启后自动启动,并立即启动服务。始终优先使用此命令而非简单的start。
reload与restart的区别
reload发送SIGHUP。主进程读取新配置,生成新worker,让旧worker排空活跃连接。零停机时间。
restart发送SIGTERM(停止),然后重新启动。所有活跃连接被断开。仅在更改监听端口、加载新模块或升级Nginx二进制文件时使用restart。
重载前务必先测试:
sudo nginx -t && sudo systemctl reload nginx
如果nginx -t失败,重载不会执行。线上配置保持不变。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重载后:
sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-03-20 10:15:32 UTC; 2s ago
Loaded行中的enabled表示它会在开机时启动。在Debian 12和Ubuntu 24.04上从官方仓库安装Nginx
如何测试和检查Nginx配置?
运行nginx -t验证语法而不影响运行中的服务器。运行nginx -T验证并将完整解析后的配置输出到stdout。运行nginx -V查看编译时的模块和参数。
| 命令 | 用途 |
|---|---|
sudo nginx -t |
测试配置语法,检查引用的文件是否存在 |
sudo nginx -t -q |
同样的测试,抑制非错误输出(适用于脚本) |
sudo nginx -T |
测试+将完整解析后的配置输出到stdout |
sudo nginx -V |
显示版本、编译器、configure参数、内置模块 |
sudo nginx -v |
仅显示版本号 |
导出并搜索运行中的配置
sudo nginx -T 2>/dev/null | grep -A5 "server_name example.com"
此命令输出完整配置(所有包含文件合并后),然后过滤特定的server块。当你有几十个include时,这比手动打开文件快得多。
检查已编译的模块
sudo nginx -V 2>&1 | tr ' ' '\n' | grep module
--with-http_ssl_module
--with-http_v2_module
--with-http_realip_module
--with-http_gzip_static_module
--with-http_stub_status_module
如果模块未编译,你就无法使用对应的指令。当某个指令导致"unknown directive"错误时,首先检查这个。
Nginx配置和日志文件在哪里?
在Debian 12和Ubuntu 24.04上,包管理器将所有内容安装在/etc/nginx/下。日志写入/var/log/nginx/。以下是完整的目录结构。
| 路径 | 用途 |
|---|---|
/etc/nginx/nginx.conf |
主配置文件。设置worker数量、events、http块、includes |
/etc/nginx/sites-available/ |
server块文件(可用但不一定已激活) |
/etc/nginx/sites-enabled/ |
指向sites-available的符号链接。Nginx加载这些文件。 |
/etc/nginx/conf.d/ |
附加配置片段。由nginx.conf中默认的include加载 |
/etc/nginx/snippets/ |
可复用的配置片段(SSL参数、安全头) |
/etc/nginx/mime.types |
MIME类型映射 |
/var/log/nginx/access.log |
请求日志 |
/var/log/nginx/error.log |
错误日志 |
/run/nginx.pid |
主进程PID文件 |
启用站点:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
禁用站点:
sudo rm /etc/nginx/sites-enabled/example.com
sudo nginx -t && sudo systemctl reload nginx
有关目录结构的深入说明,请参阅Nginx配置文件结构详解。
最常用的Nginx配置片段有哪些?
以下每个片段都是一个最小可用示例。复制、调整值、用nginx -t测试、重载。各主题的完整指南请通过内部链接查阅。
如何设置基本的server块?
server块(虚拟主机)将域名关联到文档根目录。将以下内容放在/etc/nginx/sites-available/example.com中。
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html;
server_tokens off;
location / {
try_files $uri $uri/ =404;
}
}
server_tokens off隐藏响应头中的Nginx版本。版本泄露会帮助攻击者定位已知漏洞。
创建符号链接到sites-enabled并重载。Nginx 服务器块:在单台 VPS 上托管多个域名
如何将HTTP重定向到HTTPS?
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
return 301比rewrite更快,适用于完整URL重定向。Nginx在访问文件系统之前就处理return。
如何将Nginx配置为反向代理?
将请求转发到运行在3000端口的后端。将以下内容放在HTTPS server块中。
location / {
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;
}
末尾斜杠很重要。 proxy_pass http://127.0.0.1:3000;(无末尾斜杠)传递完整的原始URI。proxy_pass http://127.0.0.1:3000/;(有末尾斜杠)去掉匹配的location前缀。这是许多代理配置出错的根源。
如何启用gzip压缩?
添加到/etc/nginx/nginx.conf的http {}块或snippet文件中:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_types
text/plain
text/css
text/javascript
application/json
application/javascript
application/xml
image/svg+xml;
gzip_min_length 1024跳过小于1 KB的文件。压缩小文件会增加CPU开销而不会显著减小体积。gzip_comp_level 5在压缩率和CPU开销之间取得良好平衡。超过6后收益递减。
如何添加速率限制?
在http {}块中定义一个zone,然后在location或server块中应用。
# In http {} block
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# In server or location block
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://127.0.0.1:8080;
}
$binary_remote_addr每个IPv4地址占用4字节。10 MB的zone可容纳约160,000个地址。burst=20允许短时间的突发流量。nodelay立即处理突发请求而不排队。
如何代理WebSocket连接?
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
proxy_http_version 1.1是必需的。HTTP/1.0不支持Upgrade头。proxy_read_timeout 86400s将空闲WebSocket连接的保持时间从默认的60秒延长到24小时。
如何设置自定义错误页面?
server {
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
root /var/www/errors;
internal;
}
location = /50x.html {
root /var/www/errors;
internal;
}
}
internal指令阻止直接访问错误页面URL。没有它,用户可以直接浏览到/404.html。
如何添加安全头?
创建/etc/nginx/snippets/security-headers.conf:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
在任意server块中包含它:
include snippets/security-headers.conf;
always参数使头信息即使在错误响应(4xx、5xx)中也会添加。没有它,Nginx只在2xx/3xx响应中添加。Ubuntu和Debian上的Nginx安全加固
最小TLS server块
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name 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_prefer_server_ciphers off;
server_tokens off;
# ... location blocks
}
不要启用TLSv1或TLSv1.1。两者都有已知漏洞,且被现代浏览器拒绝。在Debian 12和Ubuntu 24.04上为Nginx配置Let's Encrypt SSL/TLS证书
如何读取和调试Nginx日志?
Nginx默认写入两个日志:access.log记录每个请求,error.log记录问题。两者都在/var/log/nginx/目录下。
实时查看日志
sudo tail -f /var/log/nginx/error.log
或通过journald:
journalctl -u nginx -f
错误日志严重级别
error_log指令接受一个级别。从最详细到最简略:
debug > info > notice > warn > error > crit > alert > emerg
默认级别是error。临时启用调试日志:
error_log /var/log/nginx/error.log debug;
重载Nginx。调试日志非常详细。诊断完问题后请禁用,否则会填满磁盘。
JSON格式的访问日志
结构化日志更容易用jq、Loki或OpenObserve等工具解析。
log_format json_combined escape=json
'{'
'"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /var/log/nginx/access.log json_combined;
调试工具箱
| 命令 | 功能 |
|---|---|
curl -I https://example.com |
仅显示响应头。检查状态码、服务器版本、缓存头。 |
curl -v https://example.com 2>&1 | head -30 |
详细输出:TLS握手、请求/响应头。 |
sudo nginx -T 2>/dev/null | grep server_name |
列出所有配置文件中已配置的server_name。 |
sudo ss -tlnp | grep nginx |
显示Nginx正在监听的端口/地址。 |
sudo ls -la /var/log/nginx/ |
检查日志文件大小和权限。 |
启用stub_status进行监控
location /nginx_status {
stub_status;
allow 127.0.0.1;
allow ::1;
deny all;
}
curl http://127.0.0.1/nginx_status
Active connections: 3
server accepts handled requests
1542 1542 4890
Reading: 0 Writing: 1 Waiting: 2
将stub_status限制为localhost或你的监控IP。它会暴露服务器负载信息。
Nginx错误码代表什么?如何修复?
当Nginx返回HTTP错误时,error.log会告诉你发生了什么。以下是最常见的错误码、含义和修复方法。
| 错误码 | 名称 | 典型error.log消息 | 常见原因 | 修复方法 |
|---|---|---|---|---|
| 403 | Forbidden | directory index of "/var/www/html/" is forbidden |
缺少index文件、文件权限错误、autoindex off(默认) |
添加index.html,修复权限(文件chmod 644,目录755),或启用autoindex on |
| 404 | Not Found | open() "/var/www/html/page" failed (2: No such file or directory) |
root路径错误、try_files错误、文件不存在 |
检查root指令,确认磁盘上的文件路径 |
| 413 | Request Entity Too Large | client intended to send too large body |
上传超过client_max_body_size(默认:1 MB) |
在server或location块中设置client_max_body_size 50m; |
| 502 | Bad Gateway | connect() failed (111: Connection refused) while connecting to upstream |
后端未运行、proxy_pass中端口/socket错误 |
启动后端,检查端口是否与proxy_pass匹配 |
| 503 | Service Unavailable | no live upstreams while connecting to upstream |
upstream块中所有后端都已宕机 |
启动至少一个后端,检查健康检查配置 |
| 504 | Gateway Timeout | upstream timed out (110: Connection timed out) while reading response header |
后端响应太慢 | 增大proxy_read_timeout,优化后端,检查后端日志 |
诊断502错误
502是最常见的代理错误。按以下步骤排查:
# 1. Is the backend running?
sudo ss -tlnp | grep 3000
# 2. Can Nginx reach it?
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:3000/
# 3. What does the error log say?
sudo tail -20 /var/log/nginx/error.log
如果ss在3000端口没有显示任何内容,说明后端已停止。如果curl返回了响应但Nginx返回502,检查socket权限问题(PHP-FPM或Gunicorn Unix socket常见问题)。
最常见的Nginx错误有哪些?
这些错误导致了大多数"我改了配置,现在全坏了"的情况。
缺少分号
每个指令必须以分号结尾。Nginx会给出明确的错误:
nginx: [emerg] unexpected "}" in /etc/nginx/sites-enabled/example.com:12
错误指向缺少分号的下一行,而非问题所在行。往上看一行。
混淆root和alias
# root: appends the location to the path
location /images/ {
root /var/www;
# serves /var/www/images/photo.jpg
}
# alias: replaces the location with the path
location /images/ {
alias /var/www/media/;
# serves /var/www/media/photo.jpg
}
使用alias时,location和alias路径末尾都必须有斜杠。缺少它会导致404错误,且error.log中没有明显原因。
location匹配顺序混淆
Nginx按以下顺序评估location,与它们在配置文件中的位置无关:
= /exact- 精确匹配。最先检查。匹配则立即停止。^~ /prefix- 优先前缀匹配。最长匹配优先。匹配后跳过所有正则。~ regex- 区分大小写的正则。从上到下评估。第一个匹配生效。~* regex- 不区分大小写的正则。同样从上到下。/prefix- 标准前缀匹配。最长匹配优先。仅在没有正则匹配时使用。
前缀匹配看长度,不看配置文件顺序。正则匹配看配置文件顺序,不看长度。不理解这一点就混合使用会导致不可预测的路由。
proxy_pass中的末尾斜杠
# No trailing slash: passes /app/foo to backend as /app/foo
location /app/ {
proxy_pass http://127.0.0.1:3000;
}
# Trailing slash: strips /app/ and passes /foo to backend
location /app/ {
proxy_pass http://127.0.0.1:3000/;
}
选择一种方式并保持一致。大多数后端期望接收完整路径(proxy_pass不带末尾斜杠)。
重载前忘记运行nginx -t
如果用错误的配置重载,Nginx会继续使用旧配置运行并记录一条错误。它不会崩溃。但现在磁盘上的配置与运行中的配置不一致。这会在之后造成困惑。
养成习惯:sudo nginx -t && sudo systemctl reload nginx。&&确保只有测试通过才执行重载。
编辑了sites-available却没创建符号链接
/etc/nginx/sites-available/中的文件不会自动加载。你必须创建符号链接到/etc/nginx/sites-enabled/。直接复制也可以,但符号链接能保持单一可信源。
出了问题?
Nginx行为异常时的快速诊断步骤:
# Check if Nginx is running
sudo systemctl status nginx
# Test the config
sudo nginx -t
# Check which config is actually loaded
sudo nginx -T 2>/dev/null | head -50
# Check the last 30 error log entries
sudo tail -30 /var/log/nginx/error.log
# Check what ports Nginx is listening on
sudo ss -tlnp | grep nginx
# Check file permissions on the web root
sudo ls -la /var/www/example.com/html/
如果服务已失败,journalctl -u nginx --no-pager -n 50可以查看完整信息。查找[emerg]条目。