nginx 1.31.8:working_directory 的相对路径不再跟着启动目录走
nginx 1.31.8(2026-10-21)的 CHANGES 里有一条行为变更和一条配套修复:
*) Change: now the path specified in the "working_directory" directive is relative to
nginx prefix directory, but not to the current directory.
*) Bugfix: worker processes exited on start or during reconfiguration if an invalid
directory was specified in the "working_directory" directive.
working_directory 是 core 模块的 main 上下文指令,语法 working_directory directory;,作用是给 worker 进程设置工作目录。它最常见的用途是配合 core dump:进程崩溃时,如果 kernel.core_pattern 是普通路径,内核会按崩溃进程的 cwd 写 core 文件,所以 worker 的 cwd 决定了 core 落在哪。这个目录必须存在且对 worker 用户可写。
相对路径的解析基准从当前目录变成 prefix
1.31.8 之前,working_directory 里的相对路径按进程启动时的当前目录解析。而 nginx 的启动方式决定了这个当前目录是什么:
- systemd 拉起:取决于单元里的
WorkingDirectory,没写就是/,部分发行版的打包会设成/etc/nginx或别的目录; - init 脚本或 supervisor:取决于脚本里有没有
cd; - 手工启动:
cd /usr/local/nginx/sbin && ./nginx,当前目录就是sbin。
于是同一行 working_directory logs/core;,在三台机器上可能分别落到 /logs/core、/etc/nginx/logs/core、/usr/local/nginx/sbin/logs/core。配置文件看起来完全一样,行为不一样,core 文件也就时有时无。
1.31.8 起统一按 nginx prefix 解析。prefix 由编译时的 --prefix 决定,nginx -V 的 configure arguments 里能看到,也可以用启动参数 -p / --prefix 覆盖。
配套的 bugfix 是同一条变更的另一面:working_directory 指向的目录无效时,worker 进程会在启动或 reconfiguration 阶段直接退出,而不是打条警告继续跑。所以升级后如果相对路径在新基准下指向一个不存在的目录,reload 会让 worker 起不来。退出时的具体日志文案这里没有实测;排查时可以直接看 worker 进程是否存活。
升级时查什么
nginx -V,从 configure arguments 里找到--prefix,确认配置里相对路径实际指向哪。- 把
working_directory改成绝对路径。跨机器、跨启动方式都不会飘。 - 验证 worker 实际的 cwd:
ls -l /proc/$(pgrep -f 'nginx: worker')/cwd。 nginx -t只做配置语法与部分路径检查,不会创建目录,缺失目录要自己建。- core 目录 chown 给 worker 运行用户;同时确认
kernel.core_pattern——如果配成|/usr/lib/systemd/systemd-coredump这类管道形式,core 由 coredump 服务接管,不会再落到working_directory里。
配置对照与 systemd 单元
改前,路径取决于启动方式:
# 1.31.8 之前:相对启动时的 cwd,systemd 下大概率是 /logs/core
working_directory logs/core;
改后,路径相对 prefix;假设 --prefix=/usr/local/nginx:
# 等价于 /usr/local/nginx/logs/core
working_directory logs/core;
# 更稳的写法,不依赖 prefix 也不依赖启动目录
working_directory /var/log/nginx/core;
systemd 单元示例:
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
# 1.31.8 起不再影响 working_directory 的相对路径解析,但仍是 master 进程自身的 cwd
WorkingDirectory=/
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -p /usr/local/nginx
ExecStart=/usr/local/nginx/sbin/nginx -p /usr/local/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload -p /usr/local/nginx
ExecStop=/usr/local/nginx/sbin/nginx -s quit -p /usr/local/nginx
[Install]
WantedBy=multi-user.target
建目录并授权:
install -d -o nginx -g nginx -m 0750 /var/log/nginx/core
sysctl kernel.core_pattern
ls -l /proc/$(pgrep -f 'nginx: worker')/cwd
新基准比「跟着启动目录走」可预测得多,代价是以前靠 cwd 隐式生效的配置会暴露出来:升级时要么把路径写成绝对路径,要么确认 prefix 下那个目录真的存在、权限也对。