#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>
Если вы хотите обслуживать только файлы .phpphp-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