🚀 Kompletny przewodnik po Nginx: od podstaw do zaawansowanej konfiguracji

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

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

  1. Dyrektywy: Polecenia konfiguracyjne kontrolujące zachowanie Nginx
  2. Konteksty: Bloki grupujące powiązane dyrektywy
  3. Zdarzenia: Jak Nginx obsługuje połączenia
  4. HTTP: Konfiguracja serwera WWW
  5. Server: Konfiguracja hosta wirtualnego
  6. 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

  1. 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 na SAMEORIGIN pozwala na wyświetlanie strony tylko w tej samej domenie co sama strona.

  2. X-Content-Type-Options: Ten nagłówek zapobiega przeglądarkom przed MIME-sniffing odpowiedzi z deklarowanego typu zawartości. Ustawienie go na nosniff pomaga zapobiegać atakom opartym na pomyłce typu MIME.

  3. 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=block zablokuje stronę, jeśli zostanie wykryty atak XSS.

  4. Referrer-Policy: Ten nagłówek kontroluje, ile informacji o referrer powinno być dołączone do żądań. Ustawienie go na strict-origin-when-cross-origin zapewnia 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

  1. 502 Bad Gateway

    • Sprawdź czy PHP-FPM działa
    • Zweryfikuj czy plik socket istnieje
    • Sprawdź uprawnienia
  2. 404 Not Found

    • Zweryfikuj ścieżkę katalogu głównego
    • Sprawdź uprawnienia plików
    • Upewnij się, że dyrektywa try_files jest poprawna
  3. 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:

  1. Utwórz plik hasła

    • Użyj komendy htpasswd do utworzenia pliku hasła:
      sudo htpasswd -c /etc/nginx/.htpasswd username
      
    • Zostaniesz poproszony o wprowadzenie hasła dla użytkownika.
  2. 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;
      }
      
  3. Przeładuj Nginx

    • Po zaktualizowaniu konfiguracji, przeładuj Nginx, aby zastosować zmiany:
      sudo systemctl reload nginx
      

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:

  1. Przechowywanie w repozytorium:

    • Możesz przechowywać plik .htpasswd w swoim repozytorium, jeśli nie zawiera wrażliwych informacji lub jeśli używasz zmiennych środowiskowych do bezpiecznego zarządzania danymi uwierzytelniającymi.
  2. Generowanie podczas budowania:

    • Alternatywnie, możesz wygenerować plik .htpasswd podczas procesu budowania Dockera. Można to zrobić, dodając komendę w Dockerfile do utworzenia pliku za pomocą htpasswd.
  3. 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ą.

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!

Komentarze (0)
Zostaw komentarz

© 2026 Wszelkie prawa zastrzeżone.