Nginx缓存符号链接


12

我的Web服务器上有一个部署系统,每次部署应用程序时,它都会创建一个带时间戳的新目录,并将符号“当前”链接到该新目录。这一切在apache上都很好,但是在我设置的新的nginx服务器上,看起来好像正在运行“旧”部署中的脚本,而不是新的符号链接的脚本。

我已经阅读了一些有关如何解决此问题的教程和帖子,但没有太多信息,而且似乎也无济于事。这是我的虚拟主机文件:

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)

Answers:


22

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

在Q / A网站和论坛周围粘贴粘贴$realpath_root而不是使用的解决方案$document_root;它实际上是很难避免发现it.Yet,我只看到它做好解释通过一次拉斯姆斯·勒多夫。值得分享,因为它描述它的工作原理以及何时应使用它。

因此,当您通过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目录。这完全消除了此处描述的症状,这是正确的方法。这不是在操作缓存级别可以解决的问题。

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
Auris

1
嗨,非常感谢您的回答和解释,我的错误是DOCUMENT_ROOT影响到的假设$document root
Auris

2
我在服务器上使用Apache + php-fpm来解决此问题,并清除了部署时的opcached对我来说很有效,尽管我们有一个bash脚本而不是Capistrano。我认为这是一个更简单的解决方案,并且还是在部署时清除opcache的好习惯。Esa感谢您链接到Rasmus的宝贵评论!
卡洛斯·马夫拉

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-and-php-fpm-aed8a8ac1cd9

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.