Nginx 安装与部署
安装与部署
Nginx 的安装包在各大发行版官方仓库里都有,优先用包管理器装,好处是 systemd 单元、日志轮转、目录结构都帮你配好了。
Debian / Ubuntu(apt)
sudo apt update
sudo apt install -y nginx
systemctl enable --now nginx
systemctl status nginx
如果仓库里的版本太旧,可以加 Nginx 官方源再装:
sudo apt install -y curl gnupg2 ca-certificates lsb-release
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update && sudo apt install -y nginx
CentOS / Rocky / AlmaLinux(yum / dnf)
sudo yum install -y epel-release
sudo yum install -y nginx
sudo systemctl enable --now nginx
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Docker 运行
容器方式适合本地开发或需要固定版本的环境。注意配置和静态文件通过挂载进去,日志建议走 stdout。
docker run -d --name nginx \
-p 80:80 -p 443:443 \
-v /srv/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /srv/nginx/conf.d:/etc/nginx/conf.d:ro \
-v /srv/www:/usr/share/nginx/html:ro \
-v /srv/certs:/etc/nginx/certs:ro \
nginx:stable
如果后端服务也在 Docker 里,记得让 Nginx 和后端加入同一个自定义网络,然后 proxy_pass 里直接用服务名(Docker 内建 DNS 会把服务名解析到容器 IP)。不要用 localhost,在容器里那指的是 Nginx 自己。
目录结构
| 路径 | 说明 |
|---|---|
/etc/nginx/nginx.conf | 主配置。定义 worker、日志格式、http 块,并 include 其他配置。 |
/etc/nginx/conf.d/*.conf | Debian 和 RHEL 系都默认 include 的目录,放独立站点配置最方便。 |
/etc/nginx/sites-available/ 与 /etc/nginx/sites-enabled/ | Debian / Ubuntu 特有。站点配置写在 available,软链到 enabled 才生效;主配置里 include 的是 enabled。 |
/var/log/nginx/ | access.log 与 error.log,排查问题第一站。 |
/usr/share/nginx/html | 默认站点根目录,通常替换掉。 |
校验与平滑重载
改完配置永远先检查语法再 reload,这是最省事的一条纪律。语法错误的配置若直接 reload,Nginx 会拒绝加载并继续用旧配置跑,但一旦重启就起不来了。
nginx -t # 检查配置语法与引用文件
nginx -T # 打印合并后的完整配置,排查 include 顺序很有用
nginx -v # 查看版本与编译参数
nginx -s reload # 平滑重载:老 worker 处理完存量请求再退出
systemctl reload nginx # 走 systemd 的等价写法
reload 的原理是 master 进程重新读取配置、启动一批新 worker,同时通知老 worker 停止接收新连接、处理完手头请求后退出。所以连接不会断,但已经建立的 WebSocket 长连接不会迁移,会有短暂重连。
系统调优
Nginx 默认配置在压测或高并发下通常不够用,必调的有这几处:
worker_processes auto; # 一般等于 CPU 核数,auto 会自动检测
worker_rlimit_nofile 65535; # 每个 worker 能打开的文件描述符上限
events {
worker_connections 10240; # 每个 worker 的最大并发连接数
multi_accept on;
use epoll;
}
http {
sendfile on; # 零拷贝发静态文件
tcp_nopush on; # 配合 sendfile,攒够一个包再发
tcp_nodelay on; # 长连接下禁用 Nagle 算法,降延迟
keepalive_timeout 65;
client_max_body_size 20m; # 上传限制,见下文 413 排查
}
系统层面还要放开文件描述符与连接队列。systemd 管理的 Nginx 需要在单元文件里加 LimitNOFILE=65535(或写 drop-in 覆盖),只改 ulimit -n 对 systemd 服务无效。内核参数方面,net.core.somaxconn(accept 队列长度)和 net.ipv4.tcp_max_syn_backlog(半连接队列)在高并发下建议调大,具体数值要结合机器规格压测确定,以官方文档与内核文档为准,不要照搬网上随手抄的数字。
另外 worker_connections 和 worker_rlimit_nofile 是配套的:每个连接占一个文件描述符,反向代理场景下一条客户端连接还会占一条到后端的连接,所以理论上限是 worker_processes × worker_connections / 2。这两个值调不上去,Nginx 会在 error.log 里报 worker_connections are not enough 或 too many open files。
常见报错与排查
| 现象 | 常见原因 | 排查方向 |
|---|---|---|
| 502 Bad Gateway | 后端没起来、端口不对、后端崩溃 | 先 curl 后端地址直连,再看 error.log 里的 connect() failed (111: Connection refused) 或 upstream prematurely closed connection |
| 504 Gateway Timeout | 后端处理超时,超过 proxy_read_timeout 默认 60s | 长任务要单独放宽 proxy_read_timeout / proxy_send_timeout,或把任务改成异步 |
| 413 Request Entity Too Large | 请求体超过 client_max_body_size(默认 1m) | 在 http / server / location 对应层级调大;注意后端框架自身也有 upload 限制,两边都要改 |
conflicting server name | 同一 listen 端口下有两个 server 用了相同 server_name | warning 级别,Nginx 会用先出现的那个。用 nginx -T 搜出重复域名,检查是否有残留站点配置 |
directive is not allowed here | 指令写在了错误的 context | 看指令文档里的 Context 一行,挪到允许的层级 |
| 改完配置不生效 | 忘了 reload,或改了没被 include 的文件 | nginx -T 确认生效的配置里有没有你的改动 |
排查顺序建议固定成:nginx -t → 看 error.log 尾部 → curl 直连后端 → 用 curl -H "Host: 域名" http://127.0.0.1/ 绕过 DNS 验证本机匹配规则。这四步能定位绝大多数问题。

