web-dev-qa-db-fra.com

Nginx Caching Symlinks

J'ai un système de déploiement sur mon serveur Web, chaque fois qu'une application est déployée, elle crée un nouveau répertoire horodatage et des symboles "Current" dans le nouveau répertoire. Tout cela a fait de la bonne et idéale sur Apache, mais sur le nouveau serveur Nginx que j'ai mis en place, il semble que un script de l'ancien déploiement est en cours d'exécution au lieu du nouveau symbolisé.

J'ai lu des tutoriels et des postes sur la façon de résoudre ce problème, mais il n'y a pas beaucoup d'informations et rien ne semble fonctionner. Voici mon fichier 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;
    }
}

et voici mes 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;

J'apprécierais vraiment si quelqu'un pouvait m'aider avec cela au moment où chaque déploiement consiste à supprimer le déploiement précédent. Le système est Ubuntu 14.04.5 LTS; PHP 7.1; NGinx NGinx/1.4.6 (Ubuntu)

12
Auris

Variables incorporées , $realpath_root: Un chemin de chemin absolu correspondant à la valeur racine ou alias valeur de la directive pour la demande actuelle, avec tous les symboliques Liens résolus à des chemins réels

La solution d'utilisation $realpath_root Au lieu de $document_root Est collé-collé tout autour des sites Q/A et des forums; Il est effectivement difficile d'éviter de trouver .YET, je ne l'ai pas vu bien expliqué une fois par Rasmus Lerdorf . Cela vaut la peine de partager comme il décrit pourquoi Cela fonctionne et Quand Il devrait être utilisé.

Donc, lorsque vous déployez via quelque chose comme Capistrano, qui fait un swap Symlink sur la racine du document, toutes les nouvelles demandes d'obtention des nouveaux fichiers, mais vous ne souhaitez pas visser les demandes qui exécutent actuellement lorsque le déploiement se produit. Ce que vous devez vraiment créer un environnement de déploiement robuste, c'est que votre serveur Web soit responsable de cela. Le serveur Web est le morceau de la pile qui comprend lorsqu'une nouvelle demande commence. Le cache OPCODE est trop profond dans la pile pour connaître ou se soucier de cela.

Avec Nginx c'est assez simple. Il suffit d'ajouter ceci à votre configuration:

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

Cela indique à Nginx à Realpath résoudre le docommande Symlink signification que, aussi loin que votre application PHP sait, la cible du symbole symbolique si le vrai document_root. Maintenant, une fois qu'une requête démarre, Nginx résoudra le symbole SMLINK tel qu'il est à ce stade et pendant la durée de la demande, il utilisera le même répertoire de la doconce, même si le commutateur Symlink a lieu à mi-demande. Cela élimine entièrement les symptômes décrits ici et c'est la bonne approche. Ce n'est pas quelque chose qui peut être résolu au niveau de l'opcache.

Kanishk Dudeja eu des problèmes avec cela et ajouté un avis utile: assurez-vous que ces modifications seront réellement en configuration finale, c'est-à-dire après include fastcgi_params;.

22
Esa Jokinen

De https://unix.stackexchange.com/questions/157022/make-nginx-slollow-symlinks , il semble que vous puissiez pouvoir contourner le problème en modifiant

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

à

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

(c'est-à-dire changer le chemin de $document_root à $realpath_root).

Je n'ai pas accès à un serveur Nginx à présent pour confirmer cela (mon serveur d'accueil est en cours de reconstruction), mais la solution semble être collaborée par https://medium.com/@kanishkdudeja/truly -Atomic-déploiements-avec-nginx-and-php-fpm-AED8A8AC1CD9 .

3
Pak