web-dev-qa-db-ja.com

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

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)

12
Auris

埋め込み変数$realpath_root:現在のリクエストの root または alias ディレクティブの値に対応する絶対パス名、すべてのシンボリックリンク実際のパスに解決

$realpath_rootの代わりに$document_rootを使用する解決策は、Q/Aサイトおよびフォーラム全体にコピーアンドペーストされます。それを見つけるのを避けることは実際には難しいですが、私は Rasmus Lerdorf によって説明された一度だけよく見ました。機能する理由いつ使用する必要があるかを説明しているので、共有する価値があります。

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

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

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

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

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

22
Esa Jokinen

https://unix.stackexchange.com/questions/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-and-php-fpm-aed8a8ac1cd9

3
Pak