NGINX jest serwerem webowym mającym udział ponad 25% na rynku globalnym. Jest to drugi najpopularniejszy serwer webowy ( zaraz po ISS od Microsoftu – 31,9% ,a przed apache 21%).
Pytanie zatem czemu wybieramy NGINX?
Rozwiązanie Microsoftu odpada, jako że Magento 2 wymaga Linuksa (nawet FreeBSD nas tu nie uratuje).
Popularne serwery www
Na apache jak najbardziej moglibyśmy takie rozwiązanie postawić, ale nie bez powodu od 2012 roku apache pikuje ostro w dół w statystykach. NGINX’owi przybywa użytkowników (statystyki wg Netcrafta. Dla osób bliżej zainteresowanych tematem odsyłam do strony twórców NGINX.
Apache daje nam spore możliwości za pomocą modułów i obsługi .htaccess. Niestety o ile to rozwiązanie jest dobre dla hostingów współdzielonych to w naszym przypadku tylko obciąża dysk (każde zapytanie do serwera przeszukuje katalog bieżący i katalogi wyżej w strukturze w poszukiwaniu tego pliku). Fakt, że da się tą opcje wyłączyć, ale wtedy tracimy duży atut apache.
Nginx jest na pewno bardziej skomplikowany w konfiguracji, ale Magento 2 dostarcza nam przykładowy plik konfiguracyjny. W czystych testach wydajnościowych NGINX jednak wygrywa i jak spojrzymy na większość dużych stron internetowych najczęściej będzie tam właśnie NGINX.
NGINX i Varnish
Czujnym czytelnikom zapewne nasunie się pytanie „skąd wynika tak pogmatwana konfiguracja NGINX z Varnish?”.
Varnish jest serwerem cachującym i potrafi obsługiwać zapytania HTTP bez problemu.
Dlaczego więc jako pierwszy serwer z którym spotka się klient to NGINX, a nie Varnish?
Kiedyś, kiedy jeszcze szyfrowane strony były domeną głównie banków, takie rozwiązanie jak najbardziej się stosowało. Varnish jednak ma jedną dużą wadę – nie potrafi obsługiwać ruchu szyfrowanego. Na szczęście jednak możemy ten problem rozwiązać za pomocą właśnie NGINXa.
Dochodzimy tutaj do momentu w którym musimy rozbić NGINXa na części pierwsze. To co robi NGINX w naszym przypadku możemy podzielić na:
- Terminowanie ruchu HTTPS (sam NGINX odbiera tutaj zapytanie HTTPS rozpakowuje (rozszyfrowuje) i zamienia na zapytanie już nieszyfrowane (HTTP). To zapytanie jest wysyłane do Varnisha
- Jako, że przeglądarki wciąż domyślnie używają protokołu HTTP, a nie HTTPS musimy przekierować użytkowników z HTTP na HTTPS
- Obsługa zapytań na które nie odpowie nam Varnish. Tutaj potrzebujemy przekazywać zapytania PHP do serwera PHP-FPM
Konfiguracja NGINX
Uff… Wiem, że wygląda to dość skomplikowanie i łatwo się w tym pogubić. Na nasze szczęście NGINX podobnie jak apache pozwala nam tworzyć wirtualne hosty (Virtual Host), co przekłada się na stworzenie 3 wirtualnych hostów gdzie każdy pełni inną rolę.
Jedyny plik jaki
wymaga edycji to plik default znajdujący się w katalogu
/etc/nginx/site-enabled/
(czyli bardzo podobnie do apache). Zacznijmy
od terminowania ruchu. Wyjaśnienie konfiguracji zrobię w postaci
komentarza na końcu linii
server { #Każdy wirtualny host zaczyna się od sekcji server
listen 443 ssl default_server; // Ustawienie, że słuchamy na porcie 443 i będzie to SSL (HTTPS) dla IPv4
listen [::]:443 ssl default_server; // To samo dla Ipv6
ssl_certificate /etc/ssl/domena.chain.crt; // Tutaj jest różnica między apache,a nginx. Plik certyfikatu zawiera zarówno sam certyfikat jak i cały jego łańcuch (plik jest tekstowy)
ssl_certificate_key /etc/ssl/domena.key; // Klucz naszego certyfikatu
ssl_session_cache shared:le_nginx_SSL:1m; // Niżej parametry sesji SSL. Opcjonalne
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
gzip on; // Chcemy, aby strona była kompresowana.
gzip_comp_level 6; // parametry kompresji
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
image/svg+xml;
gzip_vary on;
Drugi wirtualny host jest jeszcze prostszy. Tutaj wystarczy przekierować ruch na inny port. Robimy to za pomocą poniższej konfiguracji
server {
listen {{Nasz adres Ipv4}}:80; // Nasłuchujemy na zewn. adresie IPv4
listen {{Nasz adres Ipv6}}:80; // Nasłuchujemy na zewn. adresie IPv6
server_name www.domena.pl domena.pl; // tutaj wpisujemy domenę naszego sklepu
return 301 https://$server_name$request_uri; // przekierowanie całego URL
location / {
try_files $uri $uri/ =404; // Standardowa linijka z nginxa która obsługuje każde zapytanie
}
}
Trzeci wirtualny host jest najbardziej skomplikowany. Na szczęście tutaj możemy skopiować go z pliku załączonego do samego Magento 2. Nie będą kopiował całej konfiguracji, bo ta działa tak jak plik .htaccess dostarczony też do Magento 2. To co jest istotne dla nas to linijki poniżej
server {
listen 127.0.0.1:8080 default_server; // port, który jest ukryty przed światem. Na nim słucha nasza strona bez cache
location /nginx_status { // sekcja pozwalająca robić nam statystyki
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
set $MAGE_ROOT /var/www/html; // zmienna wskazująca katalog główny strony
root $MAGE_ROOT/pub; // Odpowiednik DocumentRoot w apache.
Testowanie
W przypadku Magento
2 katalog, gdzie znajdują się pliki php, jest są katalogiem
głównym dla strony. W naszym przypadku pliki Magento 2 wrzucamy do
katalogu /var/www/html
,
a NGINX, jako katalog główny
strony, widzi /var/www/html/pub
.
Ciekawym rozwiązaniem jest podgląd strony bez Varnisha (co jest przydatne przy rozwiązywaniu problemów z cache). Możemy wtedy zamiast linijek:
listen 127.0.0.1:8080 default_server;
Użyć
listen 8080 default_server;
Wtedy możemy sprawdzić stronę po HTTP na porcie 8080 – ruch wówczas nie będzie przechodził przez Varnish. Najlepiej jednak taki port schować za firewallem tylko dla naszego IP.
Do testów konfiguracji nginx możemy użyć polecenia:
nginx -t
Następnym razem zajmiemy się konfiguracją Varnisha. Na szczęście jest on dużo prostszy do skonfigurowania 🙂