问题描述
我的 docker 容器 apache 似乎无法重写对 .PHP
文件的请求。有趣的是,任何其他文件类型似乎都可以正常工作。
例如使用这个简单的 .htaccess
配置:
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)\.PHP$ index.PHP [L]
RewriteRule ^(.*)\.html$ index.PHP [L]
RewriteRule ^(.*)\.txt$ index.PHP [L]
RewriteRule ^(.*)\.xml$ index.PHP [L]
每个以 .PHP
、.html
、.txt
或 .xml
结尾的请求都应该重写为 index.PHP
。但是,所有以 .PHP
结尾的请求都将被忽略并显示所请求的文件,就好像根本没有配置一样。
Dockerfile:
ARG APACHE_VERSION=""
FROM httpd:${APACHE_VERSION:+${APACHE_VERSION}-}alpine
RUN apk update; \
apk upgrade;
# copy apache vhost file to proxy PHP requests to PHP-fpm container
copY project.apache.conf /usr/local/apache2/conf/demo.apache.conf
RUN echo "Include /usr/local/apache2/conf/demo.apache.conf" \
>> /usr/local/apache2/conf/httpd.conf
.env(配置)
APACHE_VERSION=2.4
PROJECT_ROOT=./www
compose.yml
version: "3.2"
services:
apache:
build:
context: './apache/'
args:
APACHE_VERSION: ${APACHE_VERSION}
depends_on:
- PHP
- MysqL
networks:
- frontend
- backend
ports:
- "80:80"
volumes:
- ${PROJECT_ROOT}/:/var/www/html/
container_name: apache
Apache 配置:
ServerName localhost
LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so
LoadModule rewrite_module modules/mod_rewrite.so
<VirtualHost *:80>
# Proxy .PHP requests to port 9000 of the PHP-fpm container
ProxyPassMatch ^/(.*\.PHP(/.*)?)$ fcgi://PHP:9000/var/www/html/$1
DocumentRoot /var/www/html/
<Directory /var/www/html/>
DirectoryIndex index.PHP
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Send apache logs to stdout and stderr
CustomLog /proc/self/fd/1 common
ErrorLog /proc/self/fd/2
</VirtualHost>
我不确定问题是否出在 docker 或 apache 中,因此问题可能需要重命名。
如果有人想在他们自己的 docker 中重现问题,这是我正在使用的完整 docker 配置:https://drive.google.com/file/d/1D_a-9d_BfomzrAjSxGNo8M3nZ1s2imU9/view?usp=sharing
它有一个用于自动设置的 .bat 文件,所以你唯一需要运行它的是一个可用的 docker。
解决方法
您有此 ProxyPassMatch
行:
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
代理每个 *.php
请求到 9000
容器的端口 php-fpm
。
此指令在 before mod_rewrite
之前运行并处理所有 *.php
文件,因此您在 .htaccess
中重写所有 *.php
URI 的重写规则永远不会调用。
您可以将此指令更改为仅代理 /index.php
,并让所有剩余的 .php
请求像这样流过 mod_rewrite
和 .htaccess
。
ProxyPassMatch ^/(index\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
你可以像这样重构你的 .htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L,NC]
RewriteRule \.(php|html?|xml)$ index.php [NC,L]