Konfiguracja Nginx dla projektów Symfony

Ten wpis został napisany dawno temu i może być już nieaktualny.

Z okazji wydania wersji 1.0.0 odświeżyłem nieco swoją wiedzę o Nginx. Od czasu, kiedy po raz pierwszy go konfigurowałem, wzbogacił się o kilka nowych dyrektyw i zmiennych. Dzięki temu mogłem uprościć swoją konfigurację dla projektów Symfony (zarówno symfony 1.x jak i Symfony2). Uwaga: Konfiguracje dostępne w Internecie podatne są na wykonanie pliku niePHPowego jako PHP. Więcej o problemie w "Setting up PHP-FastCGI and nginx? Don’t trust the tutorials: check your configuration!". O samej instalacji Nginx w Ubuntu przeczytacie w "Konfiguracji środowiska deweloperskiego PHP z Nginx w Ubuntu 11.04".

Konfiguracja

Według konwencji konfigurację każdego hosta dodajemy do osobnego pliku w katalogu /etc/nginx/sites-available/ i tworzymy do niej dowiązanie symboliczne w /etc/nginx/sites-enabled/. Poniższe reguły dla domen deweloperskich umieścimy w /etc/nginx/sites-available/dev i utworzymy do nich link /etc/nginx/sites-enabled/dev.

server {
    listen 80 default;
    server_name *.dev;

    root /var/www/$host/current/web;

    access_log /var/log/nginx/$host-access.log;
    error_log  /var/log/nginx/dev-error.log error;

    index app.php index.html index.htm;

    try_files $uri $uri/ @rewrite;

    location @rewrite {
        rewrite ^/(.*)$ /app.php/$1;
    }   

    location ~ \.php {
        # try_files $uri =404;

        fastcgi_index app.php;
        fastcgi_pass 127.0.0.1:9000;

        include fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }
}

Wyjaśnienie konfiguracji

    listen 80 default;

Nginx domyślnie nasłuchuje na porcie 80. W tym fragmencie istotny jest drugi parameter - "default". Dzięki niemu aktualnie tworzona konfiguracja wirtualnego hosta będzie domyślną.

    server_name *.dev;

Konfigurujemy dynamiczny wirtualny host, który akceptuje każdą domenę .dev (kuba.dev, mojprojekt.dev itd). Alternatywnie możemy podać listę domen  (np server_name zalas.pl). W takim przypadku każdy host zdefiniujemy w osobnej sekcji server {}.

    root /var/www/$host/current/web;

Wskazujemy katalog główny domeny. Zostanie ustalony dynamicznie na podstawie zmiennej $host (dla domeny kuba.dev będzie to /var/www/kuba.dev/current/web).

    access_log /var/log/nginx/$host-access.log;
    error_log  /var/log/nginx/dev-error.log error;

Definiujemy pliki logów. Każda domena otrzyma swój własny access log. Niestety nie możemy użyć zmiennej $host przy logowaniu błędów. Stąd wszystkie będą logowane do jednego pliku.

    index app.php index.html index.htm;

Ustalamy pliki indeksu. Jeśli żądanie dotyczyć będzie katalogu, to nginx spróbuje wywołać pliki tutaj wypisane. W Symfony2 domyślny kontroler to zwykle app.php, a w symfony 1.x index.php.

    try_files $uri $uri/ @rewrite;

Jest to bardzo elegancki sposób na czytelne URLe. Pozwala uniknąć niezalecanych ifów. Serwer sprawdzi najpierw, czy istnieje plik o danym URI, następnie  poszuka katalogu, a na końcu skieruje żądanie do tzw named location.

    location @rewrite {
        rewrite ^/(.*)$ /app.php/$1;
    }

Trafimy tutaj tylko, jeśli URI nie jest fizycznym plikiem lub katalogiem (w przeciwnym razie zadziała pierwszy lub drugi parametr dyrektywy try_files). Żądanie zostanie skierowane do domyślnego kontrolera (app.php).

    location ~ \.php {
        fastcgi_index app.php;
        fastcgi_pass 127.0.0.1:9000;

        include fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

Wszystkie żądania do PHP zostaną przekierowane do demona fastcgi (działającego lokalnie na porcie 9000). Oprócz dołączenia standardowych parametrów fastcgi z pliku fastcgi_params, zadbaliśmy o poprawną definicję PATH_INFO i SCRIPT_FILENAME. fastcgi_split_path_info podpowiada jak oddzielić plik kontrolera od ścieżki.

    location ~ /\.ht {
        deny all;
    }

Ignorujemy apache'owe pliki .htaccess, które dla nginx są tylko zwykłymi, tekstowymi plikami (nie chcemy żeby były dostępne przez przeglądarkę).

Jakub Zalas

Jakub Zalas

Architekt, Programista, Trener