Open WebUI z Ollamą na własnym serwerze: instalacja i HTTPS
Open WebUI w Docker Compose z Ollamą albo samym API: nginx z HTTPS, konta i zatwierdzanie użytkowników, podpięcie OpenAI, Claude i Gemini oraz kopie danych.
Redakcja serwisu Dealownia · ceny i fakty ze stron dostawców, jak sprawdzamy
Trzy osoby w domu albo w małej firmie, każda z osobnym abonamentem czatu, i nikt nie wie, czy z niego naprawdę korzysta. Open WebUI rozwiązuje to jednym interfejsem w przeglądarce: konta dla każdego, wspólna lista modeli, a za nimi lokalna Ollama, płatne API w modelu „płacisz za tokeny” albo jedno i drugie. Poniżej stawiamy go pod https://czat.example.pl w Docker Compose, za nginx z certyfikatem, z zatwierdzaniem nowych kont i z kopią, z której da się odtworzyć rozmowy.
Czego potrzebujesz
- VPS przygotowany jak w poradniku od zera: użytkownik
deployz sudo, ufw, nginx na hoście, Docker z Compose. - RAM. Według dokumentacji Open WebUI 1 GB to bardzo mało, gdy działają dokumenty (RAG) i embeddingi, i lepiej mieć 2 GB lub więcej na sam interfejs. Lokalny model doliczasz osobno – ile pamięci potrzebuje który, pokazuje tabela w poradniku o Ollamie na VPS bez GPU. Jeśli korzystasz tylko z API, wystarczy plan z 2–4 GB.
- Dysk. Standardowy obraz pobiera się według dokumentacji w ok. 1,6 GB, do tego modele Ollamy i przesłane pliki.
- Subdomenę
czat.example.plz rekordem A wskazującym serwer.
Pełne porównanie planów jest w rankingu VPS, a roczny koszt serwera z domeną policzysz w kalkulatorze kosztu hostingu.
Krok 1. Katalog i klucz
WEBUI_SECRET_KEY podpisuje tokeny logowania i służy do szyfrowania części danych (np. sesji OAuth). Open WebUI potrafi wygenerować go sam, ale dokumentacja zaleca wygenerować go raz i trzymać stały. Bez stałego klucza po każdym odtworzeniu kontenera wszyscy zostają wylogowani, a przy przywracaniu kopii potrzebny jest ten sam klucz. Plik .env ma prawa 600, bo tak ustawił umask 077.
Krok 2. compose.yaml z Ollamą
Co tu jest ważne:
- Port 3003 na
127.0.0.1. Dokumentacja Open WebUI używa w przykładach portu 3000, ale ten numer zajmuje już Umami z poradnika o analityce, a 3001 – Uptime Kuma. Jeśli na serwerze działa coś jeszcze, sprawdź wolne porty poleceniemsudo ss -tlnp. Kontener nasłuchuje na 8080, a na zewnątrz wystawia go tylko nginx. - Ollama bez opublikowanego portu. Open WebUI łączy się z nią po nazwie usługi (
http://ollama:11434) w sieci, którą Compose tworzy dla projektu. Lokalne API Ollamy nie ma uwierzytelnienia, więc tak jest najbezpieczniej. DEFAULT_USER_ROLE: pending. Nowe konto nie dostaje dostępu do modeli, dopóki administrator go nie zatwierdzi. Dokumentacja poleca to ustawienie dla instancji dostępnych z internetu.ENABLE_COMMUNITY_SHARING: "false"wyłącza udostępnianie rozmów poza instancję. Tak radzi poradnik dokumentacji o pracy w zespole.CORS_ALLOW_ORIGIN. Bez tej zmiennej, według poradnika nginx w dokumentacji, połączenia WebSocket potrafią nie działać, nawet gdy proxy je przepuszcza. Hardening zaleca też zastąpienie domyślnego*własną domeną.mainilatest. Tagmain(tak samo jaklatest) to bieżąca kompilacja gałęzimain, a nie wybrane stabilne wydanie, i może bez ostrzeżenia przynieść zmiany niezgodne wstecz. Gdy wszystko działa, przypnij konkretne wydanie (ghcr.io/open-webui/open-webui:vX.Y.Z) – tak zaleca dokumentacja aktualizacji.
Masz już Ollamę z poprzedniego poradnika? Kontener z katalogu /opt/apps/ollama ma port tylko na 127.0.0.1 hosta, a z wnętrza innego kontenera ten adres nie jest osiągalny. Najprościej zatrzymać tamten projekt (cd /opt/apps/ollama && docker compose down) i w tym pliku podpiąć jego wolumen, żeby nie pobierać modeli drugi raz. Zamień ostatnią sekcję na:
Nazwę wolumenu sprawdzisz przez docker volume ls – Compose nazywa go <katalog projektu>_<nazwa wolumenu>. Jeśli korzystałeś z tunelu SSH albo z nginx z tokenem z tamtego poradnika, dopisz w usłudze ollama sekcję ports: ["127.0.0.1:11434:11434"] – inaczej po zatrzymaniu starego projektu ten adres przestanie odpowiadać.
Tylko API, bez lokalnego modelu? Usuń usługę ollama, całą sekcję depends_on, wolumen ollama i zmienną OLLAMA_BASE_URL, a dodaj ENABLE_OLLAMA_API: "false". Dokumentacja wspomina też o lżejszym obrazie :slim (ok. 200 MB zamiast 1,6 GB), ale nie ma w nim lokalnych embeddingów, rozpoznawania mowy ani przetwarzania dokumentów – te funkcje wymagają wtedy zewnętrznych usług, więc na start zostań przy main.
Pierwszy start trwa dłużej, bo obraz jest duży. Czekaj, aż w logu przestaną pojawiać się komunikaty o inicjalizacji, i sprawdź curl -sI http://127.0.0.1:3003 | head -1.
Krok 3. nginx z WebSocketem i certyfikat
Open WebUI używa połączeń WebSocket i strumieniuje odpowiedzi, więc proxy musi przekazywać nagłówki Upgrade i Connection i nie może buforować odpowiedzi. Mapę WebSocket tworzysz raz na serwer (wyjaśnienie w poradniku o reverse proxy); polecenie niżej nic nie zmieni, jeśli plik już istnieje:
Plik /etc/nginx/sites-available/czat.example.pl:
Wartości buforowania, limitów czasu (30 minut) i rozmiaru przesyłanych plików (20 MB) pochodzą z przykładu nginx w dokumentacji Open WebUI. Dokumentacja wyjaśnia, że włączone buforowanie potrafi pociąć strumieniowaną odpowiedź: znikają słowa i psuje się formatowanie. Jeśli użytkownicy wgrywają większe PDF-y, podnieś client_max_body_size.
Krok 4. Konto administratora i użytkownicy
Wejdź na https://czat.example.pl od razu po wystawieniu certyfikatu. Pierwsze założone konto zostaje administratorem: zarządza użytkownikami i wszystkimi ustawieniami instancji. Do tego czasu rejestracja jest otwarta i konto może przejąć każdy, kto trafi na adres. Po założeniu konta administratora Open WebUI sam wyłącza rejestrację.
Kolejne osoby dodajesz na dwa sposoby:
- Ręcznie: w panelu administratora, w sekcji użytkowników, zakładasz konto i przekazujesz hasło.
- Rejestracja z zatwierdzaniem: w ustawieniach administratora, w sekcji uwierzytelniania, włączasz nowe rejestracje. Nowe konta mają rolę
pendingi czekają, aż je zatwierdzisz. Po zaproszeniu wszystkich rejestrację wyłącz.
Zmienne ENABLE_SIGNUP i DEFAULT_USER_ROLE działają tylko przy pierwszym starcie. Później wygrywają ustawienia zapisane w bazie, więc zmiana w compose.yaml nic nie da – zmieniasz je w panelu. Dokumentacja hardeningu wymienia jeszcze kilka rzeczy wartych włączenia na instancji dostępnej z internetu: krótszy czas ważności sesji (JWT_EXPIRES_IN, domyślnie 4 tygodnie), walidację haseł i uwierzytelnianie dwuskładnikowe. Najlepiej w ogóle nie wystawiać panelu do internetu: jeśli korzystasz tylko Ty i rodzina, wystarczy VPN albo tunel, a strona nie musi mieć publicznego rekordu DNS.
Krok 5. Zewnętrzne API zamiast lokalnego modelu
Lokalny model na CPU jest wolny i mniej zdolny od dużych modeli w chmurze. Open WebUI łączy się z każdym API zgodnym z OpenAI, w tym z API Anthropic i Google. W panelu administratora wejdź w ustawienia, potem Connections → Manage OpenAI API Connections → Add Connection, wpisz adres i klucz API, zapisz.
| Dostawca | Adres (z dokumentacji Open WebUI) | Uwagi |
|---|---|---|
| OpenAI | https://api.openai.com/v1 |
domyślny adres zmiennej OPENAI_API_BASE_URL |
| Anthropic (Claude) | https://api.anthropic.com/v1 |
warstwa zgodności OpenAI; Anthropic przeznacza ją do testów i oceny, bez cache promptów i natywnej obsługi PDF |
| Google Gemini | https://generativelanguage.googleapis.com/v1beta/openai |
bez ukośnika na końcu, inaczej lista modeli się nie pobierze |
| DeepSeek | https://api.deepseek.com/v1 |
|
| Mistral AI | https://api.mistral.ai/v1 |
|
| OpenRouter | https://openrouter.ai/api/v1 |
jeden klucz do modeli wielu firm |
Kilka zasad przy kluczach:
- Załóż osobny klucz tylko dla Open WebUI. Dokumentacja odradza używanie kluczy głównych z pełnymi uprawnieniami.
- Jeśli dostawca pozwala ustawić limit wydatków albo działa na doładowaniach, skorzystaj z tego. Kilka osób na jednym kluczu potrafi wydać więcej, niż zakładasz.
- W polu Model IDs połączenia wpisz tylko modele, które chcesz pokazać. Pełna lista u dużych dostawców ma dziesiątki pozycji, w tym drogie modele.
- Weryfikacja połączenia czasem kończy się błędem 400, 401 albo 403, choć rozmowy działają – dokumentacja opisuje to wprost. Sprawdzaj wysłaniem wiadomości, nie samym przyciskiem.
Ile kosztuje taka rozmowa i kiedy API wychodzi taniej niż abonament, liczy poradnik ile kosztuje API modeli AI w złotych. Ceny abonamentów porównasz w rankingu asystentów AI.
Krok 6. Kopie danych
Rozmowy, użytkownicy, ustawienia i przesłane pliki leżą w wolumenie zamontowanym jako /app/backend/data: baza webui.db (SQLite), katalogi uploads/ i vector_db/. Dokumentacja odradza pobieranie bazy z panelu administratora jako kopii: ostatnie zmiany mogą jeszcze siedzieć w pliku webui.db-wal, więc pobrany plik może ich nie mieć. Sam webui.db nie obejmuje też przesłanych plików ani bazy wektorowej – te leżą w uploads/ i vector_db/. Najbardziej spójną kopię daje według dokumentacji kopiowanie przy zatrzymanej usłudze, więc skrypt zatrzymuje kontener na kilka sekund i pakuje cały wolumen.
Skrypt /opt/apps/openwebui/backup.sh:
trap uruchomi kontener ponownie także wtedy, gdy pakowanie się nie uda. Kopia .env jest potrzebna, bo bez tego samego WEBUI_SECRET_KEY po przywróceniu wszyscy będą musieli zalogować się od nowa, a dane zaszyfrowane tym kluczem nie dadzą się odczytać. Modeli Ollamy nie kopiujesz – pobierzesz je ponownie. Archiwum wyślij poza serwer, np. jak w poradniku o restic i rclone.
Przed każdą aktualizacją uruchom skrypt ręcznie, a potem:
Według dokumentacji migracje bazy działają tylko w jedną stronę. Powrót do starszego obrazu ich nie cofnie, więc wtedy ratuje Cię tylko kopia sprzed aktualizacji.
Najczęstsze problemy
- Po restarcie kontenera wszyscy są wylogowani. Brak stałego
WEBUI_SECRET_KEYalbo kontener nie widzi pliku.env(sprawdźdocker compose config | grep SECRET). - Odpowiedź pojawia się dopiero w całości albo brakuje w niej słów. nginx buforuje odpowiedź – sprawdź
proxy_buffering off. - Interfejs pokazuje błąd połączenia, czat się nie odświeża. Brak nagłówków
Upgrade/Connectionalbo inny adres wCORS_ALLOW_ORIGINniż ten w pasku przeglądarki. - Nie widać modeli Ollamy. Zły
OLLAMA_BASE_URL(w tym układziehttp://ollama:11434) albo w Ollamie nie ma jeszcze żadnego modelu:docker compose exec ollama ollama pull qwen3:8b. - Zmiana zmiennej w
compose.yamlnic nie zmienia. To ustawienie z grupy zapisywanych w bazie przy pierwszym starcie – zmień je w panelu administratora.
Źródła
Sprawdzone 12.11.2026:
- Open WebUI – szybki start (obrazy
main,cuda,ollama,slim, wolumen danych, pierwsze konto administratora): https://docs.openwebui.com/getting-started/quick-start/ - Open WebUI – zmienne środowiskowe (
ENABLE_SIGNUP,DEFAULT_USER_ROLE,WEBUI_URL,OLLAMA_BASE_URL,ENABLE_OLLAMA_API,OPENAI_API_BASE_URL): https://docs.openwebui.com/reference/env-configuration/ - Open WebUI – nginx (WebSocket, buforowanie, limity czasu,
CORS_ALLOW_ORIGIN): https://docs.openwebui.com/reference/https/nginx/ - Open WebUI – udostępnianie zespołowi (rola
pending, rejestracja): https://docs.openwebui.com/getting-started/sharing/ - Open WebUI – hardening: https://docs.openwebui.com/getting-started/advanced-topics/hardening/
- Open WebUI – wydajność i RAM: https://docs.openwebui.com/troubleshooting/performance/
- Open WebUI – kopie: https://docs.openwebui.com/tutorials/maintenance/backups/
- Open WebUI – aktualizacje: https://docs.openwebui.com/getting-started/updating/
- Open WebUI – połączenia zgodne z OpenAI i Anthropic: https://docs.openwebui.com/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/, https://docs.openwebui.com/getting-started/quick-start/connect-a-provider/starting-with-anthropic/
- Ollama – brak uwierzytelnienia lokalnego API: https://docs.ollama.com/api/authentication