Ollama za reverse proxy z Caddy lub Nginx w celu strumieniowania HTTPS
HTTPS Ollama bez zakłócania strumieniowania odpowiedzi.
Uruchamianie Ollama za pośrednictwem proxy odwrotnego to najprostszy sposób na uzyskanie HTTPS, opcjonalnej kontroli dostępu oraz przewidywalnego zachowania strumieniowego.
Ten artykuł koncentruje się na konfiguracji Caddy i Nginx jako bramki (ingress) dla API Ollama, a nie na kodzie po stronie klienta.

Jeśli już korzystasz z klientów Python lub Go komunikujących się z Ollama, ten artykuł jest brakującym elementem: bramka i transport dla tego samego API.
Aby dowiedzieć się, jak Ollama wpisuje się w ekosystem obok vLLM, Docker Model Runner, LocalAI oraz kompromisów związanych z hostingiem w chmurze, zobacz Hosting LLM w 2026: Porównanie rozwiązań lokalnych, self-hosted i chmurowych.
Aby zobaczyć przykłady zapytań i kod klienta, zobacz Ściąga Ollama CLI.
Aby uzyskać informacje na temat warstwy UI i obsługi wielu użytkowników, zobacz Przegląd Open WebUI, szybki start i alternatywy.
Aby poznać szerszy kontekst self-hostingu i kontroli nad danymi, zobacz Self-hosting LLM i suwerenność AI.
Aby uzyskać powtarzalną usługę Ollama na jednym węźle w Docker Compose (trwałe woluminy, OLLAMA_HOST, karty NVIDIA, aktualizacje), zobacz
Ollama w Docker Compose z GPU i trwałą pamięcią modeli.
Dlaczego warto używać proxy dla Ollama zamiast udostępniania portu 11434
Ollama został zaprojektowany z myślą o uruchamianiu lokalnie. Domyślnie nasłuchuje na localhost na porcie 11434, co jest świetne dla stacji roboczej programisty i stanowi subtelną wskazówkę, że surowy port nie jest przeznaczony do wystawienia do internetu.
Traktuję port 11434 jako wewnętrzne, kosztowne API. Jeśli jest osiągalny z internetu, każdy, kto go znajdzie, może spalić Ci zasoby procesora lub karty graficznej, wypełnić dysk pobierając modele lub po prostu utrzymywać otwarte połączenia, aż do wystąpienia błędu timeoutu. Proxy odwrotne nie czyni Ollama bezpieczniejszym w magiczny sposób, ale daje Ci miejsce na umieszczenie kluczowych mechanizmów kontroli na krawędzi sieci: TLS, uwierzytelnianie, limity czasu, limitowanie zapytań (rate limiting) oraz logi.
To ma znaczenie, ponieważ lokalne API Ollama nie posiada wbudowanej warstwy uwierzytelniania. Jeśli je wystawisz, zazwyczaj dodajesz uwierzytelnianie na krawędzi sieci lub utrzymujesz je w prywatności, dostępne tylko w zaufanej sieci.
Drugi powodem jest doświadczenie użytkownika (UX). Ollama domyślnie zwraca odpowiedzi w trybie strumieniowym. Jeśli proxy buforuje lub kompresuje w niewłaściwym miejscu, strumieniowanie wydaje się nie działać, a interfejsy użytkownika wyglądają tak, jakby „myślały" bez wyświetlania żadnego wyniku.
Minimalna architektura i strategia wiązania (binding)
Czysta, minimalna architektura wygląda tak:
Klient (curl, Python, Go, UI)
|
| HTTPS (opcjonalnie Basic Auth lub SSO)
v
Proxy odwrotne (Caddy lub Nginx)
|
| HTTP (LAN prywatny, localhost lub sieć Docker)
v
Serwer Ollama (ollama serve na 127.0.0.1:11434)
Dwie praktyczne zasady sprawią, że całość będzie nudna w najlepszym możliwym sensie.
Po pierwsze, utrzymuj Ollama w prywatności i przenoś wystawienie usługi na proxy. Jeśli Caddy lub Nginx działają na tym samym hostcie, proxy do 127.0.0.1:11434 i nie zmieniaj adresu wiązania Ollama. Jeśli proxy działa gdzie indziej (na innym hoście, w osobnej VM lub w sieci kontenerów), wiąż Ollama z interfejsem prywatnym, a nie 0.0.0.0 na publicznej karcie sieciowej, i polegaj na zaprawie ogniowej (firewall).
Po drugie, zdecyduj na wczesnym etapie, czy przeglądarki będą wywoływać Ollama bezpośrednio. Jeśli narzędzie oparte na przeglądarce będzie łączyć się z Ollama z innej domeny (origin), może być konieczne zajęcie się problemem CORS. Jeśli wszystko jest dostarczane z jednej domeny przez proxy (zalecane dla zachowania zdrowia umysłowego), często można całkowicie uniknąć CORS i utrzymać Ollama w reżimie ścisłym.
Konfiguracje proxy odwrotnego dla strumieniowania i WebSockets
API Ollama to zwykłe HTTP, a jego strumieniowanie to NDJSON (Newline-Delimited JSON). Oznacza to, że potrzebujesz proxy, które dobrze radzi sobie z trzema rzeczami:
- Nie buforuje odpowiedzi strumieniowych.
- Nie przerywa długotrwałych zapytań tylko dlatego, że model potrzebował czasu na wypowiedzenie się.
- Jeśli UI używa WebSockets (niektóre tak robią), czyści przekazuje nagłówek Upgrade.
Możesz to utrzymać w prostocie. W wielu przypadkach „poprawna obsługa WebSockets" to po prostu posiadanie konfiguracji odpornej na Upgrade, nawet jeśli upstream obecnie nie używa WebSockets.
Przykład Caddyfile dla Caddy
Caddy to opcja „mniej konfiguracji, więcej domyślnych ustawień". Jeśli podasz publiczny adres domenowy w ustawieniach strony, Caddy zazwyczaj automatycznie uzyska i odnowi certyfikaty.
Minimalne ustawienia proxy odwrotnego, HTTPS i przyjazne dla strumieniowania:
# ollama.example.com A/AAAA -> twój host proxy
ollama.example.com {
# Opcjonalne Basic Auth na krawędzi.
# Wygeneruj hasło za pomocą:
# caddy hash-password --algorithm bcrypt
#
# basic_auth {
# alice $2a$12$REDACTED...
# }
reverse_proxy 127.0.0.1:11434 {
# Niektóre konfiguracje preferują przypinanie nagłówka Host upstream.
# Dokumentacja Ollama pokazuje ten wzorzec dla Nginx.
header_up Host localhost:11434
# Dla obciążeń strumieniowych lub czatów, preferuj niskie opóźnienia.
# Strumieniowanie NDJSON zazwyczaj flushuje natychmiastowo, ale to czyni to jawnym.
flush_interval -1
transport http {
# Unikaj negocjacji gzip upstream, jeśli to zakłóca strumieniowanie.
compression off
# Daj Ollama czas na załadowanie modelu i wygenerowanie pierwszego chunka.
response_header_timeout 10m
dial_timeout 10s
}
}
}
Jeśli już masz bramkę SSO (oauth2-proxy, Authelia, authentik outpost itd.), Caddy ma zdyscyplinowaną dyrektywę forward auth. Wzorzec to „najpierw uwierzytelnianie, potem proxy":
ollama.example.com {
forward_auth 127.0.0.1:4180 {
uri /oauth2/auth
# Skopiuj nagłówki tożsamości zwracane przez Twoją bramkę, jeśli ich potrzebujesz.
copy_headers X-Auth-Request-User X-Auth-Request-Email Authorization
}
reverse_proxy 127.0.0.1:11434
}
Przykład bloku serwera dla Nginx
Nginx daje nieco więcej swobody. Zaletą jest to, że wszystkie opcje są jawne, a on posiada wbudowane mechanizmy do limitowania zapytań i połączeń. Pułapką jest buforowanie: Nginx domyślnie buforuje zoproksowane odpowiedzi, co jest przeciwieństwem tego, czego potrzebujesz do strumieniowania NDJSON.
Ten przykład zawiera:
- Redyrekcję z HTTP na HTTPS
- Ścieżki do certyfikatów TLS (styl Certbot)
- Bezpieczne przekazywanie Upgrade dla WebSockets
- Przyjazne dla strumieniowania
proxy_buffering off - Dłuższe limity czasu niż domyślne 60s
# /etc/nginx/conf.d/ollama.conf
# Bezpieczna obsługa nagłówka Connection dla WebSockets
map $http_upgrade $connection_upgrade {
default upgrade;
"" close;
}
# Opcjonalne limitowanie zapytań (na podstawie IP)
# limit_req_zone $binary_remote_addr zone=ollama_rate:10m rate=10r/s;
server {
listen 80;
server_name ollama.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name ollama.example.com;
ssl_certificate /etc/letsencrypt/live/ollama.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ollama.example.com/privkey.pem;
# Opcjonalne Basic Auth na krawędzi.
# auth_basic "Ollama";
# auth_basic_user_file /etc/nginx/.htpasswd;
location / {
# Opcjonalny limit zapytań
# limit_req zone=ollama_rate burst=20 nodelay;
proxy_pass http://127.0.0.1:11434;
# Dostosuj wzorzec z dokumentacji Ollama przy proxy do localhost.
proxy_set_header Host localhost:11434;
# Obsługa Upgrade dla WebSockets (bezwzględna jeśli nieużywana).
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Kluczowe dla strumieniowania NDJSON.
proxy_buffering off;
# Zapobiegaj timeoutom 60s podczas czekania na tokeny.
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
Jeśli chcesz bramkę w stylu SSO w Nginx, odpowiednik to auth_request. Nginx wysyła podzapytanie do usługi uwierzytelniania i przekazuje zapytanie do Ollama tylko wtedy, gdy uwierzytelnianie zwraca kod 2xx.
Automatyzacja TLS i pułapki przy odnawianiu certyfikatów
W kwestii TLS rozróżnienie operacyjne jest proste.
W przypadku Caddy, TLS jest zazwyczaj „częścią proxy odwrotnego". Automatyczny HTTPS to jedna z jego flagowych funkcji, więc wydawanie i odnawianie certyfikatów jest sprzężone z działaniem Caddy, poprawnie skonfigurowaną DNS oraz wystawieniem portów 80 i 443.
W przypadku Nginx, TLS to zazwyczaj „osobny klient ACME plus Nginx". Częstym trybem awarii nie jest kryptografia, ale infrastruktura (plumbing):
- Port 80 nieosiągalny dla wyzwań HTTP-01.
- Certyfikaty przechowywane w kontenerze, ale nie utrwalane (persistowane).
- Limity zapytań przy powtarzanych świeżych instalacjach lub testowych wdrożeniach.
Subtelny punkt, który ma znaczenie dla usług o długim życiu, to fakt, że żywotność certyfikatów jest krótka z założenia. Traktuj odnawianie jako wymaganie automatyzacji w tle, a nie coroczne wydarzenie kalendarzowe.
Uwierzytelnianie, kontrola nadużyć i weryfikacja
To jest część, która sprawia, że endpoint LLM dostępny z internetu wygląda profesjonalnie.
Opcje uwierzytelniania, od prostej do eleganckiej
Basic Auth na proxy jest prosty, ale zaskakująco skuteczny dla prywatnego endpointu. Jest też łatwy do zastosowania zarówno dla zapytań HTTP, jak i upgrade’ów WebSocket.
Jeśli chcesz przepływów logowania przyjaznych dla przeglądarki, forward auth i auth_request to powszechny wzorzec. Twoje proxy pozostaje bezstanowe, a bramka uwierzytelniania zarządza sesjami i MFA. Kompromisem jest większa liczba ruchomych części.
Jeśli już uruchamiasz Open WebUI, możesz polegać na jego uwierzytelnieniu na poziomie aplikacji i utrzymać sam Ollama w prywatności. Proxy wtedy chroni Open WebUI, a nie bezpośrednio Ollama.
Jeśli nie potrzebujesz dostępu publicznego wcale, podejście oparte wyłącznie na sieci może być czystsze. Na przykład Tailscale Serve może wystawić usługę lokalną wewnątrz Twojego tailnet bez otwierania portów przychodzących na routerze.
Podstawy kontroli nadużyć dla kosztownego API
Ollama to potężne lokalne API, a jego powierzchnia ataku wykracza poza generowanie. Posiada endpointy do czatu, embeddings, listowania modeli i sprawdzania wersji. Traktuj całe API jako wrażliwe.
Oficjalne referencje API (endpointy i strumieniowanie): https://docs.ollama.com/api
Na warstwie proxy istnieją trzy niskokosztowe środki kontroli, które redukują problemy od pierwszego dnia:
- Limitowanie zapytań (rate limiting) na IP dla endpointów generowania.
- Limity połączeń, aby zapobiec sytuacji, w której niewielka liczba klientów trzyma wszystko otwarte.
- Konserwatywne limity czasu (timeouts), które pasują do Twojego modelu i sprzętu, a nie do ogólnych domyślnych ustawień sieciowych.
Na warstwie Ollama również może on odrzucić przeciążenie z kodem 503 i posiada sterowniki po stronie serwera do kolejek. Limitowanie zapytań na proxy utrzyma Cię z dala od tej sytuacji.
Lista kontrolna weryfikacji
Użyj tych samych sprawdzeń, które stosujesz dla dowolnego API strumieniowego.
-
Podstawowa łączność i TLS
curl -sS https://ollama.example.com/api/versioncurl -sS https://ollama.example.com/api/tags | head
-
Strumieniowanie działa od końca do końca (bez buforowania)
curl -N https://ollama.example.com/api/generate -H "Content-Type: application/json" -d '{"model":"mistral","prompt":"Write 10 words only.","stream":true}'
Jeśli jesteś za Basic Auth:
curl -N -u alice:REDACTED https://ollama.example.com/api/generate -H "Content-Type: application/json" -d '{"model":"mistral","prompt":"Write 10 words only.","stream":true}'
-
Sprawdzian UI przeglądarkowego
- Załaduj swój interfejs czatu i wywołaj odpowiedź.
- Jeśli UI używa WebSockets, potwierdź, że nie widzisz błędów 400 lub 426 i połączenie pozostaje otwarte podczas generowania.
Jeśli wynik z curl pojawia się tylko na końcu, prawie zawsze jest to buforowanie na proxy. Ponownie sprawdź proxy_buffering off w Nginx i rozważ wymuszenie niskopóźniowego flushowania w Caddy dla bloku strony Ollama.