
我有兩個目錄需要提供靜態資產:
/srv/web
:靜態資源,包括影像、JavaScript、HTML 等。/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 處理程序。