Link simbolici nella cache di Nginx


12

Ho un sistema di distribuzione sul mio server web, ogni volta che un'app viene distribuita crea una nuova directory con data e ora e collegamenti simbolici "correnti" alla nuova directory. Tutto questo ha funzionato perfettamente su apache, ma sul nuovo server nginx che ho impostato, sembra che sia in esecuzione uno script della "vecchia" distribuzione anziché quello nuovo con collegamento simbolico.

Ho letto alcuni tutorial e post su come risolverlo, ma non ci sono molte informazioni e nulla sembra funzionare. Ecco il mio file 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;
    }
}

ed ecco i miei 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;

Gradirei davvero se qualcuno potesse aiutarmi con questo dato che al momento ogni distribuzione comporta l'eliminazione della distribuzione precedente. Il sistema è Ubuntu 14.04.5 LTS; PHP 7.1; Nginx nginx / 1.4.6 (Ubuntu)

Risposte:


22

Variabili integrate , $realpath_root: un percorso assoluto corrispondente alla radice o alias il valore della direttiva per la richiesta corrente, con tutti i link simbolici deliberato di percorsi reali

La soluzione di utilizzo $realpath_rootanziché $document_rootcopia è incollata in tutto i siti e forum Q / A; in realtà è difficile evitare di trovarlo. Tuttavia, l'ho visto ben spiegato solo una volta da Rasmus Lerdorf . Vale la pena condividere perché descrive perché funziona e quando dovrebbe essere usato.

Pertanto, quando si esegue la distribuzione tramite qualcosa come Capistrano che esegue uno scambio di link simbolici nella radice del documento, si desidera che tutte le nuove richieste ottengano i nuovi file, ma non si desidera rovinare le richieste attualmente in esecuzione mentre la distribuzione sta avvenendo. Ciò di cui hai veramente bisogno per creare un ambiente di distribuzione affidabile è che il tuo server web sia responsabile di questo. Il web server è il pezzo dello stack che capisce quando inizia una nuova richiesta. La cache del codice operativo è troppo profonda nello stack per saperlo o preoccuparsene.

Con nginx questo è abbastanza semplice. Aggiungi questo alla tua configurazione:

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

Questo dice a nginx di risolvere il percorso simbolico docroot, il che significa che, per quanto sa la tua applicazione PHP, la destinazione del collegamento simbolico se il documento reale root. Ora, una volta avviata una richiesta, nginx risolverà il collegamento simbolico così com'è in quel momento e per tutta la durata della richiesta utilizzerà la stessa directory docroot, anche se il passaggio del collegamento simbolico avviene a metà richiesta. Questo elimina completamente i sintomi qui descritti ed è l'approccio corretto. Questo non è qualcosa che può essere risolto a livello di opcache.

Kanishk Dudeja ha avuto problemi con questo e ha aggiunto un avviso utile: assicurati che questi cambiamenti saranno effettivamente nella configurazione finale, cioè dopo include fastcgi_params;che altrimenti li sovrascriveranno.


Ciao, questa è un'ottima risposta, ma se noti nella mia configurazione ho fastcgi_param DOCUMENT_ROOT $ realpath_root; fastcgi_param SCRIPT_FILENAME $ root_documento $ fastcgi_script_name; incluso dopo fastcgi_params e questo non aiuta in realtà. Quando riavvio php-fpm i symlink vengono risolti. Ciò indicherebbe che ho invece un problema di memorizzazione nella cache php?
Auris,

Rivedere. Il tuo SCRIPT_FILENAMEha $document_root, non è $realpath_root.
Esa Jokinen,

Hmm ... ma DOCUMENT_ROOTè impostato sul $realpath_rootmodo in cui lo capisco, dovrebbe incatenare il valore o mi sbaglio completamente e DOCUMENT_ROOTnon è collegato a$document_root
Auris

1
Ciao, grazie mille per la tua risposta e la tua spiegazione, il mio errore è stato il presupposto che DOCUMENT_ROOTinfluenza$document root
Auris,

2
Sto usando Apache + php-fpm sui server con questo problema e la cancellazione opcached sulla distribuzione ha funzionato per me, abbiamo uno script bash per la distribuzione non Capistrano però. Penso che sia una soluzione più semplice ed è una buona pratica cancellare comunque il tuo opcache durante la distribuzione. Esa grazie per il link al commento dei The Rasmus che è oro!
Carlos Mafla,

3

Da /unix/157022/make-nginx-follow-symlink , sembra che potresti essere in grado di aggirare il problema modificando

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

per

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

(ovvero cambiando il percorso da $document_roota $realpath_root).

Al momento non ho accesso a un server nginx per confermarlo (il mio server di casa è attualmente in fase di ricostruzione), ma la soluzione sembra essere collaborata da https://medium.com/@kanishkdudeja/truly-atomic-deployments -con-nginx-e-php-fpm-aed8a8ac1cd9 .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.