Nginx (wymawiane "engine-x") to potężny, wysokowydajny serwer WWW, który stał się de facto standardem w obsłudze aplikacji internetowych. Ten przewodnik przeprowadzi Cię przez wszystko, co musisz wiedzieć o Nginx, od podstawowych koncepcji do zaawansowanych konfiguracji, ze szczególnym uwzględnieniem aplikacji PHP/Laravel.
📋 Spis treści
- Wprowadzenie
- Czym jest Nginx?
- Podstawowe koncepcje
- Instalacja i podstawowa konfiguracja
- Struktura konfiguracji
- Typowe przypadki użycia
- Optymalizacja wydajności
- Najlepsze praktyki bezpieczeństwa
- Integracja z PHP/Laravel
- Integracja z Dockerem
- Rozwiązywanie problemów
- Podsumowanie
Czym jest Nginx?
Nginx to otwartoźródłowy serwer WWW, który może być również używany jako odwrotne proxy, load balancer i cache HTTP. Został stworzony przez Igora Sysoeva i publicznie wydany w 2004 roku. Nginx jest znany ze swojej wysokiej wydajności, stabilności, bogatego zestawu funkcji, prostej konfiguracji i niskiego zużycia zasobów.
Dlaczego wybrać Nginx?
- Wysoka wydajność i niskie zużycie pamięci
- Doskonała obsługa równoczesnych połączeń
- Wbudowane możliwości równoważenia obciążenia
- Silne funkcje bezpieczeństwa
- Rozbudowana dokumentacja i wsparcie społeczności
Podstawowe koncepcje
Kluczowe komponenty
- Dyrektywy: Polecenia konfiguracyjne kontrolujące zachowanie Nginx
- Konteksty: Bloki grupujące powiązane dyrektywy
- Zdarzenia: Jak Nginx obsługuje połączenia
- HTTP: Konfiguracja serwera WWW
- Server: Konfiguracja hosta wirtualnego
- Location: Dopasowywanie i obsługa URL
Podstawowa struktura konfiguracji
# Kontekst główny
user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Kontekst zdarzeń
events {
worker_connections 1024;
}
# Kontekst HTTP
http {
# Podstawowe ustawienia
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Typy MIME
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logowanie
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Kontekst serwera
server {
listen 80;
server_name example.com;
root /var/www/html;
# Kontekst lokalizacji
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
}
Instalacja i podstawowa konfiguracja
Instalacja na Ubuntu/Debian
# Aktualizacja listy pakietów
sudo apt update
# Instalacja Nginx
sudo apt install nginx
# Uruchomienie Nginx
sudo systemctl start nginx
# Włączenie automatycznego uruchamiania Nginx przy starcie
sudo systemctl enable nginx
# Sprawdzenie statusu
sudo systemctl status nginx
Podstawowa struktura plików konfiguracyjnych
/etc/nginx/
├── nginx.conf # Główny plik konfiguracyjny
├── sites-available/ # Dostępne konfiguracje stron
├── sites-enabled/ # Włączone konfiguracje stron
├── conf.d/ # Dodatkowe pliki konfiguracyjne
└── snippets/ # Wykorzystywane fragmenty konfiguracji
Struktura konfiguracji
Główna konfiguracja (nginx.conf)
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
http {
# Podstawowe ustawienia
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Typy MIME
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logowanie
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Ustawienia Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Konfiguracje hostów wirtualnych
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Konfiguracja hosta wirtualnego
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html;
# Nagłówki bezpieczeństwa
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
# Logowanie
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Typowe przypadki użycia
1. Obsługa plików statycznych
location /static/ {
alias /var/www/static/;
expires 30d;
add_header Cache-Control "public, no-transform";
}
2. Równoważenie obciążenia
upstream backend {
server backend1.example.com:8080;
server backend2.example.com:8080;
server backend3.example.com:8080;
}
server {
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. Konfiguracja SSL/TLS
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000" always;
}
Optymalizacja wydajności
1. Procesy robocze i połączenia
worker_processes auto; # Automatycznie ustawiane na podstawie rdzeni CPU
worker_rlimit_nofile 65535; # Zwiększenie limitu deskryptorów plików
events {
worker_connections 1024;
multi_accept on;
use epoll; # Wydajna metoda przetwarzania zdarzeń
}
2. Buforowanie
# Buforowanie FastCGI
fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
location ~ \.php$ {
fastcgi_cache my_cache;
fastcgi_cache_valid 200 60m;
fastcgi_cache_use_stale error timeout http_500 http_503;
fastcgi_cache_key "$request_method$request_uri";
}
3. Kompresja Gzip
Kompresja Gzip zmniejsza rozmiar plików wysyłanych z serwera do klienta, co może znacząco skrócić czas ładowania strony internetowej. Jest to szczególnie korzystne dla użytkowników z wolniejszym połączeniem internetowym. Włączając gzip, możesz poprawić wydajność i szybkość swojej strony internetowej.
Nagłówki bezpieczeństwa
-
X-Frame-Options: Ten nagłówek pomaga zapobiegać atakom clickjacking, kontrolując czy przeglądarka powinna być uprawniona do renderowania strony w
<frame>,<iframe>,<embed>lub<object>. Ustawienie go naSAMEORIGINpozwala na wyświetlanie strony tylko w tej samej domenie co sama strona. -
X-Content-Type-Options: Ten nagłówek zapobiega przeglądarkom przed MIME-sniffing odpowiedzi z deklarowanego typu zawartości. Ustawienie go na
nosniffpomaga zapobiegać atakom opartym na pomyłce typu MIME. -
X-XSS-Protection: Ten nagłówek włącza filtr Cross-Site Scripting (XSS) wbudowany w większość nowoczesnych przeglądarek. Ustawienie go na
1; mode=blockzablokuje stronę, jeśli zostanie wykryty atak XSS. -
Referrer-Policy: Ten nagłówek kontroluje, ile informacji o referrer powinno być dołączone do żądań. Ustawienie go na
strict-origin-when-cross-originzapewnia dobrą równowagę między bezpieczeństwem a użytecznością.
Timeouty ciała i nagłówków klienta
Te ustawienia kontrolują, jak długo serwer będzie czekał na wysłanie przez klienta ciała i nagłówków żądania. Ustawiając odpowiednie timeouty, możesz zapobiec powolnym klientom przed trzymaniem połączeń otwartych w nieskończoność, co może pomóc w ochronie przed pewnymi typami ataków denial-of-service (DoS).
Najlepsze praktyki bezpieczeństwa
1. Podstawowe nagłówki bezpieczeństwa
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
2. Ograniczanie szybkości
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /login {
limit_req zone=one burst=5 nodelay;
proxy_pass http://backend;
}
}
3. Konfiguracja SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
Integracja z PHP/Laravel
1. Standardowa instalacja (bez Dockera)
# /etc/nginx/sites-available/laravel
server {
listen 80;
server_name laravel.example.com;
root /var/www/laravel/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
2. Integracja z Dockerem
# docker-compose.yml
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/ssl:/etc/nginx/ssl
depends_on:
- php
- mysql
php:
image: php:8.3-fpm
depends_on:
- mysql
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: app
# docker/nginx/conf.d/default.conf
server {
listen 80;
server_name _;
root /var/www/html/public;
index index.php index.html;
charset utf-8;
client_max_body_size 100M;
client_body_buffer_size 100M;
client_body_timeout 60s;
client_header_timeout 60s;
send_timeout 60s;
# Kompresja Gzip
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript;
gzip_disable "MSIE [1-6]\.";
# Nagłówki bezpieczeństwa
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: *.example.com wss://*.example.com; img-src 'self' data: https:; font-src 'self' data: https:;";
# Logi
access_log /var/www/html/storage/logs/nginx_access.log;
error_log /var/www/html/storage/logs/nginx_error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 600;
fastcgi_send_timeout 600;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Rozwiązywanie problemów
Typowe problemy i rozwiązania
-
502 Bad Gateway
- Sprawdź czy PHP-FPM działa
- Zweryfikuj czy plik socket istnieje
- Sprawdź uprawnienia
-
404 Not Found
- Zweryfikuj ścieżkę katalogu głównego
- Sprawdź uprawnienia plików
- Upewnij się, że dyrektywa try_files jest poprawna
-
Problemy z uprawnieniami
# Napraw uprawnienia dla Laravel sudo chown -R www-data:www-data /var/www/laravel sudo chmod -R 755 /var/www/laravel sudo chmod -R 775 /var/www/laravel/storage sudo chmod -R 775 /var/www/laravel/bootstrap/cache
Przydatne komendy
# Testowanie konfiguracji
nginx -t
# Przeładowanie konfiguracji
sudo systemctl reload nginx
# Sprawdzenie logów błędów
tail -f /var/log/nginx/error.log
# Sprawdzenie logów dostępu
tail -f /var/log/nginx/access.log
Podsumowanie
Nginx to potężny i elastyczny serwer WWW, który może obsługiwać różne przypadki użycia, od serwowania plików statycznych po złożone scenariusze równoważenia obciążenia. Postępując zgodnie z najlepszymi praktykami opisanymi w tym przewodniku, możesz stworzyć bezpieczną, wydajną i łatwą w utrzymaniu konfigurację serwera WWW dla swoich aplikacji PHP/Laravel.
Pamiętaj, aby:
- Zawsze testować konfiguracje przed ich zastosowaniem
- Mieć na uwadze bezpieczeństwo
- Monitorować wydajność
- Regularnie aktualizować Nginx i jego moduły
- Tworzyć kopie zapasowe konfiguracji
Dodatkowe zasoby
Podstawowa autoryzacja
Podstawowa autoryzacja może być używana do ograniczenia dostępu do określonych części Twojej strony internetowej. Aby skonfigurować podstawową autoryzację w Nginx, wykonaj następujące kroki:
-
Utwórz plik hasła
- Użyj komendy
htpasswddo utworzenia pliku hasła:sudo htpasswd -c /etc/nginx/.htpasswd username - Zostaniesz poproszony o wprowadzenie hasła dla użytkownika.
- Użyj komendy
-
Zaktualizuj konfigurację Nginx
- Dodaj następujące linie do bloku serwera w konfiguracji Nginx:
location / { auth_basic "Restricted Content"; auth_basic_user_file /etc/nginx/.htpasswd; try_files $uri $uri/ /index.php?$query_string; }
- Dodaj następujące linie do bloku serwera w konfiguracji Nginx:
-
Przeładuj Nginx
- Po zaktualizowaniu konfiguracji, przeładuj Nginx, aby zastosować zmiany:
sudo systemctl reload nginx
- Po zaktualizowaniu konfiguracji, przeładuj Nginx, aby zastosować zmiany:
Ta konfiguracja poprosi użytkowników o wprowadzenie nazwy użytkownika i hasła podczas dostępu do ograniczonego obszaru.
Instalacja apache2-utils
Aby używać komendy htpasswd do tworzenia plików hasła, musisz zainstalować pakiet apache2-utils. Można to zrobić za pomocą następującej komendy:
sudo apt install apache2-utils
Obsługa .htpasswd w Dockerze
Podczas używania Dockera masz kilka opcji obsługi pliku .htpasswd:
-
Przechowywanie w repozytorium:
- Możesz przechowywać plik
.htpasswdw swoim repozytorium, jeśli nie zawiera wrażliwych informacji lub jeśli używasz zmiennych środowiskowych do bezpiecznego zarządzania danymi uwierzytelniającymi.
- Możesz przechowywać plik
-
Generowanie podczas budowania:
- Alternatywnie, możesz wygenerować plik
.htpasswdpodczas procesu budowania Dockera. Można to zrobić, dodając komendę w Dockerfile do utworzenia pliku za pomocąhtpasswd.
- Alternatywnie, możesz wygenerować plik
-
Użyj Docker Secrets:
- Dla bardziej bezpiecznego podejścia, rozważ użycie Docker secrets do zarządzania wrażliwymi plikami jak
.htpasswd. To trzyma plik poza Twoim repozytorium i zapewnia, że jest dostępny tylko dla kontenerów, które go potrzebują.
- Dla bardziej bezpiecznego podejścia, rozważ użycie Docker secrets do zarządzania wrażliwymi plikami jak
Przykładowa komenda Dockerfile
Aby wygenerować plik .htpasswd podczas budowania, możesz dodać komendę taką jak ta do swojego Dockerfile:
RUN apt-get update && apt-get install -y apache2-utils \
&& htpasswd -bc /etc/nginx/.htpasswd username password
Zastąp username i password swoimi pożądanymi danymi uwierzytelniającymi. Ta komenda instaluje apache2-utils i tworzy plik .htpasswd z określonymi danymi uwierzytelniającymi użytkownika.
Śledź mnie na LinkedIn, aby otrzymywać więcej wskazówek o Laravel i DevOps!