既存のすべての静的ファイルをNGINXで直接提供し、残りをバックエンドサーバーにプロキシする方法。


87
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    if (-f $request_filename) {
        access_log off;
        expires 30d;
        break;
        }

    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8080; # backend server listening
        break;
        }
    }

上記は、Nginxを使用して既存のすべてのファイルを直接提供します(たとえば、NginxはPHPソースコードを表示するだけです)。それ以外の場合は、リクエストをApacheに転送します。* .phpのリクエストもApacheに渡されて処理されるように、ルールから* .phpファイルを除外する必要があります。

Nginxですべての静的ファイルを処理し、Apacheですべての動的ファイルを処理する必要があります。

編集:ホワイトリストアプローチがありますが、それはあまりエレガントではありません。これらの拡張機能をすべて参照してください。これは必要ありません。

location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires 30d;
    }
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    }

編集2:Nginxの新しいバージョンでは、try_files代わりにhttp://wiki.nginx.org/HttpCoreModule#try_filesを使用してください


明確にするために、上記のコードは静的ファイルがディスク上に存在する場合はそれを提供し、ファイルが存在しない場合はリクエストがApacheに渡されます。私のアプリケーションのすべてのURLはmod_rewrite(またはルーティング)を使用し、実際にはディスク上に存在しないため、これはほとんどの場合機能します。* .phpファイル名への直接アクセスのみが例外であり、Apacheで解析する必要があります。
fmalina 2009年

回答:


152

使用try_filesと名付けられた場所ブロック(「@apachesite」)。これにより、不要な正規表現の一致とifブロックが削除されます。もっと効率的な。

location / {
    root /path/to/root/of/static/files;
    try_files $uri $uri/ @apachesite;

    expires max;
    access_log off;
}

location @apachesite {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

更新:この構成の前提は、の下にphpスクリプトが存在しないこと/path/to/root/of/static/filesです。これは、ほとんどの最新のphpフレームワークで一般的です。従来のphpプロジェクトのphpスクリプトと静的ファイルの両方が同じフォルダーに混在している場合は、nginxで提供するすべてのファイルタイプをホワイトリストに登録する必要があります。


WordPressを使用しているので、nginxサーバーにアップロードフォルダーを配置する必要がありますか?
シャメロン2015

7
このソリューションに関する私の問題:nginxは他の場所(プロキシ)を使用せず、ディレクトリリストを表示しようとします。したがって、ディレクトリリストがアクティブ化されていないため、403がスローされます。 編集: OK、削除する$uri/と機能します。
ChristophLSA

1
これにより、/ exampleがapacheにプロキシされますが、/ example.phpをダウンロードできます。
テレンスジョンソン

1
@TerenceJohnsonphpファイルを静的ファイルフォルダーの下に置くのは安全ではありません。を設定しroot /path/to/root/of/*static*/files;たことに注意してください。phpファイルは、インターネットから直接アクセスできないように、別のフォルダーに配置する必要があります。
チュアン馬

2
私はそれがどうあるべきかを知っていますが、誰かがWebルートの下にすべてを持ち.htaccessファイルに依存している多くの一般的な既製のPHPアプリケーションの前にNginxを置いている場合、それらはコピーしてはいけません構成を貼り付けます。
テレンスジョンソン

18

これを試して:

location / {
    root /path/to/root;
    expires 30d;
    access_log off;
}

location ~* ^.*\.php$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

うまくいけば。正規表現はプレーンな文字列よりも優先度が高いため.php、対応する.phpファイルのみが存在する場合は、で終わるすべてのリクエストをApacheに認識させる必要があります。残りは静的ファイルとして処理されます。場所を評価する実際のアルゴリズムはここにあります


6

mod_rewriteを使用してスクリプトの拡張子を非表示にする場合、または/で終わるきれいなURLが好きな場合は、別の方向からこれにアプローチすることをお勧めします。nginxに、静的でない拡張子を持つものはすべてapacheに通過させるように指示します。例えば:

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
{
    root   /path/to/static-content;
}

location ~* ^!.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

このスニペットの最初の部分は、http//code.google.com/p/scalr/wiki/NginxStaticで見つけました。


これはうまく機能しましたが、縮小されたファイル(site.min.cssやmain.min.jsなど)でエラーが発生します。ロケーション正規表現でそれらをどのようにキャッチしますか?@lo_fye
ガース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.