1. 为什么 Ubuntu 18.04 上装 Nginx 不是“执行一条命令就完事”?
Nginx 在 Ubuntu 18.04 上的安装,表面看只是
sudo apt install nginx
一行命令的事,但实际踩过的坑远比想象中多。我第一次在客户现场部署时,就因为没注意系统状态,执行完安装命令后
systemctl status nginx
显示 active (exited),服务根本没起来——不是配置错了,而是
apt
根本没装上。后来排查发现,客户给的镜像被裁剪过,连
apt
命令都不存在,终端直接报错
sudo: apt: command not found
。这根本不是 Nginx 的问题,而是底层包管理器缺失导致的连锁失效。
更常见的是环境干扰:比如服务器上已装了 Apache,它默认占用了 80 端口,而 Nginx 启动时也会尝试绑定 80,结果
systemctl start nginx
看似成功,
systemctl status nginx
却显示
failed
,日志里只有一行
bind() to 0.0.0.0:80 failed (98: Address already in use)
。这种错误不会在安装阶段报出,而是在启动环节静默失败,新手往往卡在“明明装好了,为什么打不开网页”这个死循环里。
还有防火墙这一关。Ubuntu 18.04 默认不启用
ufw
,但一旦用户手动开启过,又没放行 HTTP/HTTPS 端口,哪怕 Nginx 进程跑着、端口监听着,外部请求也全被拦在系统边界外。这时候你
curl localhost
能通,但从另一台机器
curl http://你的IP
就超时——你会怀疑是网络、DNS、甚至云服务商安全组的问题,而真正元凶只是
ufw
里缺了一条
sudo ufw allow 'Nginx Full'
。
这些都不是 Nginx 自身的缺陷,而是 Ubuntu 18.04 这个特定发行版生命周期中形成的典型环境特征:它处于 LTS(长期支持)中期,系统组件版本稳定但略旧(如
systemd
237 版本),
apt
仓库结构清晰但需手动更新索引,
ufw
配置逻辑直白却极易遗漏。所以,“安装 Nginx”这件事,在 Ubuntu 18.04 上本质是一次
系统健康度快检 + 服务依赖链验证 + 安全策略对齐
的组合操作,而不是单纯下载二进制文件。
关键词
nginx
、
ubuntu 18.04
、
apt
、
ufw
、
systemctl
并非并列工具名,而是构成一条完整执行路径的五个关键节点:
apt
是入口(获取软件),
systemctl
是中枢(控制生命周期),
ufw
是守门人(决定谁能访问),
nginx
是主体(提供服务),而
ubuntu 18.04
是舞台(定义所有规则与约束)。漏掉其中任一环,整条链就会断裂。接下来我会按这条链的真实执行顺序,把每个节点拆开揉碎讲透,包括那些官方文档里不会写、但你一定会遇到的细节。
2. apt 不是“自带的”,它需要先被确认存在且可用
很多人以为
apt
是 Linux 的标配命令,就像
ls
或
cd
一样天然存在。但在 Ubuntu 18.04 的某些精简镜像(尤其是 Docker 官方 base 镜像、部分云厂商定制 ISO、或运维人员手工裁剪过的系统)中,
apt
是被移除的。它和
apt-get
、
apt-cache
一样,属于
apt
元包的一部分,而这个元包并非最小化安装的必选项。
当你输入
sudo apt update
却收到
sudo: apt: command not found
,这不是权限问题,也不是拼写错误,而是系统压根没装
apt
这个命令行工具。此时
apt-get
往往还存在(因为它是更底层的工具),你可以用它来补救:
sudo apt-get update && sudo apt-get install -y apt
但这里有个陷阱:
apt-get update
本身也可能失败。原因在于
/etc/apt/sources.list
文件可能为空、格式错误,或指向的源已下线。Ubuntu 18.04 的标准源地址是
http://archive.ubuntu.com/ubuntu/
和
http://security.ubuntu.com/ubuntu/
,但国内用户常会替换为阿里云、清华源等镜像站。如果镜像站配置有误(比如少写了
bionic
发行版代号,或协议写成
https
但镜像站不支持),
apt-get update
就会卡在
Reading package lists...
或报
Failed to fetch
错误。
我处理过一个案例:某客户提供的虚拟机镜像里,
sources.list
被改成了
https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
,但该镜像站对 Ubuntu 18.04(代号 bionic)的 HTTPS 支持在 2022 年底已终止,强制走 HTTPS 就会 404。解决方案不是换源,而是把
https
改回
http
:
sudo sed -i 's|https://|http://|g' /etc/apt/sources.list
sudo apt-get update
提示:
apt-get update只是刷新本地包索引,并不下载软件包。它成功与否,直接决定后续apt install nginx能否找到正确的 Nginx 包版本。Ubuntu 18.04 官方仓库中,Nginx 的稳定版本是1.14.0(截至其 ESM 支持结束前),而非最新版。这是刻意为之的设计——LTS 版本追求的是接口稳定、行为可预测,而不是功能新鲜。所以如果你在apt list nginx中看到1.14.0-0ubuntu1.10这样的版本号,说明源配置正确;若看到1.24.x或更高,则极可能是你误加了第三方 PPA 源(如nginx/stable),这在生产环境中应避免,除非你明确需要新特性并承担兼容性风险。
另一个常被忽略的点是
apt
的缓存机制。
apt
会把下载的
.deb
包缓存在
/var/cache/apt/archives/
下。如果磁盘空间不足(尤其
/var
分区满),
apt install
会直接失败,报错
No space left on device
。此时不能只删日志,而要清理 apt 缓存:
sudo apt clean # 删除 /var/cache/apt/archives/ 下所有 .deb
sudo apt autoremove # 卸载不再需要的依赖包
apt clean
和
apt autoclean
的区别在于:前者清空全部缓存,后者只删旧版本包(保留最新版)。在磁盘紧张时,
clean
更彻底。但要注意,清理后下次安装相同软件会重新下载,所以如果是离线环境或带宽受限,建议先
apt download nginx
把包单独保存下来。
最后强调一个实操原则:在任何
apt install
操作前,必须先执行
sudo apt update
。这不是形式主义,而是 Ubuntu 18.04 的包管理逻辑决定的——
apt
不会自动检查远程源更新,它完全依赖本地索引。索引过期超过几天,就可能装到陈旧甚至有已知漏洞的版本(例如早期
1.14.0-0ubuntu1.1
存在 CVE-2019-20372,而
1.14.0-0ubuntu1.10
已修复)。我见过不止一次,因跳过
update
步骤,导致装上的 Nginx 带有 WebDAV 目录遍历漏洞,被扫描器直接标红。
3. systemctl 是服务控制的唯一权威,但它的状态语义必须读懂
在 Ubuntu 18.04 中,
systemctl
是管理所有系统服务的统一接口,取代了老旧的
service
命令和
chkconfig
。但很多从 CentOS 7 迁移过来的运维人员,会下意识用
sudo service nginx start
,这在 Ubuntu 上虽能兼容,但输出信息不完整,且无法体现真正的 systemd 状态机逻辑。
systemctl
的核心价值不在“启动”这个动作,而在
精确描述服务当前所处的状态阶段
。一个服务从安装完成到对外提供 HTTP 服务,要经历至少四个状态:
-
inactive (dead)
:服务未运行,也未被激活(
systemctl is-active nginx返回inactive) - activating (start) :systemd 正在 fork 进程、加载配置、绑定端口(短暂过渡态)
- active (running) :主进程 PID 已记录,端口已监听(理想状态)
-
failed
:启动过程中某个环节出错,systemd 主动标记为失败(
systemctl is-failed nginx返回failed)
关键在于,
active (running)
并不等于“一切正常”。它只表示 Nginx 主进程已 fork 成功并驻留内存,但不保证配置语法正确、不保证端口未被占用、不保证 worker 进程能正常 accept 连接。这就是为什么你常看到
systemctl status nginx
显示
active (running)
,但
curl http://localhost
却返回
Connection refused
。
此时必须深入看日志。
systemctl
提供了精准的日志过滤能力:
# 查看 Nginx 启动时的完整日志流(含启动前的预检)
sudo journalctl -u nginx --since "2 minutes ago" -n 50
# 只看错误级别日志(最高效定位问题)
sudo journalctl -u nginx -p err --since "5 minutes ago"
# 实时跟踪日志(启动后立即执行,观察启动过程)
sudo journalctl -u nginx -f
-p err
参数至关重要。Nginx 启动时,大量 INFO 级日志(如
starting worker processes
)会淹没真正的错误。而真正的致命错误,比如配置文件语法错误,会以
ERROR
级别打出:
nginx: [emerg] unknown directive "locationx" in /etc/nginx/sites-enabled/default:23
或者端口冲突:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
注意:
systemctl status nginx输出的Loaded:行会显示配置文件路径(如/lib/systemd/system/nginx.service),而Active:行后的括号里是状态摘要。但摘要只是结论,日志才是证据。我坚持一个原则:只要systemctl status nginx没显示active (running),或显示failed,第一反应不是重试start,而是journalctl -u nginx -p err。90% 的启动失败问题,日志里三行内就能定位。
另一个易混淆点是
reload
和
restart
的区别。
sudo systemctl reload nginx
会向主进程发送
SIGHUP
,要求它重新读取配置并平滑切换 worker,期间旧连接继续处理,新连接由新配置接管——这是线上变更的标准操作。而
sudo systemctl restart nginx
是先
stop
再
start
,会造成秒级服务中断。Ubuntu 18.04 的
nginx.service
文件里,
ExecReload
默认指向
/usr/sbin/nginx -s reload
,这是安全的;但如果你手动改过
ExecStart
,或用了自定义脚本,
reload
可能失效,必须用
restart
。判断依据很简单:执行
reload
后,
ps aux | grep nginx
应该显示主进程 PID 不变,worker 进程 PID 变化;若主进程 PID 也变了,说明
reload
实际退化成了
restart
。
最后提醒一个 systemd 的隐藏机制:
WantedBy=multi-user.target
。这是
nginx.service
文件里的关键行,它定义了 Nginx 的启动时机——当系统进入多用户模式(即常规的命令行登录状态)时,自动启动 Nginx。这意味着,如果你用
sudo systemctl disable nginx
关闭了开机自启,那么即使你手动
start
了一次,重启服务器后 Nginx 也不会自动起来。而
enable
操作的本质,是在
/etc/systemd/system/multi-user.target.wants/
下创建一个指向
/lib/systemd/system/nginx.service
的软链接。你可以用
ls -l /etc/systemd/system/multi-user.target.wants/ | grep nginx
来验证是否生效。这个细节决定了你的部署是临时测试还是生产就绪。
4. ufw 防火墙不是“可有可无的装饰”,它是 Ubuntu 18.04 的默认守门人
Ubuntu 18.04 的一大特点是,默认安装后
ufw
(Uncomplicated Firewall)是禁用状态,但它被深度集成进系统,且是官方推荐的防火墙管理工具。很多人装完 Nginx,
systemctl status nginx
显示
active (running)
,
curl localhost
也通,就以为大功告成,结果从公司电脑
curl http://服务器IP
却超时——第一反应是查云服务商安全组,却忘了本地
ufw
这道门。
ufw
的设计哲学是“默认拒绝,显式允许”。它不像 iptables 那样需要写复杂规则,而是用自然语言式的命令管理。但正因简单,反而容易被忽视其存在。验证
ufw
状态只需一行:
sudo ufw status verbose
如果输出
Status: inactive
,说明防火墙没开,Nginx 流量畅通无阻;如果输出
Status: active
,则必须检查
Rules
部分是否放行了 HTTP/HTTPS。
ufw
的规则是按顺序匹配的,第一条匹配即生效。默认规则链里,
22/tcp
(SSH)通常被允许,但
80/tcp
和
443/tcp
是拒绝的。所以即使 Nginx 进程在跑、端口在监听,外部请求也会被
ufw
在内核层直接丢弃,
netstat -tuln | grep :80
看得到监听,
tcpdump -i any port 80
却抓不到入站包——这就是
ufw
在起作用。
放行 HTTP 的标准命令是:
sudo ufw allow 'Nginx Full'
这个
'Nginx Full'
是
ufw
内置的应用配置文件名,它等价于同时放行
80/tcp
和
443/tcp
。你也可以手动指定:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
但注意,
sudo ufw allow samba command not found
这类错误提示,往往是因为用户把
ufw
命令和
samba
命令混写了。
ufw
不认识
samba
,它只认端口、协议或应用配置名。正确做法是分开执行:先
sudo ufw allow 'Samba'
(放行 SMB),再
sudo ufw allow 'Nginx Full'
(放行 Nginx)。
提示:
ufw规则修改后无需重启服务,它会实时生效。但有一个例外:如果你之前ufw enable过,后来ufw disable了,再ufw enable时,它会重新加载所有规则。所以ufw的状态切换是即时的,没有“配置未生效”的概念。
更隐蔽的问题是 IPv6。Ubuntu 18.04 默认启用 IPv6,而
ufw
的规则默认只作用于 IPv4。如果你的服务器有 IPv6 地址,且
ufw
只放行了 IPv4 的 80 端口,那么通过 IPv6 访问
http://[2001:db8::1]
依然会被拒绝。验证方法是:
# 查看 IPv6 规则(ufw 默认不显示,需显式指定)
sudo ufw status verbose | grep -A 10 "IPv6"
# 或直接查内核规则
sudo ip6tables -L ufw-user-input -v
解决方案是启用
ufw
的 IPv6 支持:编辑
/etc/default/ufw
,将
IPV6=yes
取消注释。然后
sudo ufw disable && sudo ufw enable
重载规则。此时
ufw allow 'Nginx Full'
会同时生成 IPv4 和 IPv6 规则。
还有一个实战技巧:
ufw
的日志默认是关闭的,但开启后对排错极有帮助。编辑
/etc/ufw/ufw.conf
,设
LOGLEVEL=low
,然后
sudo ufw logging on
。日志会写入
/var/log/ufw.log
,里面会记录所有被拒绝的连接,格式如:
[UFW BLOCK] IN=ens3 OUT= MAC=... SRC=192.168.1.100 DST=192.168.1.101 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=59091 DF PROTO=TCP SPT=52123 DPT=80 WINDOW=64800 RES=0x00 ACK SYN URGP=0
看到
UFW BLOCK
就知道是防火墙拦截,而非 Nginx 本身问题。这能帮你快速区分:是“服务没起来”,还是“服务起来了但被拦住了”。
最后强调:
ufw
和云服务商的安全组是两层独立防护。安全组是云平台的虚拟防火墙,作用于主机网卡之外;
ufw
是操作系统内的防火墙,作用于网卡之内。两者是“与”关系,必须同时放行,流量才能抵达 Nginx。所以排错时,务必按顺序检查:云安全组 → 本地
ufw
→ Nginx 进程状态 → Nginx 配置语法。
5. Nginx 本身不是黑盒,它的安装、验证与最小化配置必须亲手过一遍
安装 Nginx 的最终目的,不是让
systemctl status
显示绿色,而是让一个 HTTP 请求能完整走通:客户端发请求 → 网络层抵达服务器 →
ufw
放行 → Nginx 进程接收 → 解析配置 → 返回响应。任何一个环节断开,整个链路就失效。因此,安装完成后,必须进行一套标准化的“四步验证法”。
5.1 第一步:确认二进制与配置文件位置
Ubuntu 18.04 通过
apt
安装的 Nginx,其文件布局是严格遵循 Debian/Ubuntu FHS(文件系统层次标准)的:
-
主程序:
/usr/sbin/nginx(注意是sbin,非bin,表示系统管理程序) -
主配置文件:
/etc/nginx/nginx.conf(全局设置,如 worker 进程数、日志路径) -
站点配置目录:
/etc/nginx/sites-available/(存放所有可能启用的站点配置,如default) -
启用的站点链接:
/etc/nginx/sites-enabled/(通常是sites-available中文件的软链接)
验证命令:
# 检查主程序是否存在且可执行
ls -l /usr/sbin/nginx
# 检查主配置文件语法(这是启动前的必做检查)
sudo nginx -t
# 查看当前启用的站点(输出应包含 default)
ls -l /etc/nginx/sites-enabled/
sudo nginx -t
是灵魂命令。它不启动服务,只做两件事:1)检查
/etc/nginx/nginx.conf
语法是否正确;2)递归检查
include
进来的所有文件(如
sites-enabled/*
)。如果输出
syntax is ok
和
test is successful
,说明配置无硬性错误;若报错,会精确指出哪一行、哪个文件有问题。这是比
systemctl start
更早、更轻量的验证手段。
5.2 第二步:理解默认配置的“最小工作集”
Ubuntu 18.04 的默认
default
站点配置(
/etc/nginx/sites-available/default
)是一个教学模板,但其中很多内容在生产中是冗余甚至危险的。我们来逐行解构其核心骨架:
server {
listen 80 default_server; # 监听 80 端口,且是 default_server(兜底)
listen [::]:80 default_server; # 同时监听 IPv6 的 80 端口
root /var/www/html; # 网站根目录
index index.html index.htm index.nginx-debian.html; # 默认首页文件列表
server_name _; # 匹配任意未声明的 server_name(兜底)
location / { # 匹配所有请求
try_files $uri $uri/ =404; # 先找文件,再找目录,都找不到返回 404
}
}
这个配置能工作的关键,在于
root /var/www/html
和
index
指令。
/var/www/html
目录下必须有
index.html
文件,否则
try_files
会一路走到
=404
。Ubuntu 安装后,
apt
会自动创建这个文件,内容就是经典的 “Welcome to nginx!” 页面。你可以用
curl -I http://localhost
查看响应头,确认
HTTP/1.1 200 OK
。
但注意:
server_name _;
这行意味着,无论你在浏览器输什么域名(哪怕是错的),只要指向这台服务器,Nginx 都会用这个
server
块处理。这是开发测试的便利,但生产中应明确指定
server_name yourdomain.com;
,并确保 DNS 解析正确。
5.3 第三步:手动触发一次“冷启动”全流程
不要依赖
systemctl start nginx
的黑盒行为。我习惯手动走一遍 Nginx 的启动流程,以建立肌肉记忆:
# 1. 停止所有 nginx 进程(确保干净)
sudo pkill nginx
# 2. 手动执行主程序(前台运行,便于观察输出)
sudo /usr/sbin/nginx -c /etc/nginx/nginx.conf -g "daemon off;"
# 3. 在另一个终端 curl 测试
curl -I http://localhost
# 4. Ctrl+C 结束前台进程
-g "daemon off;"
参数强制 Nginx 在前台运行,不 fork 到后台。这样你能实时看到启动日志,比如:
2024/05/20 10:23:45 [info] 12345#12345: using the "epoll" event method
2024/05/20 10:23:45 [info] 12345#12345: start worker processes
2024/05/20 10:23:45 [info] 12345#12345: start worker process 12346
如果这里报错,比如
open() "/var/run/nginx.pid" failed (2: No such file or directory)
,说明
pid
文件路径在
nginx.conf
里配置了,但目录
/var/run/
下没有
nginx
子目录。这时要手动创建:
sudo mkdir -p /var/run/nginx
。这种细节,
systemctl
会帮你处理,但手动执行能暴露所有隐性依赖。
5.4 第四步:用真实请求验证端到端链路
最后,用一个跨机器的真实请求收尾。假设你的 Ubuntu 18.04 服务器 IP 是
192.168.1.100
,在另一台机器上执行:
# 1. 检查网络连通性(排除基础网络问题)
ping -c 3 192.168.1.100
# 2. 检查端口是否可达(绕过应用层,只测 TCP 握手)
nc -zv 192.168.1.100 80
# 3. 发送 HTTP 请求(最终验证)
curl -v http://192.168.1.100
nc -zv
是关键。如果
ping
通但
nc
不通,99% 是
ufw
或安全组问题;如果
nc
通但
curl
返回
Connection refused
,则是 Nginx 没监听或监听了错误地址(如只监听
127.0.0.1
);如果
curl -v
能看到完整的 HTTP 头和响应体,恭喜,你的 Nginx 已经真正活了。
经验之谈:我给自己定了一条铁律——任何 Nginx 部署,必须在
systemctl start nginx之后,立刻执行curl -v http://localhost和curl -v http://服务器IP两次。前者验证进程和配置,后者验证网络和防火墙。少一次,就少一层保障。这条规矩帮我避开了至少二十次上线事故。
6. 常见故障的完整排查链路:从报错信息反推根因
在 Ubuntu 18.04 上部署 Nginx,最常见的不是“装不上”,而是“装上了但用不了”。这类问题往往表现为一个模糊的错误现象,背后却有多个可能的根因。下面我以三个高频报错为例,展示如何像侦探一样,沿着线索一步步定位真相。
6.1 报错现象:
sudo: apt: command not found
表象
:执行
sudo apt update
时,终端直接报
sudo: apt: command not found
。
排查链路 :
-
确认命令是否存在
:
which apt或ls /usr/bin/apt。如果不存在,说明apt包确实未安装。 -
检查替代命令
:
which apt-get。如果apt-get存在,说明系统有基础包管理能力。 -
验证 apt-get 是否可用
:
sudo apt-get update。若失败,检查/etc/apt/sources.list格式和源地址。 -
安装 apt
:
sudo apt-get install -y apt。安装后apt --version应输出1.6.14(Ubuntu 18.04 标准版)。 - 根源分析 :此问题 100% 是系统镜像裁剪所致,与 Nginx 无关。但它是整个安装链的起点,必须优先解决。
6.2 报错现象:
systemctl status nginx
显示
active (exited)
表象
:
systemctl start nginx
后,状态是
active (exited)
,而非
active (running)
。
ps aux | grep nginx
看不到进程。
排查链路 :
-
查看详细日志
:
sudo journalctl -u nginx -p err --since "1 minute ago"。重点找exec format error或no such file or directory。 -
检查二进制兼容性
:
file /usr/sbin/nginx。Ubuntu 18.04 是 amd64 架构,若输出ELF 32-bit LSB shared object,说明你误装了 32 位包(常见于 ARM 设备上误用 x86 镜像)。 -
检查依赖库
:
ldd /usr/sbin/nginx | grep "not found"。若输出libpcre.so.3 => not found,说明 PCRE 库缺失,需sudo apt install libpcre3。 -
检查配置语法
:
sudo nginx -t。若报错,修正配置后sudo systemctl daemon-reload再试。 -
根源分析
:
active (exited)表示 systemd 认为启动脚本已执行完毕,但主进程未按预期驻留。常见于二进制损坏、动态库缺失、或配置错误导致主进程启动后立即退出。
6.3 报错现象:
curl http://服务器IP
超时,但
curl http://localhost
正常
表象
:本地
curl
通,外部
curl
超时,
netstat -tuln | grep :80
显示
0.0.0.0:80
。
排查链路 :
-
确认监听地址
:
sudo ss -tuln | grep :80。若显示127.0.0.1:80,说明 Nginx 只监听本地回环,需改listen 127.0.0.1:80为listen 80。 -
检查 ufw 状态
:
sudo ufw status verbose。若Status: active且无80/tcp规则,则sudo ufw allow 'Nginx Full'。 -
检查云安全组
:登录云平台控制台,确认入站规则放行
TCP:80。 -
抓包验证
:在服务器上
sudo tcpdump -i any port 80 -nn,然后从外部curl。若tcpdump完全无输出,说明请求未抵达服务器(安全组或网络问题);若有输出但无响应,说明ufw或 Nginx 拒绝了。 -
根源分析
:这是一个典型的“网络层 vs 应用层”混淆问题。
localhost走回环接口,绕过了ufw和安全组;而外部 IP 走物理网卡,必须经过所有中间环节。排查必须按“安全组 → ufw → Nginx 监听地址”顺序进行,不可跳跃。
这三条链路,覆盖了 Ubuntu 18.04 上 Nginx 部署 80% 的真实故障场景。它们的共同点是:
不迷信单一命令的输出,而是用一组相互印证的命令,构建一个完整的证据闭环
。
systemctl status
是起点,
journalctl
是放大镜,
ss
/
tcpdump
是透视仪,
curl
是最终裁判。掌握这套方法,你就不需要背诵错误代码,而是能自己推理出答案。
7. 生产就绪的加固要点:不只是“能用”,更要“稳用”
在 Ubuntu 18.04 上让 Nginx “能用” 可能只需 5 分钟,但让它“稳用”则需要额外的 50 分钟。这些加固措施不改变核心功能,却极大提升了系统的健壮性和可维护性。以下是我在上百个生产环境中沉淀下来的五条硬性规范。
7.1 配置文件版本化管理
/etc/nginx/
目录下的所有文件,必须纳入 Git 版本控制。不是为了 fancy,而是为了可追溯。我要求团队每次修改配置,必须:
-
cd /etc/nginx && sudo git add . && sudo git commit -m "prod: change timeout to 300s" -
修改前备份:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.$(date +%Y%m%d_%H%M%S) -
使用
nginx -t验证后再systemctl reload nginx
这样,当某天凌晨 3 点报警说 502 错误激增,你可以
git log -p
一眼看出,是 2 小时前谁改了
proxy_pass
地址。没有版本控制的配置,就像没有刹车的汽车。
7.2 日志轮转必须启用
Ubuntu 18.04 的
logrotate
默认会管理 Nginx 日志,但需确认
/etc/logrotate.d/nginx
文件存在且内容正确。关键参数:
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
prerotate
中的
kill -USR1
是精髓:它通知 Nginx 主进程重新打开日志文件,实现无缝切割。没有这行,
logrotate
会直接 mv 文件,而 Nginx 还往旧文件句柄里写,导致磁盘空间不释放。
7.3 worker 进程数设为 auto
/etc/nginx/nginx.conf
中的
worker_processes
默认是
1
,这在多核 CPU 上是巨大浪费。应改为:
worker_processes auto;
auto
指令会让 Nginx 自动检测 CPU 核心数,并启动对应数量的 worker 进程。Ubuntu 18.04 的
systemd
会为每个 worker 分配独立的 cgroup,避免单核过载。实测在 4 核服务器上,
auto
比
1
提升吞吐量 300%。
7.4 禁用不必要的模块
Ubuntu 18.04 的
nginx-full
包默认编译了所有模块,包括
ngx_http_perl_module
、
ngx_http_xslt_module
等。生产环境几乎用不到,却增加了攻击面。检查已加载模块:
/usr/sbin/nginx -V 2>&1 | grep -o with-http.*_module
若看到
with-http-perl-module
,说明 Perl 模块已编译。虽然不启用就无害,但最佳实践是重装
nginx-light
包(只含核心模块):
sudo apt install nginx-light
。它体积小、依赖少、攻击面窄,是生产首选。
7.5 设置合理的 ulimit
Nginx 默认的文件描述符限制(
ulimit -n
)是 1024,这在高并发场景下远远不够,会导致
accept() failed (24: Too many open files)
错误。永久修改方法:
- 编辑 `/etc/systemd
1494

被折叠的 条评论
为什么被折叠?



