Tutorials  /  AI/ML

Set Up Open WebUI as a Front End for Ollama

LLudwig · August 2026 ·11 min read ·AI/ML, Tutorial

Ollama exposes a REST API on port 11434 but ships no user interface, so every prompt runs through ollama run or curl. Open WebUI puts a multi-user chat front end on top of that API, with model switching, persistent chat history and document upload. This tutorial installs it in Docker on Ubuntu 24.04 against an Ollama instance running on the same host.

What is Open WebUI?

Open WebUI is a self-hosted, browser-based chat interface for local LLM back ends. It speaks to the Ollama REST API on port 11434 and adds user accounts, chat history, model management and RAG document upload on top of it.

The project is distributed as a container image (ghcr.io/open-webui/open-webui) and stores all state in a SQLite database under /app/backend/data. It does not run inference itself, so Ollama remains responsible for loading model weights and generating tokens.

Aspect ollama run (CLI) Open WebUI
Chat history Per session only Stored per user
Multi-user access No Yes, with roles
Model switching Restart the command Dropdown per chat
File and document upload No Yes

Prerequisites

  • Ubuntu 24.04 LTS on a scalable Linux cloud VM or any comparable host, with at least 8 GB RAM for 7B–8B models
  • Docker Engine 24.0 or newer and the docker compose plugin
  • Ollama 0.5 or newer installed on the host (curl -fsSL https://ollama.com/install.sh | sh)
  • 20 GB or more free disk space under /usr/share/ollama/.ollama/models
  • A user account with sudo rights

Confirm that Ollama is running before touching Open WebUI:

Console
$ systemctl is-active ollama
$ curl -s http://127.0.0.1:11434/api/version

The second command returns a JSON object such as {"version":"0.5.7"}. If it returns nothing, the service is not listening and the rest of the setup will fail at the first request.

How does Open WebUI reach Ollama?

Open WebUI reaches Ollama over plain HTTP against the URL in OLLAMA_BASE_URL, which defaults to http://localhost:11434. Inside a container that address resolves to the container itself, not to the host, which is the single most common cause of a failed setup.

The container needs a route to the host network stack. Docker provides one through the host-gateway alias, and Ollama has to be listening on an address that is reachable from the bridge network rather than on loopback alone.

graph LR
  A["Browser"] --> B["nginx :443"]
  B --> C["Open WebUI container :8080"]
  C -->|"OLLAMA_BASE_URL"| D["host.docker.internal:11434"]
  D --> E["ollama.service on the host"]
  E --> F["GPU or CPU inference"]
  C --> G["Volume: /app/backend/data"]
GPU

Matching infrastructure at centron

Dedicated NVIDIA GPUs from German data centres, billed by the hour and ready in minutes. Rent a GPU server →

Bind Ollama to the Docker bridge

By default the systemd unit binds Ollama to 127.0.0.1:11434. Change the bind address through a drop-in override so that package updates do not overwrite it:

Console
$ sudo systemctl edit ollama.service

Add the following block in the editor that opens:

ini
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

Reload and restart:

Console
$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama
$ ss -tlnp | grep 11434

The expected output shows 0.0.0.0:11434 in the local address column. The Ollama API has no authentication, so port 11434 must never be reachable from the internet. Restrict it to the Docker bridge ranges with ufw:

Console
$ sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp
$ sudo ufw deny 11434/tcp
$ sudo ufw status numbered

Rules are evaluated in order, so the allow rule must appear above the deny rule in the numbered list. If it does not, delete and re-add it with sudo ufw insert 1 ....

Run Open WebUI in Docker

Start the container with a named volume for its database and publish the port on loopback only, because nginx will terminate TLS in front of it:

Console
$ docker run -d \
  --name open-webui \
  --restart always \
  --add-host=host.docker.internal:host-gateway \
  -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
  -e WEBUI_SECRET_KEY="YOUR_RANDOM_SECRET" \
  -p 127.0.0.1:3000:8080 \
  -v open-webui:/app/backend/data \
  ghcr.io/open-webui/open-webui:main

The relevant flags:

  • --add-host=host.docker.internal:host-gateway creates the DNS name the container uses to reach the host. Without it, OLLAMA_BASE_URL cannot resolve.
  • WEBUI_SECRET_KEY signs session tokens. Generate one with openssl rand -hex 32. If it is missing, a new key is created on every container recreation and all users are logged out.
  • -v open-webui:/app/backend/data persists accounts, chats and uploaded documents. Everything in that volume is lost if you recreate the container without it.
  • -p 127.0.0.1:3000:8080 binds the published port to loopback. Published Docker ports bypass ufw, so an unqualified -p 3000:8080 would expose the interface publicly regardless of firewall rules.

For a deployment you intend to keep, put the same definition in a Compose file at /opt/open-webui/docker-compose.yml:

yaml
services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    restart: always
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      OLLAMA_BASE_URL: http://host.docker.internal:11434
      WEBUI_SECRET_KEY: YOUR_RANDOM_SECRET
      ENABLE_SIGNUP: "false"
    ports:
      - "127.0.0.1:3000:8080"
    volumes:
      - open-webui:/app/backend/data
volumes:
  open-webui:

Set ENABLE_SIGNUP to false only after you have created the first account: the first registered user automatically becomes the administrator. With signup disabled and no account present, the login page is unusable and you have to flip the variable back.

Do you need a GPU for Ollama?

Ollama runs entirely on CPU without a GPU, but throughput drops sharply: a quantized 8B model generates roughly 5 to 10 tokens per second on a typical server CPU, against 40 or more tokens per second on a current NVIDIA card.

Because Ollama runs on the host in this setup, it uses the NVIDIA driver directly and needs no NVIDIA Container Toolkit. Verify that the driver is visible and that Ollama picked it up:

Console
$ nvidia-smi --query-gpu=name,memory.total --format=csv
$ journalctl -u ollama --no-pager | grep -i "inference compute"

The log line names the detected device and its VRAM. If it reports CPU only while nvidia-smi works, restart ollama.service after the driver installation. For models above 13B parameters, VRAM becomes the limiting factor, which is where a GPU instance for LLM inference is the practical option; a 70B model at 4-bit quantization needs roughly 40 GB of VRAM to stay off the CPU.

Pull a model and verify

Open WebUI only lists models that Ollama already has. Pull one on the host:

Console
$ ollama pull llama3.1:8b
$ ollama list

Then check that the container sees the same list. The API call from inside the container is the definitive test, because it exercises the exact network path the application uses:

Console
$ docker exec open-webui curl -s http://host.docker.internal:11434/api/tags

The response is a JSON object whose models array contains an entry with "name":"llama3.1:8b". Now open http://127.0.0.1:3000 through an SSH tunnel (ssh -L 3000:127.0.0.1:3000 user@YOUR_HOST), create the first account, and select the model in the dropdown at the top of the chat window.

Publish Open WebUI over HTTPS

Open WebUI streams tokens over a WebSocket connection, so the reverse proxy has to pass the upgrade headers and must not buffer responses. Create /etc/nginx/sites-available/open-webui.conf:

nginx
server {
    listen 80;
    server_name YOUR_DOMAIN;
    client_max_body_size 64M;
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        proxy_read_timeout 600s;
    }
}

