Nginx速查表:命令、配置片段和错误修复

3 分钟阅读·Matthieu

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 301rewrite更快,适用于完整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前缀。这是许多代理配置出错的根源。

Nginx反向代理配置教程

如何启用gzip压缩?

添加到/etc/nginx/nginx.confhttp {}块或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后收益递减。

VPS上的Nginx性能调优

如何添加速率限制?

http {}块中定义一个zone,然后在locationserver块中应用。

# 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立即处理突发请求而不排队。

Nginx限流与DDoS防护

如何代理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,与它们在配置文件中的位置无关:

  1. = /exact - 精确匹配。最先检查。匹配则立即停止。
  2. ^~ /prefix - 优先前缀匹配。最长匹配优先。匹配后跳过所有正则。
  3. ~ regex - 区分大小写的正则。从上到下评估。第一个匹配生效。
  4. ~* regex - 不区分大小写的正则。同样从上到下。
  5. /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]条目。

Nginx速查表:命令、配置片段和错误修复