Сопоставление файлов Apache 404

#php #docker #apache #httpd.conf

Вопрос:

Учитывая следующую рабочую конфигурацию Apache (используется внутри httpd:2.4.48-контейнер alpine docker)

 <VirtualHost *:80>
   
   DocumentRoot "/code2"

   <Proxy "fcgi://php/">
       ProxySet enablereuse=On
   </Proxy>

   <FilesMatch .php

gt;
SetHandler "proxy:fcgi://php:9000"
</FilesMatch>

<Directory /code2>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

DirectoryIndex index.php

</VirtualHost>

Однако, если я перемещу каталог /code2, который соответствует пути в контейнере php-fpm (с именем «php»), например: /code ( я также обновляю каталог DocumentRoot и путь к каталогу ).

Я получаю 404 по всем файлам php. Почему это так? как я могу указать другой путь к файлам php для каждого контейнера?

Еще одна интересная вещь, которую следует отметить, заключается в том, что как в журнале доступа apache, так и в php не отображается полный путь к файлу php, к которому осуществляется доступ, только имя файла.

Ответ №1:

Если вы хотите использовать директиву «DocumentRoot» с обработчиком PHP, вам также необходимо подключить этот том httpd . По умолчанию несуществующие файлы будут напрямую запускать 404 (см. https://cwiki.apache.org/confluence/display/HTTPD/PHP-FPM «Прокси через обработчик»)

Вот небольшой пример (с помощью docker-compose для простоты) для вашего варианта использования:

./docker-compose.yaml :

 version: "3.9"

services:
  httpd:
    build:
      context: ./httpd/
    ports:
      - 80:80
    volumes:
      - ./php-vol:/code2:rw
  php:
    image: php:8.0-fpm
    volumes:
      - ./php-vol:/code2:rw
      - ./php-vol2:/code2/another-dir:rw
 

./httpd/Dockerfile

 FROM httpd:2.4.48-alpine

COPY php-fpm.conf conf/extra/php-fpm.conf

RUN echo "Include conf/extra/php-fpm.conf" >> conf/httpd.conf

RUN sed -i 
        -e 's/^#(LoadModule .*mod_proxy.so)/1/' 
        -e 's/^#(LoadModule .*mod_proxy_fcgi.so)/1/' 
        conf/httpd.conf
 

./httpd/php-fpm.conf (используя обработчик PHP, см. https://cwiki.apache.org/confluence/display/HTTPD/PHP-FPM)

 <VirtualHost *:80>
   DocumentRoot "/code2"

   <Proxy "fcgi://php/">
       ProxySet enablereuse=On
   </Proxy>

   <FilesMatch .php

gt;
SetHandler "proxy:fcgi://php:9000"
</FilesMatch>

<Directory /code2>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

DirectoryIndex index.php
</VirtualHost>

Если вы хотите обслуживать только файлы .php php-fpm , это можно упростить:

 <VirtualHost *:80>
   ProxyPassMatch ^/(.*.php(/.*)?)$ fcgi://php:9000/code2/$1

   DirectoryIndex index.php
</VirtualHost>
 

Комментарии:

1. Итак, ответ на ваш вопрос «как я могу указать другой путь к файлам php для каждого контейнера?» таков: у вас не может быть разных путей между php-fpm и httpd.

2. Это похоже на рабочий пример, который я привел, я предоставляю корневой каталог документов для файлов, отличных от php. Я хочу, чтобы пути были разными, так как это позволило бы использовать общий контейнер вместо нескольких копий. Я не вижу никакой функциональной разницы в моем рабочем примере, поэтому я не рассматриваю это как ответ. Я хотел бы смонтировать файлы в другом месте. С помощью nginx я предоставляю относительный путь и добавляю к нему другой корень. С apache это должно быть по умолчанию?

3. Однако, если это невозможно, как вы заявили, это правильный ответ. Ты уверен? directoryPath не полезен?

4. Да, я уверен, что DocumentRoot Apache и php-fpm должны быть равны, если вы хотите, чтобы статические файлы обслуживались непосредственно Apache. Я добавил еще один PHP-том к приведенному выше примеру, установив его где — то внутри DocumentRoot-может быть, это лучше подходит для вашего варианта использования? Следующее, что вы могли бы рассмотреть,-это дополнительный пул php-fpm, но для этого, конечно, требуется другой виртуальный хост Apache (с другим корневым каталогом документов).

5. Не могли бы вы добавить более полный пример того, какие URL-адреса вы ожидаете получить с какого тома и с помощью какой службы (apache/php-fpm)?

Ответ №2:

Если вы хотите использовать другой путь в httpd и php-fpm, вы можете настроить переменные среды, отправляемые в php-fpm, с помощью ProxyFCGISetEnvIf.

https://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html#proxyfcgisetenvif

К сожалению, комбинация переменных, на которые может обратить внимание php-fpm, чтобы определить, где искать на диске, может немного сбивать с толку-на самом деле эта директива существует для того, чтобы дать вам возможность в последний момент увидеть, что отправил бы mod_proxy_fcgi, а затем настроить их.

Этот пример из руководства устрашающе (с отброшенным суффиксом d) близок к вашей проблеме:

 ProxyFCGISetEnvIf "reqenv('PATH_TRANSLATED') =~ m|(/.*prefix)(d )(.*)|" PATH_TRANSLATED "$1$3"
 

Я предлагаю использовать этот шаблон для преобразования PATH_TRANSLATED (путь к файловой системе) из вашего контейнера httpd в тот, который действителен в контейнере FPM.

Комментарии:

1. в последний раз, когда я смотрел на это (вероятно, для реализации ProxyFCGISetEnvIf), я нашел этот поддельный сервер FPM, который сбрасывает полезные переменные: hastebin.com/xexexomubi.php