🔰 前言
在容器化環境中,常見的架構是將 Apache 與 PHP-FPM 分開成兩個容器執行。
Apache 容器負責靜態內容(HTML、CSS、JS)與 HTTP 請求處理,而 PHP-FPM 容器則負責 PHP 程式的執行。
若你的 Apache 容器目前僅能顯示靜態頁面(無法執行 PHP 程式),
可以透過設定 Apache 的網站組態檔,將 .php 檔案交由 PHP-FPM 容器 處理。
本文將說明整合步驟與注意事項。
🧩 環境假設
假設目前有以下環境:
- 一個 Apache 容器,網站根目錄為
/var/www/html - 一個 PHP-FPM 容器,例如容器名稱為
php-fpm,對外監聽埠為9000 - 兩者皆在同一個 Docker 自訂網路(如
web-network)
⚙️ 步驟一:確認網路連線
首先確認 Apache 與 PHP-FPM 是否在同一個網路中:
docker network inspect web-network
如果未在同一網段,可手動加入:
docker network connect web-network apache
docker network connect web-network php-fpm
⚙️ 步驟二:啟用 Apache 代理模組
在 Apache 容器中啟用以下模組:
a2enmod proxy proxy_fcgi setenvif
啟用後重新啟動 Apache:
service apache2 restart
⚙️ 步驟三:修改 Apache 網站設定檔
編輯網站設定檔(例如 /etc/apache2/sites-available/000-default.conf),
在 <VirtualHost> 區塊內加入以下設定:
<VirtualHost *:80>
ServerName example.local
DocumentRoot /var/www/html
<Directory "/var/www/html">
AllowOverride All
Require all granted
</Directory>
# 將 PHP 檔案轉交給 PHP-FPM 容器
<FilesMatch "\.php$">
SetHandler "proxy:fcgi://php-fpm:9000"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
設定說明:
| 參數 | 說明 |
|---|---|
SetHandler "proxy:fcgi://php-fpm:9000" | 告訴 Apache,所有 .php 檔案交由 PHP-FPM 處理 |
php-fpm | 為 PHP-FPM 容器名稱(同時也是 Docker network 內的 hostname) |
9000 | PHP-FPM 預設監聽埠 |
⚙️ 步驟四:確認 PHP-FPM 是否可連線
在 Apache 容器中測試連線:
apt update && apt install -y netcat
nc -vz php-fpm 9000
若顯示:
Connection to php-fpm 9000 port [tcp/*] succeeded!
表示網路連線正常。
⚙️ 步驟五:測試 PHP 執行
在 Apache 的網站目錄建立一個測試檔:
echo "<?php phpinfo(); ?>" > /var/www/html/info.php
在瀏覽器輸入:
http://<你的伺服器 IP>/info.php
若看到 PHP 資訊頁(phpinfo),即表示整合成功。
🧰 範例:使用 Docker Compose 建立完整環境
以下為簡易範例:
version: "3.9"
services:
apache:
image: httpd:2.4
container_name: apache
ports:
- "80:80"
volumes:
- ./html:/usr/local/apache2/htdocs/
- ./apache-config.conf:/usr/local/apache2/conf/httpd.conf
depends_on:
- php-fpm
networks:
- web-network
php-fpm:
image: php:8.3-fpm
container_name: php-fpm
volumes:
- ./html:/var/www/html
networks:
- web-network
networks:
web-network:
driver: bridge
✅ 整合摘要
| 元件 | 功能 | 備註 |
|---|---|---|
| Apache 容器 | 處理 HTTP 請求、靜態內容 | 將 .php 轉交至 PHP-FPM |
| PHP-FPM 容器 | 執行 PHP 程式 | 監聽 port 9000 |
| Docker Network | 讓兩容器互通 | 建議使用 bridge 或自訂網段 |
⚠️ 常見問題
| 問題 | 原因 | 解法 |
|---|---|---|
| PHP 無法執行 | 模組未載入 | 確認 mod_proxy、mod_proxy_fcgi、mod_setenvif 已啟用 |
| 顯示 502 Bad Gateway | 容器網路未互通 | 檢查是否在同一 Docker network |
| 無法讀取檔案 | 權限不足 | 確保兩容器共用 volume 且權限正確 |
| 無法解析 php-fpm 名稱 | 網域名稱錯誤 | 檢查 SetHandler 目標是否與容器名稱一致 |
💡 總結
在容器化架構中,讓 Apache 與 PHP-FPM 分離可提高彈性與維護性。
只要確保:
- 兩容器在同一個 Docker 網路
- Apache 啟用
proxy_fcgi模組- VirtualHost 設定中正確指向
php-fpm:9000即可讓 PHP 程式在 PHP-FPM 容器中順利執行。