多個靜態檔案目錄,單一 PHP FPM 伺服器

多個靜態檔案目錄,單一 PHP FPM 伺服器

我有兩個目錄需要提供靜態資產:

  1. /srv/web:靜態資源,包括影像、JavaScript、HTML 等。
  2. /srv/php:動態 PHP 腳本以及一些靜態資源。

我正在使用 NGINX 並按如下方式配置它:

server {
    listen 80;
    server_name _;

    # root /;
    index index.php index.html index.htm;
    try_files /srv/web/$uri /srv/php/$uri =404;

    location ~ \.php$ {
        root /srv/php;
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
#       fastcgi_param SCRIPT_FILENAME /srv/php$fastcgi_script_name;
        include fastcgi_params;
    }
}

我使用的是 Ubuntu 14.04,PHP FPM 軟體包版本是 5.5.9,NGINX 軟體包版本是 1.4.6。

這裡的簡單目標是先提供靜態文件/srv/web,如果失敗/srv/php,則傳回 404 \.php$

我目前遇到的問題是該index指令server沒有按計劃運行。我有一個index.html文件/srv/web,當我這樣做時

curl -is http://localhost/

我得到了 404。

這是設定具有多個檔案系統資料夾的 NGINX 網站以與 PHP 一起提供服務的理想方法嗎?關於為什麼我的靜態索引不起作用有什麼想法嗎?


更新

根據下面 AD7six 的回答,我已將配置更新為如下所示:

server {
    listen 80;
    server_name _; # listen at all host names

    # serve static files first from /srv/web, then from /srv/php, and any dynamic PHP files from
    # FastCGI/FPM at the Unix socket.
    location / {
        root /srv/web;
        index index.html index.htm;
        try_files $uri $uri/ @php;
    }

    location @php {
        root /srv/php;
        index index.php;
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        root /srv/php;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /srv/php/$fastcgi_script_name;
        include fastcgi_params;
    }
}

我的目錄列表如下所示:

/srv/
|-- php
|   |-- demo.php
|   |-- index.php
|   `-- phpstatic.txt
`-- web
    |-- static.html
    `-- subdir
        `-- index.html

3 directories, 5 files

取得靜態檔案和 PHP 檔案按計劃運作,取得/subdir/其索引運作正常,但如果我 GET /,我會收到 403 禁止,並且 nginx 抱怨目錄清單:

2015/08/24 21:50:59 [error] 9159#0: *7 directory index of "/srv/web/" is forbidden, client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", host: "localhost"

不知道為什麼會失敗,但至少聽起來是進步。

答案1

多個根不會那樣運作

使用此配置:

server {
    # root /;
    index index.php index.html index.htm;
    try_files /srv/web/$uri /srv/php/$uri =404;

沒有使用索引指令的請求處理,如所寫的,請求必須與檔案相符。使用調試日誌證實了這一點:

2015/08/24 08:12:11 [debug] 17173#0: *26 try files phase: 13
2015/08/24 08:12:11 [debug] 17173#0: *26 http script copy: "/srv/web/"
2015/08/24 08:12:11 [debug] 17173#0: *26 http script var: "/"
2015/08/24 08:12:11 [debug] 17173#0: *26 trying to use file: "/srv/web//" "/srv/web//"
2015/08/24 08:12:11 [debug] 17173#0: *26 http script copy: "/srv/php/"
2015/08/24 08:12:11 [debug] 17173#0: *26 http script var: "/"
2015/08/24 08:12:11 [debug] 17173#0: *26 trying to use file: "/srv/php//" "/srv/php//"
2015/08/24 08:12:11 [debug] 17173#0: *26 trying to use file: "=404" "=404"

使用try_files確實查找目錄的指令,如下所示:

try_files /srv/web/$uri /srv/web/uri/ /srv/php/$uri /srv/php/$uri/ =404;

也不起作用:

2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/web/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use file: "/srv/web//srv/web//index.html" "/srv/web//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/web/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use dir: "/srv/web//srv/web//index.html" "/srv/web//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/php/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use file: "/srv/php//srv/web//index.html" "/srv/php//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script copy: "/srv/php/"
2015/08/24 08:16:17 [debug] 17651#0: *33 http script var: "/srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use dir: "/srv/php//srv/web//index.html" "/srv/php//srv/web//index.html"
2015/08/24 08:16:17 [debug] 17651#0: *33 trying to use file: "=404" "=404"

請注意,「root」很混亂,try_files需要 url 而不是檔案路徑。我建議不要繼續嘗試使用此類解決方案 - 尤其是不是將根設定為/潛在地允許存取伺服器上的任何檔案。

使用兩個位置區塊

相反,讓事情變得簡單。此配置將提供所有靜態內容:

    root /srv/web;
    index index.html;
    try_files $uri $uri/;

此配置提供所有 php 內容:

    root /srv/php;
    index index.php;
    try_files $uri $uri/;

只需將它們放在一起即可:

location / {
    root /srv/web;
    index index.html;
    try_files $uri $uri/ @php;
    error_page 403 = @php; # see note below
}

location @php {
    root /srv/php;
    index index.php;
    try_files $uri $uri/ =404;
}

location ~ \.php$ {
    # as before
}

一個問題是,使用這種設定時,請求會與/srv/web該資料夾下的資料夾相符index.html檔案會拋出403錯誤(因為請求的是目錄,而且沒有目錄索引檔)。為了允許 php 也處理這些請求 - 有必要將 403 錯誤重定向到 php 處理程序。

相關內容