Nginx, работающий в качестве обратного прокси с бэкендом на php-fpm, всегда возвращает код состояния 200 - PullRequest
1 голос
/ 07 ноября 2019

Всякий раз, когда php-сервер возвращает ответ с телом, nginx отвечает кодом состояния 200 и правильным телом приложения, даже если приложение не возвращается с кодом состояния 200. Если приложение не установлено и тело ответа, то nginx возвращает то же самоеКод состояния, возвращаемый приложением.

Я использую этот Dockerfile.

FROM php:7.2-fpm-alpine3.9

RUN apk update && apk add nginx

WORKDIR /var/www

RUN mkdir -p /run/nginx

# nginx conf
RUN echo '\
server {                                                                \
    listen 80 default_server;                                           \
    listen [::]:80 default_server;                                      \
                                                                        \
    location / {                                                        \
      # Remove trailing slashes before checking for matching locations  \
      rewrite ^(.+)\/$ $1 permanent;                                    \
                                                                        \
      dav_methods PUT DELETE MKCOL COPY MOVE;                           \
      dav_access all:r;                                                 \
      index index.php index.html index.htm;                             \
      try_files $uri $uri/ /index.php?$args;                            \
    }                                                                   \
                                                                        \
    location ~ index\.php$ {                                            \
      include /etc/nginx/fastcgi_params;                                \
      fastcgi_split_path_info ^(.+\.php)(/.+)$;                         \
      fastcgi_pass 127.0.0.1:9000;                                      \
      fastcgi_index index.php;                                          \
      fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;  \
    }                                                                   \
}                                                                       \
' > /etc/nginx/conf.d/default.conf;

# php file
RUN echo '\
<?php                             \
echo "Hello World";               \
http_response_code(400);          \
?>                                \
'> /var/www/html/index.php

ENTRYPOINT [ "ash" ]

Для тестирования зайдите в работающий Docker-контейнер

  1. Запустите nginx
  2. Запустите php-fpmprocess
  3. использовать curl для создания запроса
  4. проверить журнал вывода nginx
$ nginx && \
  php-fpm --daemonize && \
  curl -XGET 127.0.0.1/abcd && \
  cat /var/log/nginx/access.log

ПРИМЕЧАНИЕ: если вы удалите эхо "Hello World"; из index.php, nginx возвращает правильный код состояния.

РЕДАКТИРОВАТЬ:

Но это работает, как ожидалось.

FROM debian:10-slim

ARG VERSION=7.2

# replace shell with bash so we can source files
SHELL ["/bin/bash", "-c"]

ENV DEBIAN_FRONTEND=noninteractive NODE_VERSION=12

ADD https://packages.sury.org/php/apt.gpg /opt/apt-php.gpg

RUN set -ex; \
    apt-get update -y; \
    apt-get install git gnupg -y; \
    apt-key add - < /opt/apt-php.gpg; \
    apt-get install -y apt-transport-https lsb-release ca-certificates; \
    echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list; \
    apt-get update -y; \
    apt-get upgrade -y; \
    apt-get install -y \
    php${VERSION} \
    php${VERSION}-fpm \
    nginx \
    curl;

# nginx conf
RUN echo '\
server {                                                                \
    listen 80 default_server;                                           \
    listen [::]:80 default_server;                                      \
                                                                        \
    location / {                                                        \
      # Remove trailing slashes before checking for matching locations  \
      rewrite ^(.+)\/$ $1 permanent;                                    \
                                                                        \
      dav_methods PUT DELETE MKCOL COPY MOVE;                           \
      dav_access all:r;                                                 \
      index index.php index.html index.htm;                             \
      try_files $uri $uri/ /index.php?$args;                            \
    }                                                                   \
                                                                        \
    location ~ index\.php$ {                                            \
      include /etc/nginx/fastcgi_params;                                \
      fastcgi_split_path_info ^(.+\.php)(/.+)$;                         \
      fastcgi_pass 127.0.0.1:9000;                                      \
      fastcgi_index index.php;                                          \
      fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;  \
    }                                                                   \
}                                                                       \
' > /etc/nginx/sites-available/default;

# php file
RUN echo '\
<?php                             \
echo "Hello World";               \
http_response_code(400);          \
?>                                \
'> /var/www/html/index.php

RUN sed -i "s/listen\ =\ \/run\/php\/php7.2-fpm.sock/listen\ =\ 127.0.0.1:9000/"  /etc/php/7.2/fpm/pool.d/www.conf

RUN mkdir -p /run/php

RUN ln -s /usr/sbin/php-fpm7.2 /usr/sbin/php-fpm

ENTRYPOINT [ "bash" ]

1 Ответ

0 голосов
/ 08 ноября 2019

Это ожидаемое поведение, как можно увидеть здесь - https://www.php.net/manual/en/function.header.php

В частности

Помните, что header () должна вызываться перед отправкой любого фактического вывода, либо> обычные теги HTML, пустые строки в файле или из PHP. Это очень распространенная ошибка при чтении кода с включенными или требующимися функциями или другой функцией доступа к файлу, с пробелами или пустыми строками, которые выводятся до вызова header (). Та же проблема существует при использовании одного файла PHP / HTML.

Этого можно избежать, установив output_buffering на Вкл в настройках php ini или запустив php cli с параметром, подобным php -S localhost:5000 -d output_buffering=4098.

...