The client_max_body_size value caps document uploads; the default of 1 MB rejects most PDFs. The 600-second read timeout keeps long generations from being cut off mid-answer.

Enable the site and request a certificate:

Console
$ sudo ln -s /etc/nginx/sites-available/open-webui.conf /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl reload nginx
$ sudo certbot --nginx -d YOUR_DOMAIN

Certbot rewrites the server block for TLS and adds a redirect from port 80.

Update Open WebUI and Ollama

The main tag moves frequently. Update the container while keeping the volume:

Console
$ docker compose -f /opt/open-webui/docker-compose.yml pull
$ docker compose -f /opt/open-webui/docker-compose.yml up -d
$ docker image prune -f

The database schema migrates automatically on start. Check docker logs -f open-webui after an update and confirm the migration lines complete before you send traffic. Ollama is updated separately by re-running its install script; the systemd drop-in with OLLAMA_HOST survives that.

Troubleshooting

"Ollama: Server connection failed" or an empty model list. The container cannot reach port 11434. Run docker exec open-webui curl -sv http://host.docker.internal:11434/api/version. A connection refused means Ollama is still bound to loopback, so re-check the systemd override and ss -tlnp. A timeout instead points at the ufw rule order.

The answer never appears, or arrives all at once at the end. The reverse proxy is buffering. Confirm that proxy_buffering off; and both upgrade headers are present in the active server block, then reload nginx. Cloudflare and similar proxies need streaming enabled separately.

The disk fills up. Model weights accumulate under /usr/share/ollama/.ollama/models and are never removed automatically. List them with ollama list, check the total with du -sh /usr/share/ollama/.ollama/models, and delete unused tags with ollama rm MODEL:TAG.

Wrap-up

Open WebUI now serves as the browser interface for a host-local Ollama instance, with state in a named Docker volume and TLS handled by nginx. Keep port 11434 restricted to the Docker bridge, back up the open-webui volume along with the chat database, and add further models with ollama pull as needed.

Read next

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

Ludwig Technische Redaktion

Schreibt bei centron über Linux-Administration, Container und Datenbanken – mit Fokus auf Anleitungen, die im Betrieb tatsächlich funktionieren.

Kategorie AI/ML
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren