rich@rich-vb-u24:~/pure-php-app$ cat nginx/practice.conf
server {
    # 監聽 8080 埠並啟用 SSL 加密
    listen 8080 ssl;
    server_name _;	
	
    # 🔒 SSL 憑證與金鑰路徑(請根據實際存放位置修改)
    ssl_certificate /etc/letsencrypt/live/longfutemple.duckdns.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/longfutemple.duckdns.org/privkey.pem;

    # 🛡️ 建議加入的安全加密協定與演算法設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
	
    # 1. 偵測並阻擋網址中包含常見的 LFI 路徑與 PHP 標籤
    if ($request_uri ~* "(\.\./|boot\.ini|etc/passwd|win\.ini|<\?php)") {
        return 403;
    }

    # 2. 偵測並阻擋 **User-Agent** 中包含 PHP 惡意代碼
    if ($http_user_agent ~* "(<\?php|eval\(|base64_)") {
        return 403;
    }
    # 🔒 3. 🛡️ 新增:資安個資防護!禁止任何人直接下載 .csv 志工名冊
    location ~* \.csv$ {
        deny all;
        return 403;
    }
	
    root /var/www/htmlP;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    # 遇到 .php,丟給 php-practice 容器
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-practice:9000; # 🌟 精準指向 練習區 的 PHP 容器
        fastcgi_index index.php;
        include fastcgi_params;
        #fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name; # php ext file 強制走容器的/var/www/html 路徑 
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

從你執行的測試結果來看,掛載完全正常(Nginx 容器內確實看得到檔案),且 Nginx 的語法測試也完全通過。

既然檔案在、設定也對,卻依然噴出 404,那問題就只剩下最後一個最隱蔽、也最常見的 Docker 跨容器地雷:「你的 Nginx 容器有讀到檔案,但 php-practice 容器可能根本找不到檔案!」

請注意這行關鍵設定:

fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;

這行是告訴 php-practice 容器:「請去執行你裡面的 /var/www/html/volunteer_survey.php」。

如果 php-practice 容器內部的 /var/www/html 資料夾其實是空的,或者掛載錯了,PHP 就會對 Nginx 回報找不到檔案,而 Nginx 就會一臉無辜地對瀏覽器顯示「404 Not Found」(這個 404 是 PHP 拋出來的,不是 Nginx 的 404)。


🛠️ 終極驗證與修正步驟

步驟一:檢查 php-practice 容器內部到底有沒有檔案?

請在終端機輸入這行指令,直接看 PHP 容器內部:

docker exec -it php-for-practice ls -la /var/www/html

(注意:要檢查的是 php-for-practice 容器,也就是你的 PHP 服務)

步驟二:強制清除快取並重啟整個專案

Docker Compose 有時候在修改了 Volume 掛載路徑後,如果是用 nginx -s reload,只有 Nginx 刷新,但 PHP 容器依然抓著舊的容器實例(Instance)。

請直接執行以下強制重組命令,這會徹底清除 Docker 容器殘留的舊路徑快取:

# 1. 徹底停止並刪除舊容器(資料不會不見,因為檔案在你的主機上)
docker compose down# 2. 強制重新編譯、建立並啟動所有容器
docker compose up -d --build --force-recreate

步驟三:用指令直接跟容器內的網頁「借測試」