Open WebUI looks like a local-AI project, and half the write-ups about it assume you're running Ollama and a model on the same box. Most small VPS plans cannot do that usefully. What they can do very well is run Open WebUI itself and point it at somebody else's model over an API — a private, self-hosted chat front end with your own login, your own history, and no local GPU pretending to exist.Open WebUI wirkt wie ein Projekt für lokale KI, und die Hälfte der Anleitungen dazu geht davon aus, dass du Ollama und ein Modell auf derselben Maschine laufen lässt. Die meisten kleinen VPS-Pläne können das nicht sinnvoll leisten. Was sie sehr gut können: Open WebUI selbst betreiben und es über eine API an das Modell von jemand anderem anbinden — ein privates, selbst gehostetes Chat-Frontend mit eigenem Login, eigener Historie und ohne eine lokale GPU, die nur so tut als ob.
Open WebUI is a FastAPI backend plus a bundled frontend, backed by a SQLite database by default. The catch is the default image: it bundles a local embedding stack (torch plus sentence-transformers) for the built-in "chat with documents" feature, and that alone can idle close to or past 1 GiB before Open WebUI has answered a single message — before the OS, sshd, cron, and the Docker daemon's own overhead take their share too. A Starter, 1 vCPU / 1 GiB, might run it, but with no headroom for anything else on the box; treat a Basic, 2 vCPU / 2 GiB, as the realistic floor even for this idle, no-Ollama case.Open WebUI ist ein FastAPI-Backend plus mitgeliefertes Frontend, standardmäßig unterlegt mit einer SQLite-Datenbank. Der Haken liegt im Standard-Image: Es bringt einen lokalen Embedding-Stack (torch plus sentence-transformers) für die eingebaute Funktion „Chat mit Dokumenten“ mit, und allein das kann im Leerlauf nahe an oder über 1 GiB liegen, bevor Open WebUI auch nur eine einzige Nachricht beantwortet hat — bevor überhaupt das Betriebssystem, sshd, Cron und der Docker-Daemon selbst ihren Anteil nehmen. Ein Starter, 1 vCPU / 1 GiB, könnte es zum Laufen bringen, aber ohne jeden Spielraum für sonst irgendetwas auf der Maschine; betrachte einen Basic, 2 vCPU / 2 GiB, als realistische Untergrenze, selbst für diesen Leerlauf-Fall ohne Ollama.
The story falls apart the moment you add Ollama and try to run a model on the same VPS. A model small enough to load in a couple of spare gigabytes of RAM, on a CPU with no GPU acceleration, answers slowly enough that the exercise stops being useful — you are not saving money, you are building a chatbot that takes thirty seconds to start a sentence. Local inference on a general-purpose KVM VPS without a GPU is not a sizing problem you can buy your way out of with a bigger plan in the 1-2 GiB range; it needs the kind of RAM and CPU that model actually deserves, or it needs a GPU, and neither is what a small VPS is for.Die Geschichte bricht in dem Moment zusammen, in dem du Ollama dazunimmst und versuchst, ein Modell auf demselben VPS laufen zu lassen. Ein Modell, das klein genug ist, um in ein paar übrigen Gigabyte RAM zu passen, auf einer CPU ohne GPU-Beschleunigung, antwortet so langsam, dass sich die Übung nicht mehr lohnt — du sparst kein Geld, du baust einen Chatbot, der dreißig Sekunden braucht, um einen Satz zu beginnen. Lokale Inferenz auf einem universellen KVM-VPS ohne GPU ist kein Sizing-Problem, das du dir mit einem größeren Plan im Bereich von 1-2 GiB freikaufen kannst; es braucht die Art von RAM und CPU, die dieses Modell tatsächlich verdient, oder es braucht eine GPU — und beides ist nicht das, wofür ein kleiner VPS gedacht ist.
The setup that actually works at small-VPS scale: Open WebUI on the VPS, talking to an OpenAI-compatible API provider over the network, using your own API key. The provider does the inference on their hardware; your VPS just runs the chat UI, holds your conversation history, and manages your users. A Basic, 2 vCPU / 2 GiB, is a comfortable size for this — room for Open WebUI, Caddy, and normal Docker overhead with headroom to spare. If you later decide you do want local models, that is a different, much bigger machine and a different guide; this one is about the setup most people actually want.Das Setup, das im Maßstab eines kleinen VPS tatsächlich funktioniert: Open WebUI auf dem VPS, das über das Netzwerk mit einem OpenAI-kompatiblen API-Anbieter spricht, mit deinem eigenen API-Schlüssel. Der Anbieter erledigt die Inferenz auf seiner eigenen Hardware; dein VPS betreibt nur die Chat-Oberfläche, hält deine Gesprächshistorie und verwaltet deine Nutzer. Ein Basic, 2 vCPU / 2 GiB, ist dafür eine komfortable Größe — Platz für Open WebUI, Caddy und den üblichen Docker-Overhead, mit Reserve übrig. Wenn du dich später doch für lokale Modelle entscheidest, ist das eine andere, viel größere Maschine und eine andere Anleitung; diese hier behandelt das Setup, das die meisten Leute tatsächlich wollen.
Pin the image tag — main moves under you on every restart that repulls, and a silent version bump is the last thing you want on something holding your chat history. Check github.com/open-webui/open-webui/pkgs/container/open-webui for the current release tag before you deploy.Pinne den Image-Tag — main verändert sich unbemerkt bei jedem Neustart, der neu zieht, und ein stiller Versionssprung ist das Letzte, was du bei etwas willst, das deine Chat-Historie enthält. Prüfe github.com/open-webui/open-webui/pkgs/container/open-webui auf den aktuellen Release-Tag, bevor du deployst.
services:
open-webui:
image: ghcr.io/open-webui/open-webui:<tag-from-the-packages-page> # not a real tag — copy the one you see there
restart: unless-stopped
env_file:
- .env
environment:
- WEBUI_AUTH=true
volumes:
- open-webui:/app/backend/data
ports:
- "127.0.0.1:8080:8080"
volumes:
open-webui:
The data volume is the whole of the application's state: SQLite database, uploaded files, and any local settings, all under /app/backend/data inside the container. Nothing else needs to survive a rebuild.Das Daten-Volume ist der gesamte Zustand der Anwendung: SQLite-Datenbank, hochgeladene Dateien und alle lokalen Einstellungen, alles unter /app/backend/data im Container. Nichts anderes muss einen Rebuild überleben.
.env file: your key, your providerDie .env-Datei: dein Schlüssel, dein AnbieterOpen WebUI talks to any OpenAI-compatible API — OpenAI itself, or one of the compatible providers — through two environment variables. Keep them out of the compose file and out of version control:Open WebUI spricht mit jeder OpenAI-kompatiblen API — OpenAI selbst oder einem der kompatiblen Anbieter — über zwei Umgebungsvariablen. Halte sie aus der Compose-Datei und aus der Versionskontrolle heraus:
cat > .env <<'EOF'
OPENAI_API_BASE_URL=https://api.openai.com/v1
OPENAI_API_KEY=sk-your-key-here
WEBUI_SECRET_KEY=
EOF
chmod 600 .env
OPENAI_API_BASE_URL points at the provider's API root; OPENAI_API_KEY is the key from that provider's dashboard. Swap the base URL for any other OpenAI-compatible endpoint and the key that goes with it — Open WebUI does not care which provider is behind it, only that the API shape matches. Leave WEBUI_SECRET_KEY blank for now; the next section is why it exists at all.OPENAI_API_BASE_URL zeigt auf die Basis-URL der API des Anbieters; OPENAI_API_KEY ist der Schlüssel aus dem Dashboard dieses Anbieters. Tausche die Basis-URL gegen jeden anderen OpenAI-kompatiblen Endpunkt und den dazugehörigen Schlüssel — Open WebUI ist es egal, welcher Anbieter dahintersteht, solange die Form der API passt. Lass WEBUI_SECRET_KEY vorerst leer; der nächste Abschnitt erklärt, wozu er überhaupt existiert.
WEBUI_SECRET_KEY, or why everyone gets logged out after an updateWEBUI_SECRET_KEY, oder warum nach einem Update alle ausgeloggt werdenOpen WebUI signs session tokens with a secret key. If you never set one, it generates a random key when the container is first created and keeps it inside the container, not in the data volume — which means every time the container is recreated, which is exactly what docker compose up -d after an image update does, every existing session is invalidated and everyone is logged out. Harmless on a single-user instance you barely notice; genuinely annoying the moment more than one person uses it.Open WebUI signiert Session-Tokens mit einem geheimen Schlüssel. Setzt du nie einen, erzeugt es beim ersten Anlegen des Containers einen zufälligen Schlüssel und behält ihn im Container, nicht im Daten-Volume — das heißt, jedes Mal, wenn der Container neu angelegt wird, und genau das tut docker compose up -d nach einem Image-Update, wird jede bestehende Session ungültig und alle werden ausgeloggt. Auf einer Single-User-Instanz harmlos, kaum bemerkbar; wirklich ärgerlich, sobald mehr als eine Person sie benutzt.
Generate one once and pin it in .env:Erzeuge einmal einen und pinne ihn in .env:
python3 -c "import secrets; print(secrets.token_hex(32))"
Paste the output into WEBUI_SECRET_KEY= in .env, then bring the stack up. Sessions now survive restarts and updates, because the key that signs them no longer changes underneath them.Füge die Ausgabe in .env bei WEBUI_SECRET_KEY= ein und starte den Stack dann hoch. Sessions überleben jetzt Neustarts und Updates, weil sich der Schlüssel, der sie signiert, nicht mehr unbemerkt ändert.
Bring the stack up and open it through the proxy (below) or a temporary SSH tunnel to 127.0.0.1:8080. The very first account you create becomes the admin — Open WebUI has no separate setup wizard, the first signup is the setup.Starte den Stack und öffne ihn über den Proxy (unten) oder einen temporären SSH-Tunnel zu 127.0.0.1:8080. Das allererste Konto, das du anlegst, wird zum Admin — Open WebUI hat keinen separaten Einrichtungsassistenten, die erste Registrierung ist die Einrichtung.
docker compose up -d
The moment that admin account exists, close registration:Sobald dieses Admin-Konto existiert, schließe die Registrierung:
cat >> .env <<'EOF'
ENABLE_SIGNUP=false
EOF
docker compose up -d
Until you do this, Open WebUI's default is open self-registration — anyone who finds the URL before you do can create the first account and claim admin instead of you, or add themselves as a regular user after. That's also why the compose file above deliberately does not set ENABLE_SIGNUP itself: it has to stay open long enough for your own first signup to work, since Open WebUI has no separate step for creating the first admin. ENABLE_SIGNUP=false in .env — loaded by the env_file: line already in the compose file — stops new signups from here on; the admin can still add users by hand from Admin Panel → Users afterward.Bis du das tust, ist bei Open WebUI standardmäßig die offene Selbstregistrierung aktiv — wer auch immer die URL vor dir findet, kann das erste Konto anlegen und sich statt dir den Admin-Status sichern, oder sich danach als normaler Nutzer hinzufügen. Genau deshalb setzt die Compose-Datei oben ENABLE_SIGNUP bewusst nicht selbst: Sie muss lange genug offen bleiben, damit deine eigene erste Registrierung funktioniert, da Open WebUI keinen eigenen Schritt zum Anlegen des ersten Admins kennt. ENABLE_SIGNUP=false in .env — geladen über die bereits in der Compose-Datei vorhandene env_file:-Zeile — stoppt neue Registrierungen ab diesem Zeitpunkt; der Admin kann Nutzer danach weiterhin von Hand unter Admin Panel → Users hinzufügen.
chat.example.com {
reverse_proxy 127.0.0.1:8080
}
That's the whole file — Caddy requests and renews the certificate the first time it starts with DNS already pointed at the box. Point the A record first, let it settle, then start Caddy.Das ist die ganze Datei — Caddy fordert das Zertifikat an und erneuert es, sobald es zum ersten Mal startet, während der DNS bereits auf die Maschine zeigt. Richte zuerst den A-Eintrag ein, lass ihn sich setzen, und starte dann Caddy.
The catch is the same one every guide like this has to repeat: on NAT IPv4, ports 80 and 443 are not automatically yours. Some plans forward them by default, some hand you a small set of other ports instead, and Caddy needs at least 443 reachable to get a certificate over the standard TLS-ALPN or HTTP challenge. Check what your plan actually forwards before you point DNS at it — NAT IPv4, ports and forwarding and NAT IPv4 vs a dedicated IP cover the mechanics, and a dedicated IPv4 that sidesteps the whole question is arranged by e-mail, not self-service, on our plans.Der Haken ist derselbe, den jede Anleitung dieser Art wiederholen muss: Bei NAT-IPv4 gehören dir die Ports 80 und 443 nicht automatisch. Manche Pläne leiten sie standardmäßig weiter, manche geben dir stattdessen eine kleine Auswahl anderer Ports, und Caddy braucht mindestens Port 443 erreichbar, um über die übliche TLS-ALPN- oder HTTP-Challenge ein Zertifikat zu bekommen. Prüfe, was dein Plan tatsächlich weiterleitet, bevor du DNS darauf zeigen lässt — NAT-IPv4, Ports und Portweiterleitung und NAT-IPv4 vs. dedizierte IP beschreiben die Mechanik, und eine dedizierte IPv4, die die ganze Frage umgeht, wird bei uns per E-Mail vereinbart, nicht per Self-Service.
Everything that matters lives in the one named volume, open-webui, mounted at /app/backend/data — the SQLite database with your chat history, users, and settings, plus any files uploaded through the UI. Stop the container before copying it, so nothing is mid-write:Alles, was zählt, liegt in dem einen benannten Volume open-webui, eingehängt unter /app/backend/data — die SQLite-Datenbank mit deiner Chat-Historie, den Nutzern und Einstellungen, plus allen über die Oberfläche hochgeladenen Dateien. Stoppe den Container, bevor du es kopierst, damit nichts mitten im Schreibvorgang ist:
docker compose stop open-webui
docker run --rm -v open-webui:/data -v "$(pwd)":/backup alpine \
tar czf /backup/open-webui-backup-$(date +%F).tar.gz -C /data .
docker compose start open-webui
Copy that archive off the VPS. back up your VPS is our own write-up of what off-machine backup means in practice — a tarball sitting next to the volume it came from is not a backup, it's a second copy of the same disk failure.Kopiere dieses Archiv vom VPS herunter. Backup deines VPS ist unser eigener Leitfaden dazu, was ein Backup abseits der Maschine in der Praxis bedeutet — ein Tarball, der neben dem Volume liegt, aus dem er stammt, ist kein Backup, sondern eine zweite Kopie desselben Festplattenausfalls.
docker compose pull
docker compose up -d
Bump the pinned tag in the compose file deliberately rather than tracking main, and read the release notes for whatever you're jumping to — Open WebUI ships fast, and a jump across several versions can carry a database migration. Take the volume backup above immediately beforehand; a migration you can undo is one where the backup is minutes old, not something you improvise after the fact.Aktualisiere den gepinnten Tag in der Compose-Datei bewusst, statt main zu verfolgen, und lies die Release-Notes zu dem, worauf du springst — Open WebUI erscheint schnell, und ein Sprung über mehrere Versionen kann eine Datenbank-Migration mit sich bringen. Mach das Volume-Backup von oben unmittelbar vorher; eine Migration, die du rückgängig machen kannst, ist eine, bei der das Backup Minuten alt ist, nicht etwas, das du hinterher improvisierst.
Be precise about this, because "private ChatGPT" gets oversold. Your prompts and the model's replies travel to whichever API provider you configured in OPENAI_API_BASE_URL — that provider processes them under their own terms, exactly as if you'd called their API directly, because that is literally what's happening. What Open WebUI adds is everything around that call: the UI, the accounts, the conversation history, the settings, all of it living in your own data volume on your own VPS, not in a vendor's web app tied to a vendor's account. If you want the inference itself to stay off third-party hardware too, that's the local-Ollama setup this guide talked you out of running on a small box — a real option, just not a 1-2 GiB one.Sei hier präzise, denn „privates ChatGPT“ wird gerne überverkauft. Deine Prompts und die Antworten des Modells reisen zu welchem API-Anbieter auch immer du in OPENAI_API_BASE_URL konfiguriert hast — dieser Anbieter verarbeitet sie nach seinen eigenen Bedingungen, genau so, als hättest du seine API direkt aufgerufen, weil das buchstäblich passiert. Was Open WebUI hinzufügt, ist alles rund um diesen Aufruf: die Oberfläche, die Konten, die Gesprächshistorie, die Einstellungen — alles lebt in deinem eigenen Daten-Volume auf deinem eigenen VPS, nicht in der Web-App eines Anbieters, gebunden an dessen Konto. Willst du auch, dass die Inferenz selbst von fremder Hardware fernbleibt, ist das das lokale Ollama-Setup, von dem dir diese Anleitung auf einer kleinen Maschine abgeraten hat — eine reale Option, nur keine für 1-2 GiB.
Full disclosure: this is what we sell. If you want the chat without the sysadmin, the managed Private AI Chat container comes with its own hostname and certificate.Zur vollen Transparenz: Das ist, was wir verkaufen. Willst du den Chat ohne die Systemadministration, kommt der gemanagte Private-AI-Chat-Container mit eigenem Hostnamen und Zertifikat.
One-click apps — EUR 4 to EUR 12 a month, hosted in Germany (EU). Eight apps: n8n, Uptime Kuma, Vaultwarden, Gitea, Nextcloud, Ghost, Managed WordPress, Private AI Chat. Each customer gets an isolated Docker network and volume, plus a hostname under apps.overnight.host on a real wildcard certificate. Memory and CPU are capped per plan by the container runtime.One-Click-Apps — 4 bis 12 EUR im Monat, gehostet in Deutschland (EU). Acht Apps: n8n, Uptime Kuma, Vaultwarden, Gitea, Nextcloud, Ghost, Managed WordPress, Private AI Chat. Jeder Kunde bekommt ein isoliertes Docker-Netzwerk und -Volume sowie einen Hostnamen unter apps.overnight.host mit einem echten Wildcard-Zertifikat. Arbeitsspeicher und CPU sind je Plan durch die Container-Runtime gedeckelt.
You order in the shop, pay by card (Stripe) or SEPA bank transfer, and your login details are e-mailed to you once the service is set up. Support is e-mail, run by one person, with no guaranteed response time. All prices are final totals under the German small-business rule (§19 UStG); no VAT is added or shown.Du bestellst im Shop, zahlst per Karte (Stripe) oder SEPA-Überweisung, und deine Zugangsdaten werden dir per E-Mail zugeschickt, sobald der Dienst eingerichtet ist. Support läuft per E-Mail, von einer einzelnen Person betrieben, ohne garantierte Reaktionszeit. Alle Preise sind Endpreise. Gemäß § 19 UStG wird keine Umsatzsteuer ausgewiesen.
Order ai-open-webui → · One-click apps overviewai-open-webui bestellen → · Übersicht One-Click-Apps
Written by the person who runs overnight.host: a small, honest hosting company on dedicated bare metal — Linux VPS, game servers, web hosting. Live status at up.overnight.host.Geschrieben von der Person, die overnight.host betreibt: ein kleines, ehrliches Hosting-Unternehmen auf dedizierter Bare-Metal-Hardware — Linux-VPS, Gameserver, Webhosting. Live-Status unter up.overnight.host.
Technically yes, usefully no, on anything in the 1-2 GiB range. A model small enough to fit alongside Open WebUI in that RAM, running on CPU with no GPU, answers too slowly to be worth it. Local inference wants a machine sized for the model — much more RAM, ideally a GPU — which is a different setup than the one this guide covers.Technisch ja, sinnvoll nein, bei allem im Bereich von 1-2 GiB. Ein Modell, das klein genug ist, um neben Open WebUI in diesen RAM zu passen, und dabei auf CPU ohne GPU läuft, antwortet zu langsam, um sich zu lohnen. Lokale Inferenz will eine Maschine, die auf das Modell zugeschnitten ist — deutlich mehr RAM, idealerweise eine GPU — und das ist ein anderes Setup als das, das diese Anleitung behandelt.
No. Point Open WebUI's OPENAI_API_BASE_URL and OPENAI_API_KEY at any OpenAI-compatible provider and the connections tab in the UI will list its models directly. Ollama only matters if you're running models locally.Nein. Richte OPENAI_API_BASE_URL und OPENAI_API_KEY von Open WebUI auf einen beliebigen OpenAI-kompatiblen Anbieter aus, und der Verbindungen-Tab in der Oberfläche listet dessen Modelle direkt auf. Ollama spielt nur eine Rolle, wenn du Modelle lokal betreibst.
WEBUI_SECRET_KEY?Was passiert, wenn ich WEBUI_SECRET_KEY verliere?Every existing session gets invalidated the next time the container starts with a different key, so everyone has to log back in. Accounts and chat history in the data volume are untouched — the key only signs session tokens, it doesn't encrypt the database.Jede bestehende Session wird ungültig, sobald der Container das nächste Mal mit einem anderen Schlüssel startet, also müssen sich alle neu einloggen. Konten und Chat-Historie im Daten-Volume bleiben unangetastet — der Schlüssel signiert nur Session-Tokens, er verschlüsselt nicht die Datenbank.
Same application, different ownership of the box. The managed container gives you a hostname under apps.overnight.host on a wildcard certificate and an isolated network and volume; you still bring your own API key and provider, because the managed product includes the app, not a model or API credit. You don't get a root shell to tune the compose file yourself — that's the trade for not running the VPS at all.Dieselbe Anwendung, nur mit anderem Eigentümer der Maschine. Der gemanagte Container gibt dir einen Hostnamen unter apps.overnight.host mit Wildcard-Zertifikat sowie ein isoliertes Netzwerk und Volume; deinen eigenen API-Schlüssel und Anbieter bringst du trotzdem selbst mit, denn das gemanagte Produkt umfasst die App, nicht ein Modell oder API-Guthaben. Eine Root-Shell, um die Compose-Datei selbst anzupassen, bekommst du nicht — das ist der Tausch dafür, den VPS gar nicht erst selbst zu betreiben.
It's the default and it works well for the normal case: one instance, a household or small team's worth of users, nobody hammering it with concurrent writes. It lives inside the same data volume as everything else, so the backup story above already covers it — there's no separate database container to add unless your own use pushes past what a single-file database handles comfortably.Es ist die Standardeinstellung und funktioniert für den Normalfall gut: eine Instanz, so viele Nutzer wie ein Haushalt oder ein kleines Team, niemand, der sie mit gleichzeitigen Schreibzugriffen bombardiert. Sie liegt im selben Daten-Volume wie alles andere, die Backup-Geschichte von oben deckt sie also schon ab — es gibt keinen separaten Datenbank-Container hinzuzufügen, es sei denn, dein eigener Gebrauch geht über das hinaus, was eine Einzeldatei-Datenbank noch bequem bewältigt.
Prices are final totals; no VAT is shown (§19 UStG). Need something the shop does not list? Email us for a written offer.Alle Preise sind Endpreise ohne ausgewiesene USt. (§19 UStG). Du brauchst etwas, das nicht im Shop steht? Schreib uns für ein schriftliches Angebot.
Order now →Jetzt bestellen → Request a custom configIndividuelle Konfiguration anfragen