Frage Apache 2.4 + PHP-FPM + ProxyPassMatch


Ich habe kürzlich Apache 2.4 auf meinem lokalen Rechner zusammen mit PHP 5.4.8 mit PHP-FPM installiert.

Nach einer Weile lief alles ganz reibungslos ab, aber es gibt immer noch einen seltsamen Fehler:

Ich habe Apache für PHP-FPM so konfiguriert:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1
</VirtualHost>

Es funktioniert, zum Beispiel wenn ich anrufe http://localhost/info.php Ich bekomme das Richtige phpinfo() (Es ist nur eine Testdatei).

Wenn ich jedoch ein Verzeichnis anrufe, bekomme ich einen 404 mit body File not found. und im Fehlerprotokoll:

[Tue Nov 20 21:27:25.191625 2012] [proxy_fcgi:error] [pid 28997] [client ::1:57204] AH01071: Got error 'Primary script unknown\n'

Aktualisieren

Ich habe jetzt versucht, das Proxying mit mod_rewrite durchzuführen:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"

    RewriteEngine on    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>

Aber das Problem ist: es wird immer umgeleitet, weil weiter http://localhost/ automatisch http://localhost/index.php ist gefragt, wegen

DirectoryIndex index.php index.html

Update 2

Ok, ich denke, "vielleicht prüfen, ob es eine Datei gibt, die dem Proxy zuerst gegeben wird:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"

    RewriteEngine on    
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>

Jetzt funktioniert das komplette Neuschreiben nicht mehr ...

Update 3

Jetzt habe ich diese Lösung:

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/apfelbox/WebServer"

    RewriteEngine on    
    RewriteCond /Users/apfelbox/WebServer/%{REQUEST_FILENAME} -f
    RewriteRule ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1 [L,P]
</VirtualHost>

Stellen Sie zunächst sicher, dass eine Datei an PHP-FPM übergeben wird (mit der voll und absolut Pfad) und dann das Umschreiben.

Dies funktioniert nicht, wenn URL-Rewriting innerhalb eines Unterverzeichnisses verwendet wird, auch bei URLs wie http://localhost/index.php/test/ Also zurück auf Platz eins.


Irgendwelche Ideen?


29
2017-11-20 20:27


Ursprung




Antworten:


Nach stundenlangem Suchen und Lesen der Apache-Dokumentation habe ich eine Lösung gefunden, die es erlaubt, den Pool zu verwenden, und auch der Rewrite-Direktive in .htaccess zu erlauben, selbst wenn die URL .php-Dateien enthält.

<VirtualHost ...>

 ...

 # This is to forward all PHP to php-fpm.
 <FilesMatch \.php$>
   SetHandler "proxy:unix:/path/to/socket.sock|fcgi://unique-domain-name-string/"
 </FilesMatch>

 # Set some proxy properties (the string "unique-domain-name-string" should match
 # the one set in the FilesMatch directive.
 <Proxy fcgi://unique-domain-name-string>
   ProxySet connectiontimeout=5 timeout=240
 </Proxy>

 # If the php file doesn't exist, disable the proxy handler.
 # This will allow .htaccess rewrite rules to work and 
 # the client will see the default 404 page of Apache
 RewriteCond %{REQUEST_FILENAME} \.php$
 RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
 RewriteRule (.*) - [H=text/html]

</VirtualHost>

Gemäß der Apache-Dokumentation erfordert der Proxy-Parameter SetHandler Apache HTTP Server 2.4.10.

Ich hoffe, dass diese Lösung Ihnen auch helfen wird.


27
2018-03-04 13:34



