frankenphp自身不支持日志轮转,必须依赖系统logrotate;因caddy的roll参数仅简单重命名,无压缩、清理、句柄刷新机制,高并发下易触发ebusy错误且frankenphp不响应usr1,无法安全reload日志描述符。

FrankenPHP 本身不支持日志轮转,必须用系统 logrotate 配置,否则 access.log 和 error.log 会无限增长直到占满磁盘。
为什么不能用 Caddy 的 roll 参数
Caddy v2.8+ 虽然支持 log 指令里的 roll 100MB,但它只是简单重命名文件,不清理旧日志、不压缩、不刷新写入句柄。高并发下容易出现:
-
EBUSY错误导致日志写入中断 - access.log 停止增长但
access.log.1为空或不更新 - FrankenPHP 不响应
USR1,Caddy 也无法安全 reload 日志文件描述符
logrotate 配置必须含 copytruncate 和 create
FrankenPHP 启动后,Caddy 持续向同一个 inode 写日志。直接 mv 或 rename 会导致写入失败,copytruncate 是唯一安全方案:
-
copytruncate:先复制内容到归档文件,再清空原文件,Caddy 进程无感知、不中断 -
create 644 www-data www-data:确保新日志文件权限正确(CentOS/RHEL 改为apache或nginx) -
rotate 7:比默认 30 更稳妥,防止小容量磁盘撑爆 -
size 50M:按大小触发比daily更适合流量不均的业务
配置路径示例(Debian/Ubuntu):/etc/logrotate.d/frankenphp,内容需匹配 Caddyfile 中 log 指令写的路径,例如:
/var/log/frankenphp/*.log {
daily
size 50M
rotate 7
missingok
notifempty
compress
delaycompress
copytruncate
create 644 www-data www-data
sharedscripts
}
验证 logrotate 是否真正生效
别只看 ls -lh 出现 .log.1 就算成功,要确认三点:
- 手动触发:
sudo logrotate -f /etc/logrotate.d/frankenphp,然后ls -l /var/log/frankenphp/应看到access.log大小归零、access.log.1有内容、属主是www-data - 实时监控写入:
sudo tail -f /var/log/frankenphp/access.log,触发一次请求,确认新日志行立即出现 - 检查 inode:
df -i /var/log,若之前接近 100%,轮转后应明显回落
最容易被忽略的是日志路径一致性:Caddyfile 里写的 log /var/log/frankenphp/access.log,logrotate 配置就必须完全匹配这个路径——差一个斜杠或大小写都会失效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











