Nginx-proxy docker 接收来自 php-fpm docker 的 stderr 输出(导致 502 错误)

Posted

技术标签:

【中文标题】Nginx-proxy docker 接收来自 php-fpm docker 的 stderr 输出(导致 502 错误)【英文标题】:Nginx-proxy docker receives stderr output from php-fpm docker (resulting in 502 errors) 【发布时间】:2021-05-08 04:05:33 【问题描述】:

我有一个(非常标准的)设置,其中 nginx-proxy 提供静态文件并将 php 请求发送到 php-fpm docker。 compose文件的简化版:

services:
  php:
    image: php:7-fpm-alpine
    volumes:
      - ./my-src:/var/www
  web:
    image: nginx:alpine
    volumes:
      - ./my-src:/var/www
    ports:
      - "80:80"

现在,每当我请求一个 php 页面时,通知都会被转储到 php docker 的标准错误中:

NOTICE: PHP message: [info] Matched route "game_index".
NOTICE: PHP message: [debug] Checking for authenticator support.
NOTICE: PHP message: [debug] Checking support on authenticator.
[...]
NOTICE: PHP message: [debug] Notified event "kernel.finish_request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleAwareListener::onKernelFinishRequest".
NOTICE: PHP message: [debug] Notified event "kernel.terminate" to listener "Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelTerminate".
172.18.0.2 -  03/Feb/2021:20:20:20 +0000 "GET /index.php" 200

这很好,符合预期。但是,这些消息也会出现在 nginx 的 docker 日志中

2021/02/03 20:20:20 [error] 7#7: *8 FastCGI sent in stderr: "PHP message: [info] Matched route "game_index".
PHP message: [debug] Checking for authenticator support.
PHP message: [debug] Checking support on authenticator.
[...]
PHP message: [debug] Notified event "kernel.finish_request" to listener "Symfony\Bundle\SecurityBundle\Debug\TraceableFirewallListener::onKernelFinishRequest".
PHP message: [debug] Notified event "kernel.finish_request" to listener "Symfony\Component\HttpKernel\EventListener\LocaleAwareListener::onKernelFinishRequest"" while reading response header from upstream, client: 172.18.0.1, server: , request: "GET /game/ HTTP/1.1", upstream: "fastcgi://172.18.0.3:9000", host: "localhost"
172.18.0.1 - - [03/Feb/2021:20:20:20 +0000] "GET /game/ HTTP/1.1" 200 437 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0" "-"

这会导致错误,如果文本过长,则会出现 502 Bad Gateway。在开发中,Symfony 很健谈,我经常遇到这个 502。在 prod 中,问题消失了,但我想解决根本原因。

如果我调整/usr/local/etc/php-fpm.d/docker.conf 中的设置,因此error_log 和access.log 不是默认指向/proc/self/fd/2,而是指向/dev/null,php docker 会静默,但nginx docker 仍然返回错误.

如果我按照建议的here 将文件指向/proc/self/fd/2,则两个日志都会像以前一样被填满。

如何确保 php docker 中的日志保持不变,但 stderr 没有发送到 nginx?

(刚刚在另一个线程中成功测试了完整的解决方案:按照那里的建议将log_limit 设置为 1024 并劝阻here 实际上阻止了 502 的发生。不过,在此设置中,stderr 输出似乎处理得不好)

[编辑] 根据 Ilia Yatsenko 的评论,我将其添加到 Dockerfile:

RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
RUN echo 'fastcgi.logging=0' >> "$PHP_INI_DIR/php.ini"

【问题讨论】:

遇到了同样的问题,找到了合理的解决方法。此处描述:https://***.com/a/68314973/6051839. 谢谢!这对我也有帮助,我会在问题中编辑它 【参考方案1】:

自从我在 Docker 设置中配置 alpine php-fpm 已经有一段时间了,但如果我没记错的话,我必须对默认的 php-fpm.conf 进行一些覆盖。

这是我在类似设置中所拥有的......当构建图像时,配置被复制到/etc/php7/php-fpm.conf

[www]
listen = 127.0.0.1:9000
clear_env = no

; if we send this to /proc/self/fd/1, it never appears
access.log = /dev/stdout

; Ensure worker stdout and stderr are sent to the main error log.
catch_workers_output = yes
decorate_workers_output = no

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

[global]
error_log = /dev/stdout

【讨论】:

好吧,感觉很奇怪——将错误(和通知)写入标准输出会使它们出现在页面中,不是吗?我试试看,谢谢! 我的假设是错误的,确认我并不真正了解 docker 中的文件描述符。但是,docker 日志现在是静默的,并且 nginx 502 有时会重新出现,并出现错误“[error] 7#7: *6 upstream sent too big header while reading response header from upstream”, 复制您的确切文件并没有解决问题。

以上是关于Nginx-proxy docker 接收来自 php-fpm docker 的 stderr 输出(导致 502 错误)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 nginx-proxy 与 wordpress docker 容器一起运行 phpmyadmin?

Docker使用nginx-proxy对Nextcloud进行https反向代理

无法使用nginx-proxy和dnsmasq在带有docker-compose的容器之间访问虚拟主机

如何自动缩放 Docker 容器主机?

LB负载均衡之Nginx-Proxy

.NetCore中IdentityServer使用nginx-proxy的一次排错经历