VPS 的磁盘忽然满了,先看看 Nginx 的 access.log 和 error.log。如果它们一直增长却没有归档,删除旧备份只能暂时腾出空间;还应检查日志轮转任务是否运行,以及 Nginx 是否在轮转后打开了新文件。
下面使用宿主机安装的 Nginx 和 logrotate,示例日志目录为 /var/log/nginx。容器把日志写到标准输出、面板管理独立日志目录,或机器上有多个 Nginx 实例时,要按各自的日志和进程管理方式处理,不能照抄目录与 PID 文件。
改名之后,Nginx 还可能写旧文件
Nginx 已经打开了日志文件。执行 mv 改名不会让这个文件描述符自动指向新的 access.log,进程仍可能往改名后的文件写。直接删除一个仍被进程打开的文件,也可能无法立即释放它占用的磁盘空间。
正常轮转先改名,再向 Nginx 主进程发送 USR1,让它重新打开日志。这个动作不需要为轮转而重启整个服务;HUP 用于重载配置,与 USR1 的用途不同。Nginx 控制文档说明了两种信号的区别。
先检查系统已经提供的规则
发行版安装包可能已放入 /etc/logrotate.d/nginx。先读它,并检查其他配置是否也匹配同一批日志;不要另外新建一个规则,让两个任务轮转相同文件。还要核对 Nginx 实际的日志路径、运行用户和 pid 设置。
以下是规则示例,适用于日志位于 /var/log/nginx、worker 使用 www-data、系统存在 adm 组、主进程 PID 文件为 /run/nginx.pid 的机器。保存前把不符合本机的值改掉;PID 文件应位于可信目录,由服务正确维护。
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -s /run/nginx.pid ]; then
pid=$(cat /run/nginx.pid) || exit 1
case "$pid" in
''|*[!0-9]*|0|1) exit 1 ;;
esac
kill -USR1 "$pid"
fi
endscript
}
脚本先读取并检查 PID,再发送信号,读取失败或 PID 明显不合法时不继续执行。PID 文件缺失时会跳过信号,但跳过不等于轮转完成:如果 Nginx 实际仍在运行,就应查明路径为什么不对。不要用 || true 把所有发送信号的错误都隐藏掉。
create 的用户、组和权限要与本机设置匹配。delaycompress 延后一轮压缩最新归档,给仍可能写旧文件的进程留出时间,但它不能补救错误的 PID 文件或一直没有执行的重新打开操作。各选项可以查 logrotate 手册,并以机器安装版本的 man logrotate 为准。
daily 与 rotate 14 不是磁盘限额
daily 指定按日判断轮转条件,不会创建定时任务。机器仍需要 cron 或 systemd timer 定期调用 logrotate。rotate 14 保留的是轮转次数,不能无条件解释成十四天;空日志不轮转、任务漏跑或增加大小触发条件,都会改变归档覆盖的时间。
如果日志一天就能撑满磁盘,仅设 daily 不够。可以评估与时间条件配合的 maxsize,但它也要等 logrotate 被调用时才检查,不是实时硬限额。提高检查频率后,还要重新计算保留次数,防止同一天轮转多次使旧日志提前删除。
不要把 copytruncate 当成无需通知 Nginx 的通用替代。复制与截断之间存在日志丢失的窗口。能正常重新打开日志的 Nginx,优先沿用改名加 USR1 的流程。
如果正在选 VPS,除了 CPU 和内存,也要给日志、上传文件与备份分别留出容量。可以从 雨云查看云服务器配置,优惠码 KuZhuJi;具体优惠资格和价格以购买页面为准。轮转减少日志积累,但不会增加套餐本身的磁盘空间。
检查规则,也检查定时任务
修改后先用调试模式看规则。下面假定系统已使用 /etc/logrotate.conf 作为主配置;调试模式不会实际轮转或更新状态文件:
sudo logrotate -d /etc/logrotate.conf
观察是否读取了 Nginx 规则、是否提示重复匹配、目录权限错误,以及状态文件中记录的轮转时间。使用 systemd timer 的系统还可以检查:
systemctl list-timers --all logrotate.timer
systemctl status logrotate.timer
journalctl -u logrotate.service --since today
没有这个 timer 时,检查本机 cron 或面板的调度安排,不能据此直接断定没有定时任务。容器内安装了 logrotate,也不代表容器会启动 cron。
需要实际验证轮转时,先保留配置,并安排合适的维护时间。-f 会强制执行,别把它放进每小时巡检,也不要不加区分地强制轮转所有服务。若仅验证 Nginx 规则,应先确认该文件包含所需设置,并了解它脱离主配置后不会自动获得主配置里的全局选项。
sudo logrotate -v -f /etc/logrotate.d/nginx
轮转后发起一条正常访问,确认它进入新日志,再核对新文件的所有者与权限、旧文件是否继续增长,以及任务输出是否报告错误。归档存在,只能说明文件被处理过;新请求确实写入新文件,才说明重新打开这一步生效。
定期检查磁盘余量和归档覆盖时间。日志可能含 URL 参数、IP 地址或其他敏感信息,归档同样需要限制读取权限;需要保留审计记录时,另行安排符合保留要求的存储,不能靠本机十四次轮转承担长期归档。











