複数の静的ファイルディレクトリ、単一の PHP FPM サーバー

複数の静的ファイルディレクトリ、単一の PHP FPM サーバー

静的アセットを提供する必要があるディレクトリが 2 つあります。

  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$Unix ソケット経由で PHP FPM から要求され、これは機能します。

私が現在抱えている問題は、indexのディレクティブがserver計画通りに機能していないことです。index.htmlにファイルがあり/srv/web

curl -is http://localhost/

404 が表示されます。

これは、PHP と並行して複数のファイルシステム フォルダーを提供する NGINX サイトを設定する最も理想的な方法でしょうか? 静的インデックスが機能しない理由について何か考えはありますか?


アップデート

以下の 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"

「ルート」は混乱しており、try_filesファイルパスではなくURLを期待していることに注意してください。この種の解決策を今後も使用しないことをお勧めします。特にないルートを次のように設定し/潜在的にサーバー上の任意のファイルにアクセスできるようにします。

2つのロケーションブロックを使用する

代わりに、シンプルにしてください。この設定はすべての静的コンテンツを提供します。

    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
}

1つの注意点は、このような設定では/srv/webしないファイルがあると、index.html403 エラーがスローされます (要求はディレクトリに対するものであり、ディレクトリ インデックス ファイルがないため)。これらの要求も PHP で処理できるようにするには、403 エラーを PHP ハンドラーにリダイレクトする必要があります。

関連情報