Nginx 缓存符号链接

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)

答案1

嵌入变量, $realpath_root:对应于或者别名 当前请求的指令值,所有符号链接均解析为真实路径

$realpath_root使用而不是 的解决方案$document_root在问答网站和论坛上随处可见;实际上很难避免找到它。然而,我只见过它解释曾经拉斯穆斯·勒多夫. 值得分享,因为它描述了为什么它有效并且什么时候它应该被使用。

因此,当您通过 Capistrano 之类的工具进行部署时,它会在文档根目录上进行符号链接交换,您希望所有新请求都能获取新文件,但您不想在部署过程中破坏当前正在执行的请求。要创建一个强大的部署环境,您真正需要的是让您的 Web 服务器负责这一点。Web 服务器是堆栈的一部分,它知道新请求何时开始。操作码缓存在堆栈中太深,无法知道或关心这一点。

使用 nginx 非常简单。只需将其添加到您的配置中:

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

这告诉 nginx 以 realpath 方式解析 docroot 符号链接,这意味着就您的 PHP 应用程序所知,符号链接的目标就是真正的 document_root。现在,一旦请求开始,nginx 将按当时的状态解析符号链接,并且在请求的持续时间内,它将使用相同的 docroot 目录,即使符号链接切换发生在请求中间。这完全消除了此处描述的症状,并且这是正确的方法。这不是可以在 opcache 级别解决的问题。

卡尼什克·杜德贾有问题有了这个,并添加了一个有用的通知:确保这些更改实际上将在最终配置中,即之后include fastcgi_params;覆盖它们。

答案2

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

相关内容