Reverse proxy w świecie self hosted – po co to wszystko?
Czym jest reverse proxy w praktyce domowego serwera
Reverse proxy to serwer pośredniczący, który stoi przed Twoimi aplikacjami self hosted i przyjmuje ruch z Internetu (lub z sieci lokalnej), a następnie przekazuje go dalej do właściwego backendu – kontenera, usługi, aplikacji na innym porcie. Dla klienta (przeglądarki, aplikacji mobilnej, innego serwera) reverse proxy wygląda jak docelowy serwer, ale w środku to tylko „dyspozytor” kierujący żądania w odpowiednie miejsca.
W środowisku self hosted typowy scenariusz wygląda tak: na jednym serwerze (lub VPS, czy nawet Raspberry Pi) działa jednocześnie wiele usług – np. Nextcloud, Jellyfin, Gitea, Home Assistant, panel do routera, kilka mniejszych mikroserwisów. Każda nasłuchuje na innym porcie, często tylko na localhost lub w sieci Docker. Reverse proxy umożliwia:
- udostępnienie wszystkich tych usług pod jednym adresem IP,
- rozróżnienie ich po domenie lub ścieżce URL (np.
cloud.mojadomena.pl,git.mojadomena.pl), - terminowanie TLS – czyli obsługę HTTPS i certyfikatów w jednym miejscu,
- wprowadzenie centralnych zasad bezpieczeństwa, logowania i kompresji.
Bez reverse proxy każda usługa wymagałaby osobnego portu wystawionego na świat, osobnego zarządzania certyfikatami i trudnego do zapamiętania adresu. Reverse proxy porządkuje ten chaos i działa jak brama do całej infrastruktury self hosted.
Reverse proxy a klasyczny serwer HTTP
Klasyczny serwer HTTP (np. Apache w trybie statycznym) często jest bezpośrednim gospodarzem plików i aplikacji. Reverse proxy zwykle nie przechowuje logiki aplikacyjnej – tylko pośredniczy. Jego rola to:
- parsowanie nagłówków HTTP,
- wybór backendu na podstawie hosta, ścieżki lub innych kryteriów,
- przepisywanie nagłówków (np.
X-Forwarded-For,X-Forwarded-Proto), - buforowanie odpowiedzi (w niektórych konfiguracjach),
- opcjonalna kompresja gzip/brotli.
Nginx i Traefik mogą być jednocześnie reverse proxy oraz serwerem statycznych plików (np. plików frontendu SPA), ale w świecie self hosted pełnią głównie rolę bramy do wielu usług, często działających w kontenerach Docker lub w klastrach Kubernetes.
Najczęstsze zastosowania reverse proxy w self hostingu
W domowych lub małych serwerowniach najbardziej typowe scenariusze użycia reverse proxy to:
- Wystawianie wielu aplikacji za jednym adresem IP – np. VPS z jednym publicznym adresem, za którym działają dziesiątki usług.
- Ukrywanie portów i topologii sieci – świat widzi tylko port 80/443, a wewnątrz można dowolnie zmieniać porty i hosty backendów.
- Centralne HTTPS – jeden mechanizm Let’s Encrypt / certbot / ACME, zamiast instalowania certyfikatów w każdej aplikacji.
- Autoryzacja przed aplikacjami – reverse proxy może chronić serwisy za pomocą SSO, Basic Auth, OAuth2 Proxy itp.
- Segmentacja dostępu – różne usługi dostępne tylko z LAN, inne z Internetu, niektóre tylko z VPN.
W praktyce reverse proxy staje się centralnym elementem infrastruktury – od jego konfiguracji zależy, czy dostęp do usług jest wygodny, bezpieczny i łatwy w utrzymaniu.
Jak działa reverse proxy od środka – przepływ żądania
Ścieżka żądania HTTP krok po kroku
Dobrze zrozumieć, co się dzieje z momentem wpisania https://cloud.mojadomena.pl do przeglądarki, aż do odpowiedzi z Twojego Nextclouda:
- Rozwiązanie DNS – domena
cloud.mojadomena.plwskazuje publiczny adres IP Twojego serwera. - Połączenie TCP/TLS – przeglądarka łączy się z portem 443; reverse proxy (Nginx lub Traefik) przyjmuje połączenie i wykonuje handshake TLS.
- Odczyt nagłówków HTTP – reverse proxy analizuje nagłówek
Host, metodę, ścieżkę URL i inne parametry. - Dobór reguły routingu – na podstawie konfiguracji wybierany jest odpowiedni upstream / backend (np. kontener
nextcloudna porcie 8080). - Tworzenie połączenia z backendem – reverse proxy otwiera (lub wykorzystuje istniejące) połączenie do usługi backendowej w sieci lokalnej lub Docker.
- Przekazanie żądania – żądanie jest wysyłane do backendu, często z modyfikacją nagłówków (np.
X-Forwarded-Forz IP klienta). - Odpowiedź backendu – aplikacja odsyła odpowiedź HTTP do reverse proxy.
- Opcjonalna obróbka – reverse proxy może wykonać kompresję, dodać nagłówki bezpieczeństwa, zbuforować odpowiedź.
- Zwrot odpowiedzi klientowi – użytkownik widzi stronę, nawet nie wiedząc, że po drodze działało kilka warstw.
Ten mechanizm jest podobny w Nginxie i Traefiku, choć sposób opisywania reguł i konfiguracji różni się dość znacząco.
Routing po domenie i ścieżce
Najprostszy i najczęściej używany sposób routingu w reverse proxy to rozróżnianie żądań po:
- domenie (vhost) – np.
cloud.mojadomena.pl,media.mojadomena.pl,git.mojadomena.pl, - ścieżce URL – np.
mojadomena.pl/cloud,mojadomena.pl/git,mojadomena.pl/monitoring.
Routing po domenie jest czytelniejszy i rzadziej sprawia problemy z aplikacjami, które generują absolutne linki. Routing po ścieżce bywa praktyczny przy jednej domenie i wielu prostych usługach, ale wymaga starannego przepisywania ścieżek (zwłaszcza dla frontendów SPA i aplikacji, które oczekują, że działają w /).
Reverse proxy może też brać pod uwagę inne parametry – nagłówki, metodę HTTP, adres IP klienta – ale w self hostingu to scenariusz bardziej niszowy, zwykle zarezerwowany dla zaawansowanych instalacji.
Terminowanie TLS i nagłówki X-Forwarded-*
Gdy reverse proxy przyjmuje połączenie HTTPS, mają miejsce dwa istotne mechanizmy:
- Terminowanie TLS – szyfrowanie kończy się na reverse proxy. To tutaj są klucze prywatne i certyfikaty, a dalej do backendu żądania zwykle lecą już „czystym” HTTP w sieci lokalnej (czasem również HTTPS, ale wewnątrz).
- Nagłówki przekazujące kontekst – reverse proxy dodaje nagłówki typu:
X-Forwarded-For– oryginalny adres IP klienta,X-Forwarded-Proto– protokół użyty przez klienta (httplubhttps),X-Real-IP– też często IP klienta (popularne w Nginx + PHP-FPM).
Aplikacje działające za reverse proxy zwykle potrafią korzystać z tych nagłówków, aby poprawnie rozpoznawać adres klienta oraz generować linki https:// zamiast http://. W konfiguracjach self hosted kluczowe jest włączenie opcji „siedzę za reverse proxy” w samych aplikacjach (np. w Nextcloud, Gitea, Grafana), aby nie myliły się co do adresu zewnętrznego.

