Ubuntu 18.04 安装 Nginx 的完整排错链路:apt、systemctl、ufw 与配置验证

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 服务,要经历至少四个状态:

  1. inactive (dead) :服务未运行,也未被激活( systemctl is-active nginx 返回 inactive
  2. activating (start) :systemd 正在 fork 进程、加载配置、绑定端口(短暂过渡态)
  3. active (running) :主进程 PID 已记录,端口已监听(理想状态)
  4. 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

排查链路

  1. 确认命令是否存在 which apt ls /usr/bin/apt 。如果不存在,说明 apt 包确实未安装。
  2. 检查替代命令 which apt-get 。如果 apt-get 存在,说明系统有基础包管理能力。
  3. 验证 apt-get 是否可用 sudo apt-get update 。若失败,检查 /etc/apt/sources.list 格式和源地址。
  4. 安装 apt sudo apt-get install -y apt 。安装后 apt --version 应输出 1.6.14 (Ubuntu 18.04 标准版)。
  5. 根源分析 :此问题 100% 是系统镜像裁剪所致,与 Nginx 无关。但它是整个安装链的起点,必须优先解决。

6.2 报错现象: systemctl status nginx 显示 active (exited)

表象 systemctl start nginx 后,状态是 active (exited) ,而非 active (running) ps aux | grep nginx 看不到进程。

排查链路

  1. 查看详细日志 sudo journalctl -u nginx -p err --since "1 minute ago" 。重点找 exec format error no such file or directory
  2. 检查二进制兼容性 file /usr/sbin/nginx 。Ubuntu 18.04 是 amd64 架构,若输出 ELF 32-bit LSB shared object ,说明你误装了 32 位包(常见于 ARM 设备上误用 x86 镜像)。
  3. 检查依赖库 ldd /usr/sbin/nginx | grep "not found" 。若输出 libpcre.so.3 => not found ,说明 PCRE 库缺失,需 sudo apt install libpcre3
  4. 检查配置语法 sudo nginx -t 。若报错,修正配置后 sudo systemctl daemon-reload 再试。
  5. 根源分析 active (exited) 表示 systemd 认为启动脚本已执行完毕,但主进程未按预期驻留。常见于二进制损坏、动态库缺失、或配置错误导致主进程启动后立即退出。

6.3 报错现象: curl http://服务器IP 超时,但 curl http://localhost 正常

表象 :本地 curl 通,外部 curl 超时, netstat -tuln | grep :80 显示 0.0.0.0:80

排查链路

  1. 确认监听地址 sudo ss -tuln | grep :80 。若显示 127.0.0.1:80 ,说明 Nginx 只监听本地回环,需改 listen 127.0.0.1:80 listen 80
  2. 检查 ufw 状态 sudo ufw status verbose 。若 Status: active 且无 80/tcp 规则,则 sudo ufw allow 'Nginx Full'
  3. 检查云安全组 :登录云平台控制台,确认入站规则放行 TCP:80
  4. 抓包验证 :在服务器上 sudo tcpdump -i any port 80 -nn ,然后从外部 curl 。若 tcpdump 完全无输出,说明请求未抵达服务器(安全组或网络问题);若有输出但无响应,说明 ufw 或 Nginx 拒绝了。
  5. 根源分析 :这是一个典型的“网络层 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,而是为了可追溯。我要求团队每次修改配置,必须:

  1. cd /etc/nginx && sudo git add . && sudo git commit -m "prod: change timeout to 300s"
  2. 修改前备份: sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.$(date +%Y%m%d_%H%M%S)
  3. 使用 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) 错误。永久修改方法:

  1. 编辑 `/etc/systemd
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值