Dies ist definitiv die Antwort für 2015, alles andere hier ist Mist für ein modernes Setup (sagen wir Debian stabil) - Dmitri DB
Zweiter @ DmitriDB-Kommentar. Dies ist, was Sie für ein modernes Setup mit Apache 2.4.10 oder höher verwenden möchten (dies ist, wenn Unix-Sockets unterstützt wurden) - Brady
Ich habe schon seit geraumer Zeit mit dem Kopf gegen die Wand geschlagen, und ich habe eine sehr ähnliche Einstellung wie deine. Würden Sie bitte Ihre .htaccess Rewrite-Anweisungen posten? Soweit ich weiß, ist alles in dieser Antwort nur das, was Sie in Ihrer Datei httpd.d/site.conf haben. - David W
Francesco: Ist es möglich, dass RewriteRule für Alias-URLs funktioniert? - Zulakis
Im Moment scheint diese RewriteRule ziemlich gefährlich zu sein, da sie aussetzen könnte config.php  Dateien in Plain, wenn sie sich in Aliase-Verzeichnissen befanden und daher nicht in% {DOCUMENT_ROOT} /% {REQUEST_URI} vorhanden waren. - Zulakis


Ich bin gestern auch auf dieses Problem gestoßen - Apache 2.4 ist ausgezogen Debian / experimentell in Debian / instabil zwingt mich, mit diesem neuen Zeug umzugehen; natürlich nicht auf unseren Produktionsservern;).

Nachdem ich gelesen habe, was sich wie Millionen von Websites anfühlt, Apache-Dokumentation, Fehlerberichte und Debugging-Ausgaben im Fehlerprotokoll, habe ich es endlich zum Laufen gebracht. Nein, da ist keine Unterstützung für FPM mit Sockets, noch. Die Debian-Standardkonfiguration verwendet seit einiger Zeit Sockets, daher müssen Debian-Benutzer dies ebenfalls ändern.

Hier ist, was für eine CakePHP-Site und PHPMyAdmin (letzteres benötigt einige Konfiguration, wenn Sie die Debian-Pakete verwenden), so dass ich das bestätigen kann mod_rewrite funktioniert immer noch wie erwartet, um ein fantastisches URL-Rewriting durchzuführen.

Beachten DirectoryIndex index.php, was der Grund dafür sein könnte, dass keine Ihrer Konfigurationen für "Ordner" funktioniert (zumindest funktionierte das hier nicht).

Ich verstehe immer noch File not found. für Verzeichnisse, aber nur, wenn keine Indexdatei parsen kann. Ich würde es gerne wieder loswerden, aber es ist nicht so wichtig wie jetzt.


<VirtualHost *:80>
    ServerName site.localhost

    DocumentRoot /your/site/webroot
    <Directory />
            Options FollowSymlinks
            DirectoryIndex index.php
            AllowOverride All
            Require all granted
    </Directory>

    <LocationMatch "^(.*\.php)$">
            ProxyPass fcgi://127.0.0.1:9000/your/site/webroot
    </LocationMatch>

    LogLevel debug
    ErrorLog /your/site/logs/error.log
    CustomLog /your/site/logs/access.log combined
</VirtualHost>

Der obige vhost funktioniert perfekt mit einem .htaccess im root wie folgt:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

Ich verstehe nicht ganz, was Sie meinen URL rewriting inside a subdirectory though (Ich schreibe nur in die index.php der root um).


(Oh, und Sie müssen sicherstellen, dass Xdebug nicht mit FPM auf Ihrem System in Konflikt steht, sie wollen sofort die gleichen Ports verwenden.)


9
2018-06-01 09:37



Dies ist eine gute Lösung, aber leider funktioniert dieser Ansatz nicht, wenn URLs, die .php enthalten, neu geschrieben werden müssen, z. für WordPress Multisite. /ms_blog_1/wp-admin/load-scripts.php?blah=blah - Phil
Für mich, fügen Sie einfach eine Überschreibung hinzu DirectoryIndex index.html in dem fraglichen vhost behoben. Wenn ich habe DirectoryIndex index.php, dann scheinen andere PHP-Dateien den Fehler "Datei nicht gefunden" und "Primäres Skript unbekannt" zu erhalten. In meinem Fall habe ich eine index.html aber eine PHP-Datei test.php. - geerlingguy


Das ist, was ich habe. Es scheint OK zu funktionieren. Ich habe Drupal in ein Unterverzeichnis geschrieben und es funktioniert neu, Verzeichnisindizes funktionieren und PATH_INFO funktioniert.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %2 -f
RewriteRule . fcgi://127.0.0.1:9000/%1 [L,P]
RewriteOptions Inherit

Ich habe versucht, etwas ohne Umschreibungen ("Wenn" und so) zu machen, aber ich konnte nichts zum Arbeiten bekommen.

Bearbeiten: Beachten Sie, dass dies ein Sicherheitsproblem sein könnte, wenn Sie dies als Shared Hosting-Provider implementieren. Es würde Benutzern erlauben, PHP-Skripte an einen beliebigen fcgi-Proxy zu übergeben. Wenn Sie für jeden Benutzer einen eigenen Pool hätten, würden Angriffe mit erhöhten Rechten möglich sein.


2
2017-11-04 12:50





Alles, was Sie tun müssen, ist:

 ProxyErrorOverride on

Und vergessen Sie nicht, die Kundenseite wie folgt zu setzen:

ErrorDocument 404 /path/to/error_page_file    

2
2018-06-24 15:07





Der beste Weg, dies zu lösen, ist Debug-Protokolle für mod_proxy und mod_rewrite und php-fpm zu aktivieren. In Apache 2.4 können Sie nun Debug-Protokolle nur für bestimmte Module aktivieren. http://httpd.apache.org/docs/current/mod/core.html#loglevel Die Konfiguration pro Modul und pro Verzeichnis ist in Apache HTTP Server 2.3.6 und höher verfügbar

Vielleicht erhalten Sie einen doppelten Schrägstrich in Verzeichnissen?

Hier ist, was ich benutze und es funktioniert gut:

<LocationMatch ^(.*\.php)$>
  ProxyPass fcgi://127.0.0.1:9000/home/DOMAINUSER/public_html$1
</LocationMatch>

1
2018-05-25 05:39





Noch eine andere Lösung (erfordert Apache> = 2.4.10) - Im vhost:

# define worker
<Proxy "unix:/var/run/php5-fpm-wp.bbox.nuxwin.com.sock|fcgi://domain.tld" retry=0>
    ProxySet connectiontimeout=5 timeout=7200
</Proxy>

<If "%{REQUEST_FILENAME} =~ /\.php$/ && -f %{REQUEST_FILENAME}">
    SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
    SetHandler proxy:fcgi://domain.tld
</If>

Hier wird der fcgi-Handler für PHP nur dann gesetzt, wenn die Datei existiert und der Name mit der PHP-Dateierweiterung übereinstimmt.

BTW: Für diejenigen, die eine Idee hätten, die ProxyErrorOverride zu Auf, sei dir bewusst, dass das wirklich eine schlechte Idee ist. Die Verwendung dieser Richtlinie ist nicht ohne ein Problem zu verursachen. Zum Beispiel würde jede PHP-Anwendung, die einen HTTP-Code wie 503 sendet, zu einem unerwarteten Ergebnis führen. In jedem Fall wäre ein Standard-Error-Handler beteiligt, und bei PHP-Anwendungen, die eine API bereitstellen, ist das wirklich ein schlechtes Verhalten.


1
2017-12-10 18:12





Eine Sache, auf die ich bei meinem Umgang mit diesem Thema gestoßen bin, ist, dass wenn Sie die Kombination von:

chroot = /path/to/site
chdir = /

Übergeben Sie in Ihrer fpm-Pool-Konfiguration nicht den vollständigen Pfad zum ProxyPass Richtlinie.

ProxyPass fcgi://127.0.0.1:9020/$1

Aber -ONLY- wenn der Pool an diesem Port chroot ist.


0
2018-02-19 05:26





Linode hat ein tolles Tutorial zu diesem Thema

Im Grunde haben Sie einen Handler für den gesamten Server eingerichtet, der alle PHP-Skripte abfängt und an fast-cgi weiterleitet.


0
2018-04-05 15:28