J'ai récemment installé Apache 2.4 sur ma machine locale, avec PHP 5.4.8 en utilisant PHP-FPM.
Tout s'est bien passé (après un certain temps ...) mais il y a quand même une étrange erreur:
J'ai configuré Apache pour PHP-FPM comme ceci:
<VirtualHost *:80>
ServerName localhost
DocumentRoot "/Users/apfelbox/WebServer"
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/Users/apfelbox/WebServer/$1
</VirtualHost>
Cela fonctionne, par exemple si j'appelle http://localhost/info.php
J'obtiens la bonne phpinfo()
(c'est juste un fichier de test).
Cependant, si j'appelle un répertoire, j'obtiens un 404 avec le corps File not found.
Et dans le journal des erreurs:
[Tue Nov 20 21:27:25.191625 2012] [proxy_fcgi:error] [pid 28997] [client ::1:57204] AH01071: Got error 'Primary script unknown\n'
J'ai maintenant essayé de faire le proxy avec mod_rewrite:
<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>
Mais le problème est: il redirige toujours, car sur http://localhost/
Automatiquement http://localhost/index.php
Est demandé, à cause de
DirectoryIndex index.php index.html
Ok, donc je pense "peut-être vérifier s'il y a un fichier à donner au proxy en premier:
<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>
Maintenant, la réécriture complète ne fonctionne plus ...
Maintenant, j'ai cette solution:
<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>
Vérifiez d'abord qu'il y a un fichier à passer à PHP-FPM (avec le chemin complet et absol) puis faites la réécriture.
Cela ne fonctionne pas lorsque vous utilisez la réécriture d'URL dans un sous-répertoire, mais cela échoue également pour les URL comme http://localhost/index.php/test/
. Revenons donc à la case départ.
Des idées?
Après des heures de recherche et de lecture de la documentation Apache, j'ai trouvé une solution qui permet d'utiliser le pool, et aussi de permettre à la directive de réécriture dans .htaccess de fonctionner même lorsque l'url contient des fichiers .php.
<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>
Selon la documentation Apache, le paramètre proxy SetHandler nécessite Apache HTTP Server 2.4.10.
J'espère que cette solution vous aidera aussi.
J'ai également rencontré ce problème hier - Apache 2.4 a quitté Debian/experimental pour Debian/unstable me forçant à faire face à ce nouveau truc; pas sur nos serveurs de production bien sûr;).
Après avoir lu ce qui ressemble à des millions de sites, des documents Apache, des rapports de bogues et une sortie de débogage dans le journal des erreurs, j'ai finalement réussi à le faire fonctionner. Non, il y a pas de support pour FPM avec sockets , pour l'instant. La configuration Debian par défaut utilise des sockets depuis un certain temps maintenant, donc les utilisateurs Debian devront également changer cela.
Voici ce qui fonctionne pour un site CakePHP et PHPMyAdmin (ce dernier a cependant besoin d'une configuration si vous utilisez les paquets Debian), donc je peux confirmer que mod_rewrite
fonctionne toujours comme prévu pour effectuer une réécriture sophistiquée d'URL.
Remarquer DirectoryIndex index.php
, ce qui pourrait être la raison pour laquelle aucune de vos configurations n'a fonctionné pour les "dossiers" (c'est du moins ce qui n'a pas fonctionné ici).
Je reçois toujours File not found.
pour les répertoires, mais uniquement s'il n'y a pas de fichier d'index, il peut les analyser. J'adorerais me débarrasser de cela aussi, mais ce n'est pas aussi critique que pour le moment.
<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>
Le vhost ci-dessus fonctionne parfaitement bien avec un .htaccess à la racine comme ceci:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
Je ne comprends pas vraiment ce que vous entendez par URL rewriting inside a subdirectory
cependant (je ne fais que réécrire dans le fichier index.php de la racine).
(Oh, et vous devrez vous assurer que Xdebug n'entre pas en conflit avec FPM sur votre système, dès le départ, ils veulent utiliser les mêmes ports.)
Il vous suffit de définir:
ProxyErrorOverride on
Et n'oubliez pas de paramétrer la page client en:
ErrorDocument 404 /path/to/error_page_file
Encore une autre solution (nécessite Apache> = 2.4.10) - À l'intérieur du 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>
Donc, ici, le gestionnaire fcgi pour PHP ne sera défini que si le fichier existe et si son nom correspond à PHP extension de fichier.
BTW: Pour ceux qui auraient l'idée de régler ProxyErrorOverride sur On, sachez que c'est vraiment une mauvaise idée. L'utilisation de cette directive n'est pas sans poser de problème. Par exemple, toute application PHP envoyant du code HTTP tel que 503 conduirait à un résultat inattendu. Un gestionnaire d'erreur par défaut serait impliqué dans tous les cas et pour les applications PHP PHP fournir une API, c'est vraiment un mauvais comportement.
Voilà ce que j'ai. Il semble fonctionner correctement. Je mets Drupal dans un sous-répertoire et son travail de réécriture, les index de répertoire fonctionnent et PATH_INFO fonctionne.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %2 -f
RewriteRule . fcgi://127.0.0.1:9000/%1 [L,P]
RewriteOptions Inherit
J'ai essayé de faire quelque chose comme ça sans réécriture ("Si" et autres), mais je n'ai rien pu faire fonctionner.
EDIT: Notez que si vous l'implémentiez en tant que fournisseur d'hébergement partagé, cela pourrait être un problème de sécurité. Cela permettrait aux utilisateurs de passer des scripts PHP à un proxy fcgi arbitraire. Si vous aviez un pool séparé pour chaque utilisateur, cela permettrait une élévation des attaques de privilèges.
La meilleure façon de résoudre ce problème est d'activer les journaux de débogage pour mod_proxy et mod_rewrite et php-fpm. Dans Apache 2.4, vous pouvez désormais activer les journaux de débogage pour des modules spécifiques uniquement. http://httpd.Apache.org/docs/current/mod/core.html#loglevel La configuration par module et par répertoire est disponible dans Apache HTTP Server 2.3.6 et versions ultérieures
Peut-être que vous obtenez une double barre oblique sur les répertoires?
Voici ce que j'utilise et cela fonctionne bien:
<LocationMatch ^(.*\.php)$>
ProxyPass fcgi://127.0.0.1:9000/home/DOMAINUSER/public_html$1
</LocationMatch>
Une chose que j'ai rencontrée dans mon traitement de ce problème est que si vous utilisez la combinaison de:
chroot = /path/to/site
chdir = /
Dans votre configuration de pool fpm, ne passez pas le chemin d'accès complet à la directive ProxyPass
.
ProxyPass fcgi://127.0.0.1:9020/$1
Mais -Seulement- si le pool sur ce port est chrooté.
Je ne sais pas si le problème est lié, mais j'ai trouvé une solution de travail partielle ici:
L'astuce semble être d'ajouter un? char dans le .htaccess RewriteRule, par exemple en utilisant:
RewriteRule ^(.*)$ index.php?/$1 [L,NS]
au lieu de:
RewriteRule ^(.*)$ index.php/$1 [L,NS]
La source du problème semble être un changement dans mod_rewrite d'Apache 2.4.25. J'ai utilisé le niveau de journal d'Apache trace1 pour observer une "boucle" qui passe $ 1 à php-fpm après que index.php/$ 1 a été passé. Le $ 1 génère l'erreur "AH01071: Got error 'Primary script unknown\n'".
J'espère que cette petite friandise aidera quelqu'un à résoudre ses problèmes.
Une version légèrement modifiée de la réponse de @ FrancescoA qui ne nécessite pas de mod_rewrite
<IfModule proxy_fcgi_module>
<FilesMatch \.php$>
<If "-f '%{REQUEST_FILENAME}'">
SetHandler "proxy:unix:/path/to/socket.sock|fcgi://unique-domain-name-string/"
</If>
</FilesMatch>
<Proxy fcgi://unique-domain-name-string>
ProxySet connectiontimeout=5 timeout=240
</Proxy>
</IfModule>
Linode a un excellent tutoriel sur ce sujet
Fondamentalement, vous configurez un gestionnaire pour l'ensemble du serveur qui interceptera tous les scripts php et les passera à fast-cgi.
Je fais face aux mêmes problèmes sur mon serveur (docker centos 7.3.16). Après avoir suivi le journal de php-fpm, j'ai trouvé miss a sys lib. WARNING: [pool www] child 15081 said into stderr: "php-fpm: pool www: symbol lookup error: /lib64/libnsssysinit.so: undefined symbol: PR_GetEnvSecure"
puis, je rappelle le nspr, cela fonctionne. Si vous ne trouvez pas les solutions après avoir essayé des méthodes, vous pouvez essayer ceci. yum -y install/reinstall nspr
Cela fonctionne avec Wordpress 5.1.1 et plus récent avec PHP 7.3, FastCGI, proxy, également MariaDB/MySQL. Vérifié deux fois sur mes serveurs. Fonctionne comme un charme.
Premier sur CentOS/Fedora/Red Hat
Sudo yum remove php*
Sudo yum --enablerepo=extras install epel-release
Sudo yum install php-fpm php-mysql php-Gd php-imap php-mbstring
Sudo grep -E '(proxy.so|fcgi)' /etc/httpd/conf.modules.d/00-proxy.conf
Sudo mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf_bak
Modifiez ce fichier:
Sudo nano /etc/php-fpm.d/www.conf
Collez ceci:
[www]
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = 127.0.0.1:9000
listen = /run/php-fcgi.sock
Sudo ll /run/php-fcgi.sock
Devrait donner srw-rw-rw-.
Ou comment configurer sur Debian/Ubuntu
Didacticiel:
Sudo apt purge 'php*' or Sudo apt-get purge 'php*'
Sudo add-apt-repository ppa:ondrej/php
Sudo apt-get update
Sudo apt install php7.3 php7.3-fpm php-mysql php-mbstring php-Gd php-imap libapache2-mod-security2 modsecurity-crs
systemctl status php7.3-fpm
systemctl stop php7.3-fpm.service
Sudo a2dismod php7.0 php7.1 php7.2 mpm_event mpm_worker
Sudo a2enmod mpm_prefork
Sudo a2enmod php7.3
Sudo systemctl restart Apache2 (httpd in CentOS)
Le problème est que php 7.3 du repo Ondrej ne fonctionne qu'avec le mode mpm_prefork. Il a git repo, donc vous pouvez le trouver sur le net et lui demander s'il fera php 7.3 pour mpm_worker et mpm_event. Le reste de la configuration des distributions de la famille Debian est ci-dessous:
Sudo apt --assume-yes install php7.3-fpm
Sudo systemctl stop php7.3-fpm.service
Sudo rm /var/log/php7.0-fpm.log
Sudo mkdir /var/log/php7.3-fpm/
Sudo touch /var/log/php7.3-fpm/error.log
Sudo mkdir /var/log/php7.3/
Sudo touch /var/log/php7.3/error.log
Sudo mkdir /var/tmp/php7.3/
Sudo > /etc/php/7.3/fpm/php.ini
Sudo > /etc/php/7.3/fpm/php-fpm.conf
Sudo rm /etc/php/7.3/fpm/pool.d/www.conf
Sudo touch /etc/php/7.3/fpm/pool.d/example.com.conf
Sudo useradd --comment "PHP" --Shell "/usr/sbin/nologin" --system --user-group php
Sudo nano /etc/php/7.3/fpm/php.ini
pâte
[PHP]
date.timezone = Europe/Prague
display_errors = Off
error_log = /var/log/php7.3/error.log
error_reporting = 32767
log_errors = On
register_argc_argv = Off
session.gc_probability = 0
short_open_tag = Off
upload_tmp_dir = /var/tmp/php7.3/
Sudo nano /etc/php/7.3/fpm/php-fpm.conf
pâte
[global]
error_log = /var/log/php7.3-fpm/error.log
include = /etc/php/7.3/fpm/pool.d/*.conf
Sudo nano /etc/php/7.3/fpm/pool.d/example.com.conf
pâte
[example.com]
group = php
listen = 127.0.0.1:9000
pm = ondemand
pm.max_children = 5
pm.max_requests = 200
pm.process_idle_timeout = 10s
user = php
Sudo nano /etc/logrotate.d/php7.3-fpm
copiez ceci dans un fichier txt:
/var/log/php7.3-fpm.log {
rotate 12
weekly
missingok
notifempty
compress
delaycompress
postrotate
/usr/lib/php/php7.3-fpm-reopenlogs
endscript
}
supprimez-le et collez-le au lieu de ci-dessus:
/var/log/php7.3/*.log /var/log/php7.3-fpm/*.log
{
copytruncate
maxage 365
missingok
monthly
notifempty
rotate 12
}
Ajouter une directive
Sudo nano /etc/Apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
ServerAdmin [email protected]
DocumentRoot /var/www/html/example.com/public_html
DirectoryIndex index.php index.htm index.html index.xht index.xhtml
LogLevel info warn
ErrorLog ${Apache_LOG_DIR}/error.log
CustomLog ${Apache_LOG_DIR}/access.log combined
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
<files readme.html>
order allow,deny
deny from all
</files>
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/example.com/public_html
<Directory /var/www/html/example.com/public_html>
Options Indexes FollowSymLinks Includes IncludesNOEXEC SymLinksIfOwnerMatch
AllowOverride None
</Directory>
</VirtualHost>
Activez ensuite le site:
Sudo a2ensite /etc/Apache2/sites-available/example.com.conf
Modifiez ensuite le site SSL (dans ce cas, le certbot de Let's Encrypt a été installé et configuré précédemment au début de la configuration du certificat SSL).
Sudo nano /etc/Apache2/sites-available/example.com-le-ssl.conf
<IfModule mod_ssl.c>
#headers for security man in the middle attack find how to enable this mod in Google
LoadModule headers_module modules/mod_headers.so
<VirtualHost *:443>
Header always set Strict-Transport-Security "max-age=15768000"
SSLEngine On
ServerName example.com
ServerAdmin [email protected]
DocumentRoot /var/www/html/example.com/public_html
<Directory /var/www/html/example.com/public_html>
Options Indexes FollowSymLinks Includes IncludesNOEXEC SymLinksIfOwnerMatch
AllowOverride All
Require all granted
DirectoryIndex index.php
RewriteEngine On
<FilesMatch ^/(.*\.php(/.*)?)$>
SetHandler "fcgi://example.com:9000/var/www/html/example.com/public_html"
</FilesMatch>
</Directory>
# Log file locations
#LogLevel info ssl:warn
LogLevel debug
ErrorLog ${Apache_LOG_DIR}/error.log
CustomLog ${Apache_LOG_DIR}/access.log combined
# modern configuration
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-Apache.conf
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
#SSLCipherSuite HIGH:!aNULL:!MD5
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM$
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
<files readme.html>
order allow,deny
deny from all
</files>
</VirtualHost>
#Stapling OCSP for Let's Encrypt certs.
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
</IfModule>
Sudo a2enmod proxy proxy_fcgi setenvif
Sudo systemctl reload Apache2.service
Sudo chown --recursive root:adm /etc/php/
Sudo chmod --recursive 0770 /etc/php/
Sudo chown --recursive php:adm /var/log/php7.3/
Sudo chown --recursive php:adm /var/log/php7.3-fpm/
Sudo chmod --recursive 0770 /var/log/php7.3/
Sudo chmod --recursive 0770 /var/log/php7.3-fpm/
Sudo chown --recursive php:php /var/tmp/php7.3/
Sudo chmod --recursive 0770 /var/tmp/php7.3/
Sudo a2enconf php7.3-fpm
Sudo systemctl enable php7.3-fpm.service
Sudo systemctl start php7.3-fpm.service
N'oubliez pas d'ajouter un port 9000 à un pare-feu sur Debian/Ubuntu
Sudo ufw allow 9000/tcp
Sudo ufw status
Sur CentoOS/Fedora/Red Hat
Sudo firewall-cmd --zone=public --add-port=9000/tcp --permanent
Sudo firewall-cmd --reload
Sudo firewall-cmd --list-all
Sudo firewall-cmd --state
j'ai également l'erreur après le passage à php-fpm + Apache 2.4.6 pour drupal
mais j'utilise le mod d'événement mpm
il suffit d'insérer
DirectoryIndex index.php
travaille pour moi
alors mes paramètres Vhost ressemblent à ci-dessous
<VirtualHost *:8080>
ServerAdmin webmaster@localhost
ServerName sever.com
DocumentRoot /var/www/html/webroot
ErrorLog logs/web-error_log
CustomLog logs/web-access_log common
<IfModule mpm_event_module>
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/webroot/$1
</IfModule>
<Directory /var/www/html/webroot>
Options FollowSymlinks
DirectoryIndex index.php
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
merci
pas besoin de réviser le fichier .htaccess par défaut de drupal