Docker环境下的apache+php-fpm

我们需要用到两个container。一个apache的,另一个则是php-fpm。

apache的Docker接受http请求并转给php-fpm处理。php-fpm的Docker默认监听9000端口。

工作目录构成如下。

1
2
3
4
5
6
7
8
.
├── Dockerfile
├── docker-compose.yml
├── extra
│   └── my-php-conf.conf
├── html
│   └── index.php
└── my-httpd.conf

首先我们要加工一下官方的apache2的docker,放入我们自定义的httpd conf文件。

复制一份默认的httpd.conf

1
docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > my-httpd.conf

编辑my-http.conf

1
2
3
4
5
6
# 去掉下面两个注释
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

# 增加一行
Include conf/extra/my-php-conf.conf

然后考虑一个重要的问题。我们的php文件到是放哪里?

php-fpm 默认的webroot是/var/www/html,就放这儿能行?

那apache的web server怎么配置?

接下来编辑extra/my-php-conf.conf

1
2
3
4
5
6
7
8
9
10
11
<VirtualHost *:80>
DocumentRoot /usr/local/apache2/htdocs
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
<Directory "/usr/local/apache2/htdocs">
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
DirectoryIndex index.php index.html
</VirtualHost>

最关键的是

1
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1

这个配置制定了php文件在php-fpm Docker中的位置。

这不理所当然?有什么问题吗?

问题来自网上充斥着的一种配置。

如下。

1
2
3
<FilesMatch \.php$>
SetHandler "proxy:fcgi://php:9000"
</FilesMatch>

很多人说这个是apache2的推荐做法。但是我们会发现如果我们直接把php文件放入php-fpm的/var/www/html,运行docker的话,返回的结果是404。

原因是,setHandler并没有带任何参数,apache默认的webRoot则是/usr/var/apache2/htdocs,所以用这个handler,php-fpm会直接去找自己docker中的/usr/var/apache2/htdocs,刚刚说过了,php-fpm默认的webroot是/var/www/html,自然只能返回404了。

所以网上很多建议也并不是很负责。

最后我们创建docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
version: '3.7'
services:
web:
build: .
ports:
- "80:80"
volumes:
- ./extra:/usr/local/apache2/conf/extra
php:
image: php:7.4-fpm
volumes:
- ./html:/var/www/html

把一个index.php放入html

内容可以适宜。

1
<?php phpinfo();

最后运行docker-compose up, 打开浏览器localhost,一切顺利。

如果你觉得本文对你有帮助,请给我点赞助。