Nginx jako reverse proxy – fundamenty konfiguracji
Podstawowa struktura konfiguracji Nginx
Nginx ma konfigurację opartą na blokach: główny blok http, w nim bloki server (wirtualne hosty), a w nich bloki location (dopasowanie ścieżek). Minimalny przykład prostego reverse proxy dla jednej aplikacji wygląda tak:
http {
upstream nextcloud_backend {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name cloud.mojadomena.pl;
location / {
proxy_pass http://nextcloud_backend;
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;
}
}
}
Blok upstream definiuje backend (pojedynczy serwer lub pulę serwerów). Blok server opisuje, pod jaką domeną i portem dostępna jest usługa. W location / odbywa się kluczowe proxy_pass i ustawianie nagłówków dla aplikacji.
Konfiguracja virtual hostów i proxy_pass
Dla wielu usług self hosted typowe jest stworzenie osobnego pliku konfiguracji Nginx dla każdej domeny, np. w katalogu /etc/nginx/sites-available/. Przykładowo:
server {
listen 80;
server_name git.mojadomena.pl;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
Jeśli aplikacja działa w Dockerze i nasłuchuje na porcie kontenera (np. gitea:3000 w sieci dockerowej), można użyć nazwy hosta kontenera jako backendu, jeśli Nginx jest w tej samej sieci Docker:
upstream gitea_backend {
server gitea:3000;
}
W takim scenariuszu Nginx też działa w kontenerze podpiętym do tej samej sieci. W praktyce w świecie self hosted są dwa popularne podejścia: Nginx na hoście + aplikacje w Docker (proxy na host: 127.0.0.1:PORT) lub Nginx w Docker, a wszystko połączone przez sieci Docker.
Przekazywanie nagłówków i poprawne adresy klienta
Bez poprawnie ustawionych nagłówków aplikacja backendowa będzie widzieć IP reverse proxy zamiast IP użytkownika, a także nie będzie wiedzieć, że zewnętrznie używany jest HTTPS. Standardowy zestaw dyrektyw w Nginx to:
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;
W konfiguracjach bardziej zaawansowanych dołącza się też nagłówki X-Forwarded-Host, X-Forwarded-Port, albo wykorzystuje gotowy blok include proxy_params; dostępny w wielu dystrybucjach, który zawiera sensowny zestaw domyślny. W self hostingu wygodnie jest stworzyć własny plik proxy_common.conf i dołączać go w wielu vhostach, aby nie powielać konfiguracji.
Nginx i HTTPS dla self hosted – Let’s Encrypt i bezpieczeństwo
Integracja Nginx z Let’s Encrypt (certbot, acme.sh)
Najczęstszy sposób na uzyskanie certyfikatów HTTPS dla usług self hosted to Let’s Encrypt. Z Nginx można go zintegrować na kilka sposobów:
- certbot + wtyczka nginx – automatyczna edycja konfiguracji Nginx przez certbota, prostsza dla początkujących, ale mniej przewidywalna przy złożonych setupach.
- certbot + tryb webroot – ręczna konfiguracja lokalizacji
/.well-known/acme-challenge/, certbot tylko zapisuje pliki i odnawia certyfikaty. - acme.sh lub inne skrypty ACME – elastyczne narzędzia, często wygodniejsze przy DNS-01, wildcardach i bardziej zaawansowanych scenariuszach.
Przykład prostego vhosta z HTTP, który służy do walidacji HTTP-01 i przekierowuje ruch na HTTPS:
server {
listen 80;
server_name cloud.mojadomena.pl;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}
Po wydaniu certyfikatu powstaje dodatkowy blok server nasłuchujący na 443 z dyrektywą ssl_certificate i konfiguracją backendu. Odnawianie certyfikatów można zautomatyzować w cronie lub systemd timers, co jest szczególnie ważne przy wielu usługach i domenach.
Konfiguracja serwera HTTPS w Nginx
Typowy, uproszczony blok HTTPS w Nginx wygląda tak:
server {
listen 443 ssl http2;
server_name cloud.mojadomena.pl;
ssl_certificate /etc/letsencrypt/live/cloud.mojadomena.pl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cloud.mojadomena.pl/privkey.pem;
# opcjonalne, mocniejsze ustawienia TLS
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/proxy_common.conf;
}
}
W konfiguracji dla wielu usług część parametrów TLS lepiej wynieść do bloku http lub do osobnego pliku ssl_params.conf włączanego w każdym serwerze.
Reverse proxy a cache, kompresja i limity
Reverse proxy może nie tylko przekazywać żądania dalej, ale też optymalizować ruch. W Nginx często łączy się kilka mechanizmów:
- cache odpowiedzi HTTP (statyczne pliki, zasoby API z krótkim TTL),
- kompresję gzip/brotli dla zasobów tekstowych,
- limity rozmiaru żądania (np. uploadów) i limity szybkości (rate limiting).
Przy typowym self hostingu wystarczy prosty cache na statyczne pliki i rozsądny limit uploadu, np. dla Nextclouda:
http {
# katalog na cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m
inactive=60m use_temp_path=off;
server {
listen 443 ssl http2;
server_name cloud.mojadomena.pl;
# ...
# cache tylko na statyczne pliki
location ~* .(css|js|png|jpg|jpeg|gif|svg|ico|webp|avif)$ {
proxy_pass http://127.0.0.1:8080;
proxy_cache static_cache;
proxy_cache_valid 200 301 302 60m;
add_header X-Cache-Status $upstream_cache_status;
include /etc/nginx/proxy_common.conf;
}
# cała reszta bez cache
location / {
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/proxy_common.conf;
}
# limit rozmiaru uploadu
client_max_body_size 2G;
}
}Do tego można dołożyć globalną kompresję:
http {
gzip on;
gzip_types text/css application/javascript application/json application/xml;
gzip_min_length 1024;
gzip_vary on;
}Obsługa WebSocketów i HTTP/2 w Nginx
Coraz więcej usług self hosted korzysta z WebSocketów (np. interfejsy webowe, narzędzia do streamingu logów, panele administracyjne). Reverse proxy musi poprawnie przekazać upgrade połączenia:
location /ws/ {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
include /etc/nginx/proxy_common.conf;
}
Dla HTTP/2 wystarczy dopisać http2 w dyrektywie listen, co już było użyte w przykładach HTTPS. Backend nadal może działać na zwykłym HTTP/1.1 – to reverse proxy realizuje terminowanie HTTP/2.
Reverse proxy jako punkt centralnego logowania
Ponieważ cały ruch przechodzi przez reverse proxy, to ono jest naturalnym miejscem na logi dostępu i błędów. W Nginx można stworzyć wspólny format logów dla wszystkich vhostów:
http {
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server {
# ...
}
}Przy wielu usługach przydaje się oddzielny log per domena:
server {
listen 443 ssl http2;
server_name git.mojadomena.pl;
access_log /var/log/nginx/git_access.log main;
error_log /var/log/nginx/git_error.log warn;
# ...
}Dzięki temu łatwiej przejrzeć, kto logował się do konkretnego serwisu, bez mieszania wpisów z innych usług.

