
Ich habe viel gegoogelt und es gibt sicherlich viele Ergebnisse (sogar auf serverfault.com) zu diesem Problem. Ich konnte meine Probleme damit jedoch nicht lösen.
Mein Setup
Ich habe Ubuntu 20 auf WSL2 eingerichtet und versuche, es mit Ansible bereitzustellen. Ich versuche, Apache mit PHP-FPM-7.4 einzurichten.
Apache
Apache scheint einwandfrei zu funktionieren. Ich habe ein Dokumentstammverzeichnis mit einer test.html darin. Wenn ich die direkte URL zu dieser HTML-Datei aufrufe, sehe ich den Inhalt wie er sollte.
Vhost
Hinweis: Der besseren Lesbarkeit halber habe ich alle Kommentare weggelassen
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 FPM
Nun besteht das Problem darin, dass wenn ich eine PHP-Datei aufrufe, im Webbrowser die Meldung „Datei nicht gefunden“ angezeigt wird.
pool.d/www.conf
Hinweis: Der besseren Lesbarkeit halber habe ich alle Kommentare weggelassen
[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
Fehlerprotokolle
Das PHP-FPM-Fehlerprotokoll zeigt an, dass es einwandfrei läuft:
[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
Das Apache-Fehlerprotokoll zeigt einen Fehler an:
[Thu Dec 24 12:44:38.779511 2020] [proxy_fcgi:error] [pid 26424:tid 140510559713024] [client ::1:57178] AH01071: Got error 'Primary script unknown'
Wie kann ich das Problem beheben/untersuchen?
Zunächst einmal finde ich die Fehlermeldung „Datei nicht gefunden.“ sehr unklar. Wer hat welche Datei nicht gefunden? Es würde mir und anderen, die diesen Fehler in Zukunft haben, helfen, zu erklären, wer diesen Fehler auslöst und was er genau bedeutet.
Meine Schlussfolgerung bis zu diesem Punkt wäre, dass die Fehlermeldung von Apache ausgegeben wird und bedeutet, dass der PHP-FPM-Prozess nicht gefunden werden kann. Ist das richtig?
Wie kann ich das weiter untersuchen und beheben?
Bearbeiten:Hinzufügen meines Apache- und PHP-FPM-Setups.
Bearbeiten / wichtiger Hinweis
Während ich diesen Beitrag verbesserte und das Problem untersuchte, fand ich heraus, dass das Basis-Setup von Apache und PHP-FPM einwandfrei funktioniert.
Das Problem wird offensichtlich durch die folgende Anweisung verursacht:
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/hosts/%-4.0.%-3.0/%-5+"
Diese Anweisung funktionierte bei einem früheren Setup (mit Centos) einwandfrei, aber jetzt nicht mehr. Wenn ich diese Anweisung durch einen statischen Pfad zum Dokumentstamm ersetze, funktioniert es einwandfrei.
Ich werde die Untersuchung weiterführen, aber wenn jemand weiß, wie man das behebt, lassen Sie es mich bitte wissen.
Antwort1
Nach weiteren Untersuchungen fand ich heraus, dass meine ProxyPassMatch
Anweisung den Fehler verursachte. Und dann fand ich einen Beitrag auf StackOverflow, in dem stand, dass die gesamte ProxyPassMatch-Anweisung nicht verwendet werden sollte.
Simply SetHandler proxy:fcgi://127.0.0.1:9000
(das sich bereits auf meinem virtuellen Host befand) lässt PHP funktionieren.
Antwort2
Da dies das erste Ergebnis ist, das Google mir bei der Suche nach „Apache PHP-FPM-Datei nicht gefunden“ angezeigt hat, möchte ich meine Antwort hier hinzufügen.
Wenn das Apache-seitige Dokumentstammverzeichnisandersaus dem PHP-FPM-orientierten Dokumentstamm
In meinem Fall war das Apache-seitige Dokumentstammverzeichnis /data/.../wwwroot
und das PHP-FPM-seitige Dokumentstammverzeichnis (das in einem Container ausgeführt wird) war /var/www/html
.
DOCUMENT_ROOT
Die Lösung bestand darin , und SCRIPT_FILENAME
mit anzupassenProxyFCGISetEnvIf
:
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
(Ein Hinweis zu den verschiedenen Variablenzugriffssyntaxen: jede Syntax ist für Variablen aus unterschiedlichen Quellen. ${}
ist für Sachen, die definiert sind mitDefine
oder mit dem -D
Kommandozeilenargument; %{}
wenn fürVon Apache definierte Variablen; und %{reqenv:}
ist einFunktionsaufrufum auf eine interne Umgebungsvariable zuzugreifen.)
Sie können diese Variablen debuggen, indem Sie am Ende des FilesMatch
Abschnitts die folgenden Zeilen hinzufügen:
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}"
Sie sollten diese dann in den Antwortheadern sehen.