Dowiązania symboliczne buforowania Nginx

12

Mam system wdrażania na moim serwerze internetowym, za każdym razem, gdy aplikacja jest wdrażana, tworzy nowy katalog ze znacznikiem czasu i dowiązania symboliczne „bieżące” do nowego katalogu. Wszystko działało dobrze i dobrze na Apache, ale na nowym serwerze Nginx, który skonfigurowałem, wygląda na to, że uruchamiany jest skrypt ze „starego” wdrożenia zamiast nowego z dowiązaniem symbolicznym.

Przeczytałem kilka samouczków i postów na temat rozwiązania tego problemu, ale nie ma zbyt wielu informacji i nic nie działa. Oto mój plik 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;
    }
}

a oto moje 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;

Byłbym naprawdę wdzięczny, gdyby ktoś mógł mi w tym pomóc, ponieważ w tej chwili każde wdrożenie wymaga usunięcia poprzedniego wdrożenia. System to Ubuntu 14.04.5 LTS; PHP 7.1; Nginx nginx / 1.4.6 (Ubuntu)

Auris
źródło

Odpowiedzi:

22

Zmienne wbudowane , $realpath_root: absolutna ścieżka odpowiadającej korzeń lub alias wartości dyrektywy dla bieżącego żądania, z wszystkich linków symbolicznych rozwiązane do rzeczywistych ścieżek

Rozwiązanie polegające na użyciu $realpath_rootzamiast zamiast $document_rootjest wklejane we wszystkich witrynach i forach Q / A; tak naprawdę trudno jest go nie znaleźć, ale widziałem to dobrze wyjaśnione tylko raz przez Rasmus Lerdorf . Warto się nią podzielić, ponieważ opisuje, dlaczego działa i kiedy należy go używać.

Tak więc, kiedy wdrażasz za pomocą czegoś takiego jak Capistrano, który dokonuje wymiany dowiązań symbolicznych w katalogu głównym dokumentu, chcesz, aby wszystkie nowe żądania otrzymywały nowe pliki, ale nie chcesz przekręcać żądań, które są obecnie wykonywane w trakcie wdrażania. To, czego naprawdę potrzebujesz, aby stworzyć solidne środowisko wdrażania, to mieć za to swój serwer internetowy. Serwer WWW to część stosu, która rozumie, kiedy rozpoczyna się nowe żądanie. Pamięć podręczna opcode jest zbyt głęboko w stosie, aby o tym wiedzieć lub się tym przejmować.

Z Nginx jest to dość proste. Po prostu dodaj to do swojej konfiguracji:

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

Mówi to nginx, aby realpath rozpoznał dowiązanie symboliczne docroot, co oznacza, o ile wie twoja aplikacja PHP, cel dowiązania symbolicznego, jeśli prawdziwy katalog_główny_dokumentu. Teraz, gdy żądanie zostanie uruchomione, nginx rozpozna dowiązanie symboliczne w takim stanie, w jakim się znajduje w tym momencie i przez czas trwania żądania użyje tego samego katalogu docroot, nawet jeśli przełącznik dowiązania symbolicznego dzieje się w połowie żądania. To całkowicie eliminuje opisane tutaj objawy i jest to prawidłowe podejście. Nie można tego rozwiązać na poziomie opcache.

Kanishk Dudeja miał z tym problemy i dodał użyteczną uwagę: upewnij się, że zmiany te faktycznie będą w ostatecznej konfiguracji, tj. Po include fastcgi_params;czym w inny sposób je zastąpią.

Esa Jokinen
źródło
Cześć, to świetna odpowiedź, ale jeśli zauważysz w mojej konfiguracji, mam fastcgi_param DOCUMENT_ROOT $ realpath_root; fastcgi_param SCRIPT_FILENAME $ katalog_główny dokumentu $ fastcgi_script_name; uwzględnione po fastcgi_params, a to w rzeczywistości nie pomaga. Kiedy ponownie uruchamiam php-fpm, dowiązania symboliczne zostają rozwiązane. Czy to wskazuje, że zamiast tego mam problem z buforowaniem php?
Auris,
Poprawić. Twój SCRIPT_FILENAMEma $document_root, nie $realpath_root.
Esa Jokinen
Hmm ... ale DOCUMENT_ROOTjest ustawiony $realpath_roottak, aby go zrozumieć, powinien łańcuch ciągnąć wartość lub jestem całkowicie w błędzie i DOCUMENT_ROOTnie jest związany z$document_root
Auris
1
Cześć, bardzo dziękuję za odpowiedź i wyjaśnienie, mój błąd polegał na założeniu, które DOCUMENT_ROOTma wpływ$document root
Auris,
2
Używam Apache + php-fpm na serwerach z tym problemem i wyczyszczenie opcached przy wdrożeniu działało dla mnie, mamy jednak skrypt bash do wdrożenia, ale nie Capistrano. Myślę, że jest to prostsze rozwiązanie i dobrą praktyką jest wyczyszczenie opcache po wdrożeniu. Esa dziękuję za link do komentarza Rasmus, który jest złoty!
Carlos Mafla,
3

Z /unix/157022/make-nginx-follow-symlinks wydaje się, że możesz obejść ten problem, zmieniając

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

do

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

(tj. zmiana ścieżki z $document_rootna $realpath_root).

Obecnie nie mam dostępu do serwera nginx, aby to potwierdzić (mój serwer macierzysty jest obecnie w trakcie przebudowy), ale wydaje się, że rozwiązanie współpracuje z https://medium.com/@kanishkdudeja/truly-atomic-deployments -z-nginx-and-php-fpm-aed8a8ac1cd9 .

Pak
źródło