雜談

一個 Nginx + PHP-FPM MVC PHP 部署的小故事

遇到的問題

我架設好 Nginx、PHP-FPM,也弄好了 SSL 證書,網站根目錄也對應了 MVC PHP 的 public 資料夾。 結果一打開瀏覽器,滿滿的「504 Gateway Time-out」…心裡的雷聲響個不停。

嘗試用 curl 測試本機 PHP-FPM TCP 端口 9000,居然卡住不動,甚至被 reset。 這時候我才意識到,不只是 PHP 或 Nginx 的設定問題,而是連線本身被擋住了。

排查流程

  • 確認 Nginx 與 PHP-FPM 都在跑
  • 檢查 PHP-FPM 聆聽的 TCP 端口
  • 測試 curl 本機連線
  • 檢查防火牆規則,發現 INPUT policy 是 DROP,阻擋了 127.0.0.1:9000
  • 嘗試開放 loopback 網路或端口,但依然 reset,原因是 PHP-FPM 用戶權限與 Nginx 不匹配

原來問題的核心是:Nginx 無法透過 TCP 連線 PHP-FPM ,這就導致了 504。

解決方案

我最後選擇把 PHP-FPM 改用 UNIX Socket ,不但避免防火牆問題,還解決了權限阻擋:

  • 修改 PHP-FPM pool 的 listen 為 socket,例如 /run/php-fpm.sock
  • 設定 socket owner 與 group 為 nginx,用戶權限 0660
  • 修改 Nginx 的 fastcgi_pass 指向 socket
  • 重啟 PHP-FPM 與 Nginx

測試後,一切正常!504 消失,網站可以透過 MVC PHP 正常呈現。

小結與教訓

  • TCP 模式容易被防火牆或權限問題阻擋,Socket 更穩定且安全
  • 504 Gateway Time-out 大多是 upstream (PHP-FPM) 無法連線造成
  • Nginx server block 需正確對應 HTTPS、server_name、root
  • PHP-FPM 權限要對應 Nginx 用戶,否則即使端口開通也可能 reset

架設自己的網站其實很容易踩雷,但每一步排查都能學到寶貴的經驗。下次遇到類似 504,我只要先想: 「Nginx 能連到 PHP-FPM 嗎?」就對了。