Nginxキャッシングシンボリックリンク


12

Webサーバーに展開システムがあり、アプリが展開されるたびに、タイムスタンプ付きの新しいディレクトリが作成され、新しいディレクトリへの「現在の」シンボリックリンクが作成されます。これはすべてApacheでうまく機能しましたが、設定した新しいnginxサーバーでは、新しいシンボリックリンクの代わりに「古い」デプロイメントのスクリプトが実行されているようです。

私はこれを解決する方法に関するいくつかのチュートリアルと投稿を読みましたが、あまり情報がなく、何も機能していないようです。これが私のvhostファイルです。

server {
    listen 80;

    server_name ~^(www\.)?(?<sname>.+?).testing.domain.com$;
    root /var/www/$sname/current/public;
    index index.html index.htm index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~* \.(jpg|jpeg|gif|png|bmp|ico|pdf|flv|swf|exe|html|htm|txt|css|js) {
        add_header        Cache-Control public;
        add_header        Cache-Control must-revalidate;
        expires           7d;
    }

    location ~ \.php$ {
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_index index.php;
    }

    location ~ /\.ht {
        deny all;
    }
}

ここに私のfastcgi_paramsがあります:

fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name;
fastcgi_param   QUERY_STRING        $query_string;
fastcgi_param   REQUEST_METHOD      $request_method;
fastcgi_param   CONTENT_TYPE        $content_type;
fastcgi_param   CONTENT_LENGTH      $content_length;

fastcgi_param   SCRIPT_NAME     $fastcgi_script_name;
fastcgi_param   REQUEST_URI     $request_uri;
fastcgi_param   DOCUMENT_URI        $document_uri;
fastcgi_param   DOCUMENT_ROOT           $realpath_root;
fastcgi_param   SERVER_PROTOCOL     $server_protocol;

fastcgi_param   GATEWAY_INTERFACE   CGI/1.1;
fastcgi_param   SERVER_SOFTWARE     nginx/$nginx_version;

fastcgi_param   REMOTE_ADDR     $remote_addr;
fastcgi_param   REMOTE_PORT     $remote_port;
fastcgi_param   SERVER_ADDR     $server_addr;
fastcgi_param   SERVER_PORT     $server_port;
fastcgi_param   SERVER_NAME     $server_name;

fastcgi_param   HTTPS           $https if_not_empty;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param   REDIRECT_STATUS     200;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;

現時点ではすべての展開で以前の展開を削除する必要があるため、誰かがこれを手伝ってくれると本当にありがたいです。システムはUbuntu 14.04.5 LTSです。PHP 7.1; Nginx nginx / 1.4.6(Ubuntu)

回答:


22

埋め込み変数$realpath_root: 現在の要求のルートまたはエイリアスディレクティブの値に対応する絶対パス名。すべてのシンボリックリンクが実際のパスに解決されます。

$realpath_root代わりに使用するソリューションは$document_root、Q / Aサイトおよびフォーラム全体にコピーアンドペーストすることです。見つけるのを避けるのは実際には難しいですが、ラスムス・ラードルフによって一度だけ説明されるのを見たことがあります。なぜ機能し、いつ使用すべきかを説明するので、共有する価値があります。

そのため、ドキュメントルートでシンボリックリンクスワップを行うCapistranoなどを介してデプロイする場合、すべての新しいリクエストで新しいファイルを取得する必要がありますが、デプロイの実行中に現在実行中のリクエストをめちゃくちゃにしたくありません。堅牢なデプロイ環境を作成するために本当に必要なのは、Webサーバーにこれを担当させることです。Webサーバーは、新しいリクエストがいつ開始されるかを理解するスタックの一部です。オペコードキャッシュがスタックの深すぎて、それを認識したり、気にしたりできません。

nginxでは、これは非常に簡単です。これを設定に追加するだけです:

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;

これにより、nginxはdocrootシンボリックリンクをrealpathで解決するようになります。つまり、PHPアプリケーションが知る限り、実際のdocument_rootであればシンボリックリンクのターゲットになります。現在、リクエストが開始されると、nginxはその時点でシンボリックリンクを解決し、リクエストの途中でシンボリックリンクの切り替えが発生しても、同じdocrootディレクトリを使用します。これにより、ここで説明した症状が完全に排除され、正しいアプローチになります。これは、opcacheレベルで解決できるものではありません。

Kanishk Dudejaにこれに関する問題があり、有用な通知が追加されました。これらの変更が実際に最終構成にあることを確認include fastcgi_params;してください。


こんにちは、これは素晴らしい答えですが、私の設定で気づいた場合、fastcgi_param DOCUMENT_ROOT $ realpath_root; fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name; fastcgi_paramsの後に含まれていますが、これは実際には役に立ちません。php-fpmを再起動すると、シンボリックリンクが解決されます。これは、代わりにphpキャッシュの問題があることを示していますか?
オーリス

修正します。あなたSCRIPT_FILENAMEが持っているの$document_rootではない$realpath_root
エサヨキネン

うーん...しかしDOCUMENT_ROOTに設定されている$realpath_root私はそれを理解する方法は、それが連鎖値を引く必要がありますので、または私は完全に間違っているとDOCUMENT_ROOTに関連していない$document_root
オーリス

1
こんにちは、回答と説明に感謝します。私の間違いは、DOCUMENT_ROOT影響を与える仮定でした$document root
Auris

2
この問題のあるサーバーでApache + php-fpmを使用していますが、デプロイ時にopcachedをクリアするとうまくいきましたが、カピストラーノではなくデプロイ用のbashスクリプトがあります。私はより簡単なソリューションだと思うし、とにかくデプロイ時にopcacheをクリアするのは良い習慣だと思います。Esaは、金のラスマスコメントへのリンクをありがとう!
カルロスマフラ

3

/unix/157022/make-nginx-follow-symlinksから、変更することで問題を回避できるようです

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

(つまり、パスをから$document_rootに変更します$realpath_root)。

現在、これを確認するためのnginxサーバーへのアクセス権はありません(ホームサーバーは現在再構築中です)が、ソリューションはhttps://medium.com/@kanishkdudeja/truly-atomic-deploymentsによって共同作業されているようです-with-nginxの-と-PHP-FPM-aed8a8ac1cd9

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.