Deployment aplikacji Średnio zaawansowany 60 min

Nginx jako reverse proxy

Skonfigurujesz Nginx jako reverse proxy przekazujące żądania HTTP do lokalnego Uvicorna oraz nauczysz się rozróżniać błędy proxy, serwera ASGI i samej aplikacji.

Wróć do listy lekcji

1. Krótka teoria

Reverse proxy przyjmuje żądania klientów i przekazuje je do serwera aplikacji. W tym układzie Nginx nasłuchuje publicznie na porcie 80, a Uvicorn tylko lokalnie na 127.0.0.1:8000. Blok server wybiera port przez listen 80 i domenę przez server_name app.example.com. W location / dyrektywa proxy_pass http://127.0.0.1:8000 wskazuje upstream. Nagłówki przekazywane przez proxy_set_header zachowują nazwę hosta, adres klienta i oryginalny schemat: Host, X-Real-IP, X-Forwarded-For oraz X-Forwarded-Proto. Przed przeładowaniem konfigurację sprawdza się przez nginx -t; dopiero poprawny wynik uzasadnia systemctl reload nginx. Błąd 502 Bad Gateway zwykle oznacza, że Nginx nie może uzyskać poprawnej odpowiedzi od upstreamu. Najpierw trzeba więc wywołać Uvicorna lokalnym curl, potem sprawdzić nasłuch i usługę, a następnie logi Nginxa. Kod 500 zwrócony zarówno lokalnie, jak i przez Nginx częściej wskazuje błąd aplikacji. Ta lekcja świadomie pozostaje przy HTTP; HTTPS jest osobnym etapem.

2. Przykłady komend

/etc/nginx/conf.d/example-app.conf

Przykładowy blok server przekazujący żądania HTTP do lokalnego Uvicorna.

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo nginx -t

Sprawdza składnię i poprawność całej konfiguracji Nginxa.

$ sudo nginx -t
syntax is ok
test is successful
sudo systemctl reload nginx

Wczytuje poprawną konfigurację bez pełnego restartu usługi.

$ sudo systemctl reload nginx
curl -i http://127.0.0.1:8000/

Testuje Uvicorna i aplikację z pominięciem Nginxa.

$ curl -i http://127.0.0.1:8000/
curl -i -H 'Host: app.example.com' http://127.0.0.1/

Testuje lokalny wybór bloku server na podstawie nagłówka Host.

$ curl -i -H 'Host: app.example.com' http://127.0.0.1/
systemctl status nginx

Pokazuje stan procesu Nginxa i ostatnie komunikaty usługi.

$ systemctl status nginx
sudo tail -n 50 /var/log/nginx/error.log

Pokazuje ostatnie błędy Nginxa, w tym problemy z połączeniem do upstreamu.

$ sudo tail -n 50 /var/log/nginx/error.log

3. Zadanie praktyczne

Przygotuj laboratoryjny blok server z listen 80, server_name app.example.com i location /. Ustaw proxy_pass http://127.0.0.1:8000 oraz nagłówki Host, X-Real-IP, X-Forwarded-For i X-Forwarded-Proto. Uruchom lokalną aplikację, wykonaj nginx -t, a po poprawnym teście przeładuj Nginx. Porównaj curl bezpośrednio do portu 8000 z żądaniem przez port 80. Na końcu zatrzymaj laboratoryjnego Uvicorna, zaobserwuj 502 i potwierdź przyczynę w logu.

4. Typowe błędy

  • Przeładowanie Nginxa bez wcześniejszego wykonania nginx -t.
  • Wskazanie w proxy_pass błędnego adresu lub portu Uvicorna.
  • Brak zgodności server_name z domeną wysyłaną w nagłówku Host.
  • Pomijanie nagłówków przekazujących host, adres klienta i schemat.
  • Traktowanie każdego błędu HTTP jako problemu Nginxa.
  • Szukanie przyczyny 502 bez sprawdzenia lokalnej odpowiedzi Uvicorna.
  • Dodawanie konfiguracji HTTPS w etapie przeznaczonym wyłącznie dla HTTP.

5. Podsumowanie

Nginx odbiera publiczne żądania HTTP i przekazuje je do lokalnego Uvicorna przez proxy_pass. server_name wybiera domenę, a proxy_set_header zachowuje ważne informacje o żądaniu. Każdą zmianę należy najpierw sprawdzić przez nginx -t. Diagnostyka idzie warstwami: lokalna aplikacja i Uvicorn, połączenie Nginxa z upstreamem, a dopiero potem publiczna domena.

Flow nauki
  1. Teoria
  2. Przykład
  3. Ćwiczenie
  4. Quiz
  5. Praktyka
  6. Podsumowanie