php错误日志默认不输出到stdout,docker中需将error_log设为/dev/stderr(fpm)或/dev/stdout(cli),并确保log_errors=on、权限正确、fpm启用catch_workers_output=yes且以前台模式运行,才能被docker logs捕获。

PHP错误日志默认不输出到stdout,Docker里就看不见
PHP-FPM或CLI模式下,error_log 默认写入文件(如 /var/log/php_errors.log),而不是标准输出。Docker容器启动后,docker logs 只能捕获进程直接输出到 stdout/stderr 的内容——所以你 docker logs -f 什么也看不到,不是没日志,是它根本没往控制台打。
- 检查 PHP 是否启用了
log_errors = On(php.ini中) - 确认
error_log配置项:若设为文件路径(如/var/log/php/error.log),需确保目录存在、PHP进程有写权限 - 更推荐设为
error_log = /dev/stderr(FPM)或error_log = /dev/stdout(CLI),这样docker logs就能直接看到 - FPM 场景下,还要注意
php-fpm.conf中的error_log(这是 FPM 自身日志,非 PHP 脚本错误)
用 docker exec 进容器查真实日志文件位置
别猜路径,直接进容器看配置:
- 运行
docker exec -it <container_name> sh</container_name> - 执行
php -i | grep error_log,输出类似error_log => /var/log/php/errors.log - 再执行
ls -l /var/log/php/确认文件是否存在、权限是否可写(常见坑:目录不存在,或属主是root,但 PHP-FPM 以www-data运行) - 如果日志文件为空但 PHP 报错,大概率是权限/路径问题,不是没触发错误
PHP-FPM 容器必须重定向 stderr 才能被 docker logs 捕获
FPM 主进程本身不输出错误到 stderr,子进程(worker)的错误默认也不上浮。必须显式配置:
- 在
www.conf或 FPM pool 配置中加:catch_workers_output = yes - 同时确保
php_admin_value[error_log] = /dev/stderr(不是php_value,后者可能被覆盖) - 启动命令别用
php-fpm -D(后台模式),要用php-fpm -F(前台模式),否则主进程退出,容器立刻 stop - 验证:改完重启容器,执行一个触发
E_WARNING的脚本(如file_get_contents('nonexistent')),再docker logs看是否出现
审计日志(如 login、admin 操作)得自己写,PHP 不自动产生
“审计日志”不是 PHP 内置概念,没人帮你记谁什么时候改了密码。这类日志必须代码里主动写:
- 别往
error_log()里塞审计事件——它语义是“出错了”,不是“用户操作了” - 统一用
file_put_contents('/var/log/app/audit.log', $msg . PHP_EOL, FILE_APPEND | LOCK_EX),但要注意并发写入和 logrotate 兼容性 - 更稳妥做法:通过
syslog()写到/dev/log,再由容器外的 syslog daemon 收集(比如 host 上跑 rsyslog,挂载/dev/logsocket) - 如果用 Monolog,配
SyslogHandler或StreamHandler到/dev/stdout,再用 Docker 日志驱动转发到 ELK 或 Loki
真正难的不是找日志,是分清哪条日志属于哪个层级:PHP 解析错误、FPM worker 崩溃、应用逻辑异常、业务审计事件——它们来源不同、落盘位置不同、收集方式也不同。漏掉任意一层,排查时就会卡住。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











