
Я много гуглил и там, конечно, много результатов (даже на serverfault.com) по этой проблеме. Однако я не смог решить свои проблемы с ней.
Моя установка
Я настраиваю Ubuntu 20 на WSL2 и пытаюсь настроить его с помощью Ansible. Я пытаюсь настроить Apache с PHP-FPM-7.4.
Апачи
Apache, кажется, работает нормально. У меня есть корневой документ с test.html в нем. Когда я вызываю прямой URL к этому HTML-файлу, я вижу содержимое, как и должно быть.
Vhost
Примечание: для удобства чтения я опустил все комментарии.
DirectoryIndex index.php index.html
<VirtualHost *:80>
ServerName paul.test
ServerAlias *.paul.test
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>
UseCanonicalName Off
VirtualDocumentRoot /var/www/hosts/%-4.0.%-3.0/%-5+
<Directory "/var/www">
AllowOverride All
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
</VirtualHost>
<VirtualHost *:443>
ServerName paul.test
ServerAlias *.paul.test
<FilesMatch \.php$>
Require all granted
SetHandler proxy:fcgi://127.0.0.1:9000
</FilesMatch>
UseCanonicalName Off
VirtualDocumentRoot /var/www/hosts/%-4.0.%-3.0/%-5+
SSLEngine on
SSLCipherSuite AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCompression off
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<Directory "/var/www">
AllowOverride All
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
</VirtualHost>
PHP-ФПМ
Теперь проблема в том, что когда я вызываю PHP-файл, я вижу в веб-браузере сообщение «Файл не найден».
pool.d/www.conf
Примечание: для удобства чтения я опустил все комментарии.
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 5
listen.allowed_clients = 127.0.0.1
Журналы ошибок
Журнал ошибок PHP-FPM сообщает, что все работает нормально:
[24-Dec-2020 12:16:06] NOTICE: fpm is running, pid 26532
[24-Dec-2020 12:16:06] NOTICE: ready to handle connections
[24-Dec-2020 12:16:06] NOTICE: systemd monitor interval set to 10000ms
В журнале ошибок Apache отображается ошибка:
[Thu Dec 24 12:44:38.779511 2020] [proxy_fcgi:error] [pid 26424:tid 140510559713024] [client ::1:57178] AH01071: Got error 'Primary script unknown'
Как исправить/исследовать?
Для начала, я нахожу сообщение об ошибке "Файл не найден." очень непонятным. Кто не нашел какой файл? Мне и другим, у кого в будущем возникнет эта ошибка, было бы полезно объяснить, кто выдает эту ошибку и что она означает.
До этого момента я пришел к выводу, что сообщение об ошибке выдает Apache, и это означает, что он не может найти процесс PHP-FPM. Это верно?
Как мне следует провести дальнейшее расследование и исправить ситуацию?
Редактировать:Добавляю настройку Apache и PHP-FPM.
Редактировать / важное примечание
Улучшая этот пост и исследуя проблему, я обнаружил, что базовая настройка Apache и PHP-FPM работает нормально.
Проблема, по-видимому, вызвана следующим утверждением:
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
Это выражение работало нормально на предыдущей настройке (с Centos), но сейчас не работает. Когда я заменяю это выражение на статический путь к document-root, оно работает нормально.
Я буду изучать этот вопрос дальше, но если кто-то знает, как это исправить, пожалуйста, дайте мне знать.
решение1
После дальнейшего расследования я выяснил, что мое ProxyPassMatch
утверждение вызвало ошибку. А затем я нашел пост на StackOverflow, в котором говорилось, что не следует использовать все утверждение ProxyPassMatch.
Просто SetHandler proxy:fcgi://127.0.0.1:9000
(что уже было в моем виртуальном хосте) заставляет PHP работать.
решение2
Поскольку это первый результат, который Google выдал мне при поиске «файл apache php-fpm не найден», я хотел бы добавить свой ответ здесь.
Если корневой каталог документов, обращенный к Apache,другойиз корневого документа, обращенного к PHP-FPM
В моем случае корневой каталог документов, обращенный к Apache, был /data/.../wwwroot
, а корневой каталог документов, обращенный к PHP-FPM (работающий в контейнере), был /var/www/html
.
Исправление заключалось в настройке DOCUMENT_ROOT
и SCRIPT_FILENAME
с помощьюProxyFCGISetEnvIf
:
Define container_root "/var/www/html"
<FilesMatch "\.php$">
<If "-f %{REQUEST_FILENAME}">
SetHandler "proxy:fcgi://127.0.0.1:9000"
ProxyFCGISetEnvIf "true" DOCUMENT_ROOT "${container_root}"
ProxyFCGISetEnvIf "true" SCRIPT_FILENAME "%{HANDLER}${container_root}%{reqenv:SCRIPT_NAME}"
</If>
</FilesMatch>
UnDefine container_root
(Примечание о различных синтаксисах доступа к переменным: каждый синтаксис предназначен для переменных из разных источников. ${}
предназначен для вещей, определенных с помощьюDefine
, или с -D
аргументом командной строки; %{}
если дляпеременные, определенные Apache; и %{reqenv:}
этовызов функции(для доступа к внутренней переменной среды.)
Вы можете отладить эти переменные, добавив следующие строки в конец раздела FilesMatch
:
Header always set X-HANDLER "expr=%{HANDLER}"
Header always set X-DOCUMENT_ROOT "expr=%{reqenv:DOCUMENT_ROOT}"
Header always set X-SCRIPT_FILENAME "expr=%{reqenv:SCRIPT_FILENAME}"
Header always set X-SCRIPT_NAME "expr=%{reqenv:SCRIPT_NAME}"
Затем вы должны увидеть их в заголовках ответа.