links simbólicos de cache Nginx

8

Eu tenho um sistema de implantação no meu servidor web, toda vez que um aplicativo é implantado, ele cria um novo diretório com timestamp e links simbólicos "current" para o novo diretório. Isso tudo funcionou bem e ótimo no apache, mas no novo servidor nginx que eu configurei, parece que um script da implementação "antiga" está sendo executado em vez do novo link com link simbólico.

Eu li alguns tutoriais e postagens sobre como resolver isso, mas não há muita informação e nada parece funcionar. Aqui está o meu arquivo 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;
    }
}

e aqui está o meu 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;

Eu realmente aprecio se alguém puder me ajudar com isso, já que no momento toda a implantação envolve a exclusão da implantação anterior. O sistema é o Ubuntu 14.04.5 LTS; PHP 7.1; Nginx nginx / 1.4.6 (Ubuntu)

    
por Auris 05.05.2017 / 17:59

2 respostas

14

Embedded Variables, $realpath_root: an absolute pathname corresponding to the root or alias directive’s value for the current request, with all symbolic links resolved to real paths

A solução de usar $realpath_root em vez de $document_root é copiada e colada em todos os sites e fóruns de Q / A; na verdade, é difícil evitar encontrá-lo. No entanto, eu só o vi bem explicado uma vez por Rasmus Lerdorf . Vale a pena compartilhar como ele descreve porque funciona e quando deve ser usado.

So, when you deploy via something like Capistrano which does a symlink swap on the document root, you want all new requests to get the new files, but you don't want to screw over requests that are currently executing as the deploy is happening. What you really need to create a robust deploy environment is to have your web server be in charge of this. The web server is the piece of the stack that understands when a new request is starting. The opcode cache is too deep in the stack to know or care about that.

With nginx this is quite simple. Just add this to your config:

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

This tells nginx to realpath resolve the docroot symlink meaning that as far as your PHP application knows, the target of the symlink if the real document_root. Now, once a request starts, nginx will resolve the symlink as it stands at that point and for the duration of the request it will use the same docroot directory, even if the symlink switch happening mid-request. This entirely eliminates the symptoms described here and it is the correct approach. This isn't something that can be solved at the opcache level.

Kanishk Dudeja teve problemas com isso e adicionou um aviso útil: certifique-se de que essas alterações estejam realmente na configuração final, ou seja, após include fastcgi_params; , que de outra forma as substituirá.

    
por 05.05.2017 / 20:17
3

De link , parece que você pode solucionar o problema mudando

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

para

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

(ou seja, alterando o caminho de $document_root para $realpath_root ).

Eu não tenho acesso a um servidor nginx atualmente para confirmar isso (meu servidor doméstico está passando por uma reconstrução), mas a solução parece ser colaborada por link .

    
por 05.05.2017 / 18:40