Traefik jako reverse proxy w środowiskach kontenerowych
Filozofia Traefika w porównaniu z Nginx
Nginx opiera się głównie na statycznych plikach konfiguracyjnych. Traefik został zaprojektowany z myślą o środowisku dynamicznym – Docker, Kubernetes, usługi powstające i znikające automatycznie. Zamiast edytować pliki i przeładowywać proces, Traefik:
- nasłuchuje na API Dockera / Kubernetesa,
- odkrywa kontenery na podstawie etykiet (labels),
- sam generuje routing i reguły,
- automatycznie wystawia i odnawia certyfikaty Let’s Encrypt.
W praktyce oznacza to mniejszą liczbę ręcznie tworzonych plików i większy porządek przy dużej liczbie kontenerów. Z drugiej strony konfiguracja Traefika bywa mniej intuicyjna dla osób przyzwyczajonych do klasycznych vhostów.
Podstawowa architektura Traefika: entrypoints, routers, services, middlewares
Traefik dzieli konfigurację reverse proxy na kilka pojęć:
- entrypoints – porty/wejścia (np.
:80,:443), - routers – reguły dopasowania żądań (domena, ścieżka, metoda HTTP),
- services – backendy (adresy kontenerów / serwerów),
- middlewares – filtry po drodze (redirect, auth, nagłówki bezpieczeństwa, strippath itd.).
W konfiguracji statycznej definiuje się entrypointy i integrację z ACME, a reszta może być tworzona dynamicznie z etykiet Dockera.
Przykładowa konfiguracja Traefika w docker-compose
Przy self hostingu Traefik najczęściej uruchamia się jako kontener reverse-proxy w sieci współdzielonej z innymi usługami. Minimalny przykład:
version: "3.8"
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.httpchallenge=true"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.le.acme.email=admin@mojadomena.pl"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
networks:
- proxy
gitea:
image: gitea/gitea:latest
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`git.mojadomena.pl`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls.certresolver=le"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
networks:
proxy:
external: false
Traefik automatycznie zauważy kontener gitea i wystawi go pod wskazaną domeną z HTTPS. Nie ma tu osobnych plików konfiguracyjnych per domena – wszystko definiują etykiety.
Dynamiczne routowanie po domenie i ścieżce w Traefiku
Reguły routerów Traefika wykorzystują prosty język wyrażeń. Kilka typowych przykładów:
Host(`cloud.mojadomena.pl`)– dopasowanie po domenie,PathPrefix(`/grafana`)– dopasowanie po prefiksie ścieżki,Host(`monitor.mojadomena.pl`) && PathPrefix(`/api`)– połączenie warunków.
Jeśli kilka usług ma działać na jednej domenie pod różnymi ścieżkami, można skonfigurować różne routery wskazujące na inne backendy. Przykład z Grafaną i Prometheusem pod wspólną domeną:
labels:
- "traefik.enable=true"
# Grafana pod /grafana
- "traefik.http.routers.grafana.rule=Host(`monitor.mojadomena.pl`) && PathPrefix(`/grafana`)"
- "traefik.http.routers.grafana.entrypoints=websecure"
- "traefik.http.routers.grafana.tls.certresolver=le"
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
- "traefik.http.middlewares.grafana-stripprefix.stripprefix.prefixes=/grafana"
- "traefik.http.routers.grafana.middlewares=grafana-stripprefix"
# Prometheus pod /prometheus
- "traefik.http.routers.prom.rule=Host(`monitor.mojadomena.pl`) && PathPrefix(`/prometheus`)"
- "traefik.http.routers.prom.entrypoints=websecure"
- "traefik.http.routers.prom.tls.certresolver=le"
- "traefik.http.services.prom.loadbalancer.server.port=9090"
- "traefik.http.middlewares.prom-stripprefix.stripprefix.prefixes=/prometheus"
- "traefik.http.routers.prom.middlewares=prom-stripprefix"
Middleware StripPrefix usuwa fragment ścieżki, dzięki czemu backend uważa, że działa w /, choć z perspektywy użytkownika widoczny jest np. /grafana.
Traefik i automatyczne certyfikaty Let’s Encrypt
Traefik ma wbudowaną obsługę ACME, więc nie trzeba uruchamiać osobnego certbota. Po skonfigurowaniu certificatesresolvers wystarczy dodać do routera:
traefik.http.routers.cloud.entrypoints=websecure
traefik.http.routers.cloud.tls.certresolver=le
oraz odpowiednią regułę Host(). Traefik sam:
- wystawi challenge HTTP-01 na porcie 80 (entrypoint
web), - uzyska certyfikat,
- zapisze go w pliku
acme.json, - odnowi certyfikat przed wygaśnięciem.
Przy wielu domenach nie trzeba dopisywać nowych wpisów w cronie ani odświeżać serwera – routery z nowymi regułami po prostu pojawiają się po uruchomieniu kontenerów.
Traefik jako reverse proxy dla usług spoza Dockera
Choć Traefik kojarzy się z Dockerem, potrafi także proxować usługi działające „na hoście” lub na innych serwerach. Służy do tego tzw. file provider (dodatkowy plik YAML/TOML) albo provider http. Przykład prostego pliku dynamicznego dynamic.yml dla usługi na 127.0.0.1:8080:
http:
routers:
cloud:
rule: "Host(`cloud.mojadomena.pl`)"
entryPoints:
- websecure
tls:
certResolver: le
service: cloud_svc
services:
cloud_svc:
loadBalancer:
servers:
- url: "http://127.0.0.1:8080"W części statycznej Traefika wystarczy włączyć tego providera:
--providers.file.filename=/etc/traefik/dynamic.ymlTakie połączenie przydaje się, gdy na jednym serwerze współistnieją aplikacje dockerowe i kilka „gołych” usług, np. stary panel WWW albo serwer mediów bez Dockera.
Nagłówki X-Forwarded-* i adres klienta w Traefiku
Traefik automatycznie ustawia standardowe nagłówki X-Forwarded-* dla backendów:
X-Forwarded-For– adres klienta,X-Forwarded-Proto– protokół zewnętrzny,X-Forwarded-Host– domena, pod którą przyszło żądanie.
Jeśli aplikacja dodatkowo chroni się przed spoofingiem nagłówków, czasem trzeba wskazać reverse proxy jako zaufane (np. w konfiguracji Symfony, Django, Nextclouda). Sytuacja jest analogiczna jak przy Nginx – różni się tylko to, że tu nie ma ręcznego konfigurowania proxy_set_header.
Bezpieczeństwo: nagłówki HSTS, redirect HTTP→HTTPS, rate limiting
Nginx i Traefik mogą wymusić korzystanie z HTTPS i dodać nagłówki bezpieczeństwa. W Nginx typowy blok dla przekierowania HTTP:
server {
listen 80;
server_name cloud.mojadomena.pl;
return 301 https://$host$request_uri;
}Dla HSTS w Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;W Traefiku takie nagłówki ustawia się jako middleware:
labels:
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.routers.cloud.middlewares=secure-headers"
Jeśli usługa jest intensywnie atakowana (np. panel logowania), można dołożyć limitowanie żądań – w Nginx przez limit_req_zone, w Traefiku przez middleware rateLimit. Umiarkowane limity wystarczą, by odciążyć backend przy prostych atakach brute force.
Gdzie Nginx, gdzie Traefik – praktyczne scenariusze self hosted
Prosty serwer VPS z kilkoma usługami
Przy klasycznym scenariuszu: jeden VPS, kilka usług (Nextcloud, Gitea, Photoprism, Grafana) i głównie ruch HTTP(S), Nginx wciąż jest wygodnym wyborem:
- konfiguracja czytelna w plikach,
- łatwe przeniesienie na inny serwer (skopiowanie
/etc/nginx), - dobra dokumentacja aplikacji pod Nginx (często gotowe snippet-y).
Jeśli część usług jest w Dockerze, a część na hoście, Nginx może działać na hoście i proxować do portów Dockera (127.0.0.1:PORT) i usług lokalnych. To najprostsza architektura dla osoby, która chce mieć pełną kontrolę nad każdym vhostem.
Większa instalacja z wieloma kontenerami i automatyzacją
Środowisko z orkiestracją (Docker Swarm, Kubernetes, Nomad)
Przy wielu hostach i klastrze kontenerów role Nginxa i Traefika rozjeżdżają się mocniej. Nginx zwykle pełni wtedy funkcję klasycznego reverse proxy / ingressu, konfigurowanego z zewnątrz (pliki, ConfigMapy), natomiast Traefik staje się elementem bardziej „świadomym” platformy – czyta metadane z API Dockera, Swarma czy Kubernetesa i sam buduje konfigurację.
Przykładowy układ przy Swarmie:
- Traefik działa jako stack
reverse-proxyw trybie globalnym (po jednym tasku na nodzie), - poszczególne usługi definiowane są jako kolejne stacki z labelkami Traefika,
- certyfikaty Let’s Encrypt są wspólne dla całego klastra (współdzielony wolumen z
acme.json).
W Kubernetesie Traefik występuje jako Ingress Controller. Zamiast etykiet Dockera używa się CRD Traefika (IngressRoute, Middleware, TraefikService), a routery powstają na podstawie obiektów w klastrze. To rozwiązanie pasuje do bardziej rozrośniętych instalacji, gdzie kolejne aplikacje są wdrażane przez CI/CD, a nie ręcznie na jednym VPS-ie.
Nginx także ma swoje wersje „kubernetesowe” (Nginx Ingress Controller) i dobrze sprawdza się w klastrach. Różnica polega na poziomie „magii”: Nginx zwykle wymaga bardziej jawnej konfiguracji (Ingress, ConfigMapy), Traefik mocniej polega na dynamicznych providerach i etykietach.
Hybrid: Nginx jako frontend, Traefik jako router usług
Ciekawy scenariusz to połączenie obu narzędzi. Na brzegu stoi Nginx, który:
- nasłuchuje na 80/443,
- robi wstępny TLS (np. z certyfikatem wildcard),
- dodaje spójne nagłówki bezpieczeństwa i polityki (
Content-Security-Policy,Referrer-Policy,Permissions-Policy), - terminuje ruch do jednego lub kilku Traefików, pracujących w sieciach Dockera.
Nginx ma wtedy kilka prostych bloków:
server {
listen 443 ssl http2;
server_name *.mojadomena.pl;
ssl_certificate /etc/ssl/wildcard.crt;
ssl_certificate_key /etc/ssl/wildcard.key;
# Nagłówki bezpieczeństwa wspólne dla wszystkich subdomen
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header X-Content-Type-Options "nosniff";
location / {
proxy_pass http://127.0.0.1:8080; # Traefik
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Traefik działa wtedy wyłącznie jako router „wewnętrzny”, nie musi wystawiać 80/443 na zewnątrz, a do zarządzania certyfikatami można użyć klasycznego ACME po stronie Nginxa lub ręcznie utrzymywanego certyfikatu wildcard. Przydaje się to np. gdy:
- lista subdomen zmienia się rzadko, ale usług kontenerowych jest dużo,
- trzeba mieć bardzo dopieszczoną konfigurację TLS (np. pod testy PCI),
- Traefik jest okresowo przeładowywany / aktualizowany, a Nginx ma gwarantować stabilny front.
Kiedy zostać przy Nginx, a kiedy wejść w Traefika
Jeżeli konfiguracja reverse proxy polega głównie na:
- kilku–kilkunastu hostach wirtualnych,
- pojedynczym serwerze VPS lub bare-metal,
- mieszance aplikacji w Dockerze i bez Dockera,
Nginx będzie wystarczający, prosty i przewidywalny. Typowy zestaw:
- osobny plik w
/etc/nginx/sites-availablena każdą domenę, - dzielenie konfiguracji na snippet-y (np.
/etc/nginx/snippets/ssl.conf), - certbot lub inny „zewnętrzny” mechanizm ACME.
Traefik sprawdza się lepiej, gdy:
- większość usług jest dockerowa,
- często pojawiają się i znikają nowe kontenery (dev, staging, testy),
- routowanie zależy głównie od etykiet i chcesz, by docker-compose był jedynym źródłem prawdy.
Z praktyki: przy małym, staticznym serwerze domowym Nginx jest mniej ruchomy, czyli mniej kusi, żeby robić „magiczne” konfiguracje. Z kolei przy homelabie z kilkunastoma docker-compose’ami i automatycznym deployem Traefik redukuje liczbę plików konfiguracyjnych i powtarzalnych fragmentów.

Konfiguracje przykładowe: Nginx vs Traefik dla tych samych usług
Nextcloud za Nginx – konfiguracja typowa
Popularne aplikacje, takie jak Nextcloud, mają gotowe, dopracowane konfiguracje pod Nginxa. Dają one m.in.:
- zabezpieczenie plików
.htaccess/.user.ini, - specyficzne reguły
try_files, - buforowanie statycznych zasobów,
- obsługę
well-knowndla WebDav, CalDav, CardDav.
Przykładowy skrócony vhost:
server {
listen 80;
server_name cloud.mojadomena.pl;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name cloud.mojadomena.pl;
root /var/www/nextcloud;
index index.php index.html /index.php$request_uri;
# SSL, HSTS itd. (pominięte dla czytelności)
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location / {
rewrite ^ /index.php$request_uri;
}
location ~ .php(?:$|/) {
fastcgi_split_path_info ^(.+?.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ .(?:css|js|woff2?|svg|gif)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
}
location ~ .(?:htaccess|xml|user.ini)$ {
deny all;
}
}Cała logika jest po stronie Nginxa; backend (PHP-FPM) tylko wykonuje skrypty. Taki układ pasuje wielu administratorom, bo łatwo się go debugguje (logi Nginxa i PHP są rozdzielone).
Nextcloud za Traefikiem – bardziej „aplikacyjnie”
Uruchamiając Nextclouda w Dockerze, można całą „wiedzę” o nim przerzucić do kontenera (np. obraz nextcloud:fpm + kontener z Nginxem wewnątrz sieci Dockera) i wystawić tylko front reverse-proxy.
Jeden wariant:
- wewnętrzny Nginx przy Nextcloudzie (z konfigiem jak wyżej, ale bez SSL),
- Traefik na brzegu, który przekazuje ruch do
nextcloud-nginxpo HTTP.
Przykładowe labelki przy kontenerze z Nginxem Nextclouda:
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud.rule=Host(`cloud.mojadomena.pl`)"
- "traefik.http.routers.nextcloud.entrypoints=websecure"
- "traefik.http.routers.nextcloud.tls.certresolver=le"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"Cały złożony vhost siedzi w środku kontenera aplikacyjnego; Traefik jedynie szyfruje, terminuje TLS i robi routing. Przy aktualizacji Nextclouda z gotowych obrazów często taki embedded Nginx jest już dopięty zgodnie z zaleceniami producenta.
Serwowanie statycznych plików, obrazów i dużych uploadów
Nginx słynie z wydajnego serwowania statycznych zasobów i strumieniowania dużych plików:
- można ustawić
sendfile on;,tcp_nopush on;, - przerzucić logikę obsługi duplikatów ETag / Last-Modified na serwer,
- łatwo włączyć cache na poziomie reverse proxy.
Przykładowa uproszczona konfiguracja statycznego katalogu:
location /media/ {
alias /srv/media/;
autoindex off;
expires 30d;
add_header Cache-Control "public";
}Traefik także radzi sobie z plikami statycznymi, ale nie ma aż tylu „niskopoziomowych” gałek. Tam, gdzie wymagana jest maksymalna kontrola nad buforowaniem, kompresją czy wielkością buforów uploadu, Nginx bywa wygodniejszy.
Diagnostyka i logowanie w reverse proxy
Logi dostępu i błędów – co widać w Nginx, a co w Traefiku
Przy debugowaniu problemów istotne są logi:
- Nginx:
access.logierror.logw formacie ustawianym przezlog_format, - Traefik: logi aplikacyjne oraz osobne logi access log, jeśli są włączone.
W Nginx można dopasować szczegółowo format access logów:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';
access_log /var/log/nginx/access.log main;Dzięki temu w jednym wierszu widać np. czas odpowiedzi backendu i całego żądania. Gdy Nextcloud nagle zwalnia, wystarczy przejrzeć kilka wpisów i porównać czasy.
W Traefiku access logi włącza się flagą statyczną:
--accesslog=true
--accesslog.format=json
Domyślnie logi pojawiają się na stdout kontenera i można je zbierać np. Promtailem lub Filebeatem. W przypadku self hostingu na jednym VPS-ie wystarczy zwykłe docker logs traefik, ale przy większych instalacjach dobrze jest mieć scentralizowany system logowania.
Podgląd routingów i metryk w Traefiku
Traefik ma panel webowy (dashboard), który pokazuje:
- jakie routery są aktywne,
- jakie middlewares są używane,
- na jakie serwisy wskazuje dany router.
Podstawowa konfiguracja panelu:
--api.dashboard=true
--api.insecure=falseNastępnie tworzy się router dla panelu, najlepiej pod nietrywialną domeną z ochroną hasłem:
labels:
- "traefik.http.routers.traefik.rule=Host(`router.mojadomena.pl`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=le"
- "traefik.http.routers.traefik.service=api@internal"
Z poziomu panelu szybko wychodzi na jaw, dlaczego konkretna usługa nie działa – brakujące etykiety, literówki w nazwach entrypointów, konflikt reguł Host(). Przy Nginx jedyną podpowiedzią są zazwyczaj logi i ręczne przejrzenie plików konfiguracyjnych.
Wydajność i zasoby przy self hostingu
Zużycie pamięci i CPU
Na małych maszynach (domowy serwer, tani VPS) liczy się każdy megabajt RAM-u. W przybliżeniu:
- Nginx jest bardzo lekki; pojedyncza instancja z kilkoma vhostami potrafi działać bez problemu na 256–512 MB RAM (oczywiście razem z resztą systemu trzeba liczyć więcej),
- Traefik, napisany w Go, też jest oszczędny, ale dochodzi narzut na funkcje dynamiczne (watchowanie providera Docker, dashboard, ACME).
Przy jednym–dwóch serwisach reverse proxy często nie jest w ogóle wąskim gardłem – obciążają głównie same aplikacje (baza danych, PHP, JVM, Node). W takim przypadku wybór między Nginx a Traefikiem powinien wynikać z wygody zarządzania, a nie z samej wydajności.
Bufory, limity rozmiaru żądania i uploady
Problemy z dużymi uploadami (np. w Nextcloudzie albo własnym serwerze kopii zapasowych) wynikają zwykle z limitów po stronie reverse proxy:
- w Nginx:
client_max_body_size,client_body_buffer_size, - w Traefiku: opcje
maxRequestBodyByteslub limity w backendzie.
Nginx przykładowo:
server {
# ...
client_max_body_size 2G;
}W Traefiku (v3) wielkość requestu ustawia się na poziomie serwisu:
Najczęściej zadawane pytania (FAQ)
Co to jest reverse proxy i po co mi ono w domowym serwerze (self hosted)?
Reverse proxy to serwer pośredniczący, który przyjmuje ruch z Internetu lub sieci lokalnej na standardowych portach (zwykle 80 i 443), a następnie przekazuje go do właściwych usług działających na innych portach lub hostach. Dla użytkownika wygląda jak jeden serwer, ale w środku działa jak „dyspozytor” kierujący żądania do różnych aplikacji.
W self hostingu reverse proxy pozwala wystawić wiele usług (np. Nextcloud, Jellyfin, Gitea, Home Assistant) za jednym adresem IP i jedną bramą. Ułatwia to zarządzanie, zwiększa bezpieczeństwo, upraszcza używanie HTTPS i sprawia, że adresy usług są czytelne i łatwe do zapamiętania.
Jaka jest różnica między reverse proxy a zwykłym serwerem WWW (Apache, Nginx)?
Klasyczny serwer WWW często bezpośrednio serwuje pliki (HTML, CSS, JS) lub uruchamia aplikację (np. PHP, Python) i jest „gospodarzem” logiki aplikacji. Reverse proxy z założenia nie przechowuje logiki biznesowej – jedynie przyjmuje żądania i przekazuje je do innych usług, które tę logikę realizują.
Nginx czy Traefik mogą pełnić obie role, ale w świecie self hosted zazwyczaj używa się ich przede wszystkim jako reverse proxy. Odpowiadają za terminowanie TLS, routowanie po domenach i ścieżkach, modyfikację nagłówków oraz opcjonalne logowanie, cache czy kompresję.
Jak reverse proxy rozróżnia, którą usługę self hosted wybrać (routing po domenie i ścieżce)?
Najczęściej reverse proxy korzysta z dwóch mechanizmów routingu: domeny (nagłówka Host) oraz ścieżki URL. Dzięki temu możesz mieć np. cloud.mojadomena.pl wskazujące na Nextclouda, git.mojadomena.pl na Giteę, a media.mojadomena.pl na Jellyfin.
Możliwe jest też routowanie po ścieżce, np. mojadomena.pl/cloud dla Nextclouda, mojadomena.pl/git dla Gitey. Wymaga to jednak staranniejszej konfiguracji (przepisywanie ścieżek, poprawka linków), ponieważ wiele aplikacji zakłada, że działa w katalogu głównym /.
Jak reverse proxy obsługuje HTTPS i certyfikaty (terminowanie TLS)?
Reverse proxy przyjmuje połączenia HTTPS z przeglądarki i to na nim kończy się szyfrowanie TLS (tzw. terminowanie TLS). Na tym serwerze znajdują się certyfikaty SSL/TLS (np. z Let’s Encrypt) oraz klucze prywatne. Po stronie backendu ruch najczęściej przekazywany jest już zwykłym HTTP w zaufanej sieci lokalnej lub wewnątrz Dockera.
Dzięki temu nie musisz konfigurować certyfikatów osobno w każdej aplikacji. Jeden mechanizm ACME/Let’s Encrypt (np. w Nginxie, Traefiku) może automatycznie odnawiać i podawać certyfikaty wszystkim usługom stojącym za reverse proxy.
Do czego służą nagłówki X-Forwarded-For i X-Forwarded-Proto w konfiguracji reverse proxy?
Nagłówki X-Forwarded-For, X-Forwarded-Proto i często X-Real-IP służą do przekazywania informacji o oryginalnym żądaniu klienta do aplikacji działającej za reverse proxy. Aplikacja „widzi” wtedy prawdziwy adres IP użytkownika oraz to, czy użył on HTTP czy HTTPS.
X-Forwarded-For– zawiera adres IP klienta (i ewentualnie kolejne pośredniki).X-Forwarded-Proto– informuje, czy klient łączył się pohttpczyhttps.X-Real-IP– często używany przez Nginxa do przekazania IP klienta.
W wielu aplikacjach self hosted (np. Nextcloud, Gitea, Grafana) trzeba włączyć opcję pracy „za reverse proxy”, aby poprawnie korzystały z tych nagłówków i generowały właściwe linki HTTPS.
Jak wygląda podstawowa konfiguracja Nginx jako reverse proxy dla jednej aplikacji?
W Nginxie konfiguracja opiera się na blokach http, server i location. W typowym scenariuszu definiujesz blok upstream z backendem (np. 127.0.0.1:8080), a następnie tworzysz blok server z domeną (np. cloud.mojadomena.pl), w którym w location / umieszczasz dyrektywę proxy_pass.
W tym samym miejscu ustawiasz nagłówki przekazujące IP i protokół (Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto). Dla wielu usług self hosted najwygodniej jest tworzyć osobny plik konfiguracyjny Nginx dla każdej domeny i aktywować go poprzez sites-available / sites-enabled.
Czy muszę używać Nginxa, czy mogę zamiast tego wybrać Traefika jako reverse proxy?
Nie musisz ograniczać się do Nginxa – Traefik jest bardzo popularną alternatywą, szczególnie w środowiskach opartych na Dockerze i Kubernetesie. Oba narzędzia pełnią tę samą funkcję (reverse proxy + terminowanie TLS + routing), ale różnią się podejściem do konfiguracji.
Nginx zwykle konfiguruje się statycznymi plikami konfiguracyjnymi, natomiast Traefik oferuje dynamiczne wykrywanie usług (np. z etykiet Dockera), zintegrowane zarządzanie certyfikatami Let’s Encrypt oraz rozbudowane opcje routingu. Wybór zależy od Twojego ekosystemu: dla prostego VPS często wystarczy Nginx, a dla intensywnego użycia Dockera/Kubernetesa Traefik bywa wygodniejszy.
Najważniejsze lekcje
- Reverse proxy działa jako pośrednik przed aplikacjami self hosted – przyjmuje ruch na jednym adresie/porcie i przekazuje go do właściwych usług działających na różnych portach lub hostach.
- Dzięki reverse proxy wiele usług może być udostępnionych pod jednym publicznym adresem IP, rozróżnianych po domenach (vhost) lub ścieżkach URL, co upraszcza dostęp dla użytkownika.
- Reverse proxy centralizuje obsługę HTTPS (TLS), certyfikatów oraz wybranych mechanizmów bezpieczeństwa, logowania i kompresji, odciążając poszczególne aplikacje backendowe.
- W typowym przepływie żądania reverse proxy rozwiązuje DNS, terminuję TLS, analizuje nagłówki HTTP, wybiera backend na podstawie reguł routingu, modyfikuje nagłówki (np. X-Forwarded-For) i opcjonalnie buforuje/kompresuje odpowiedź.
- Routing po domenie jest zwykle prostszy i mniej problematyczny dla aplikacji (szczególnie generujących absolutne linki) niż routing po ścieżce, który często wymaga dodatkowego przepisywania URL-i.
- Reverse proxy pozwala ukryć wewnętrzną topologię i porty usług, segmentować dostęp (LAN/Internet/VPN) oraz dodawać warstwy autoryzacji (SSO, Basic Auth, OAuth2 Proxy) przed aplikacjami.
- Nginx i Traefik pełnią w self hostingu rolę centralnej „bramy” do wielu kontenerów i usług, a ich poprawna konfiguracja jest kluczowa dla wygody, bezpieczeństwa i utrzymania całej infrastruktury.






