docker 中的 Apache 重写不适用于 PHP 文件
Apache rewrite in docker not working for PHP files
我的 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
结尾的请求都将被忽略,并显示请求的文件,就好像根本没有配置一样。
Docker文件:
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/
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/
它代理每个 *.php
请求到 php-fpm
容器的端口 9000
。
此指令在之前 mod_rewrite
运行并处理所有*.php
文件,因此.htaccess
中的重写规则重写所有*.php
URI 永远不会被调用。
您可以将此指令更改为仅代理 /index.php
并让所有剩余的 .php
请求像这样流向 mod_rewrite
和 .htaccess
。
ProxyPassMatch ^/(index\.php(/.*)?)$ fcgi://php:9000/var/www/html/
您可以像这样重构您的 .htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L,NC]
RewriteRule \.(php|html?|xml)$ index.php [NC,L]
我的 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
结尾的请求都将被忽略,并显示请求的文件,就好像根本没有配置一样。
Docker文件:
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/
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/
它代理每个 *.php
请求到 php-fpm
容器的端口 9000
。
此指令在之前 mod_rewrite
运行并处理所有*.php
文件,因此.htaccess
中的重写规则重写所有*.php
URI 永远不会被调用。
您可以将此指令更改为仅代理 /index.php
并让所有剩余的 .php
请求像这样流向 mod_rewrite
和 .htaccess
。
ProxyPassMatch ^/(index\.php(/.*)?)$ fcgi://php:9000/var/www/html/
您可以像这样重构您的 .htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L,NC]
RewriteRule \.(php|html?|xml)$ index.php [NC,L]