How to run Open WebUI with Ollama using Docker Compose and HTTPS
Run Open WebUI with Ollama in Docker Compose, reach Ollama safely on 127.0.0.1, add HTTPS with Caddy, lock down sign-up and back up chats and settings.
- Intermediate
- 35 min read
- Updated
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13
This guide is not available in your language yet, so it is shown in English.
On this page
- Prerequisites
- Step 1 — Choose how Open WebUI reaches Ollama
- Step 2 — Create the project directory and secrets
- Step 3 — Write the Compose file
- Step 4 — Start the stack and load a model
- Step 5 — Create the administrator account privately
- Step 6 — Publish Open WebUI over HTTPS with Caddy
- Back up and restore
- Update Open WebUI
- Troubleshooting
- No models appear in the model selector
- Logs show an origin that is not an accepted origin
- Changing an environment variable has no effect
- Everyone is logged out after recreating the container
- Caddy returns 502 Bad Gateway
- Next steps
Open WebUI is a self-hosted web interface for large language models. It gives you a ChatGPT-style chat with user accounts, chat history, document upload and model management, and it works with Ollama as well as with OpenAI-compatible APIs. This guide runs Open WebUI with Docker Compose, connects it to Ollama without exposing Ollama's API, publishes the interface only on 127.0.0.1, puts Caddy in front for HTTPS, creates the administrator account privately and shows how to back up, update and troubleshoot the installation.
Prerequisites
- A server running Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12 or Debian 13.
- A non-root user with
sudorights; see Secure a new Linux server and Set up SSH keys. - Docker Engine with the Compose plugin: follow Install Docker on Ubuntu or Install Docker on Debian.
- A domain or subdomain, for example
chat.example.com, with an A (and optionally AAAA) record pointing at the server, and Caddy installed as described in Caddy as a reverse proxy. - Optional: Ollama already installed on the host from How to install Ollama. If you do not have it yet, this guide can run Ollama in Docker for you.
| Resource | Minimum (official) | Suggested starting point |
|---|---|---|
| CPU | Not published | 2 vCPU for Open WebUI, plus what your models need |
| RAM | Not published | 4 GB for Open WebUI, plus the memory of the models you run in Ollama |
| Disk | Not published (the standard image is about 1.66 GB) | 20 GB free, plus space for models |
The Open WebUI quick start does not publish minimum CPU or memory figures; the suggested values are a conservative starting point, not a benchmark. Model inference happens in Ollama, so size the server mainly for your models; How to install Ollama covers model memory.
Step 1 — Choose how Open WebUI reaches Ollama
Open WebUI's examples use --add-host=host.docker.internal:host-gateway so the container can reach services on the host. That name resolves to the host's address on the Docker bridge network, not to the host's loopback interface. Ollama, however, listens on 127.0.0.1:11434 by default and therefore refuses connections arriving on the bridge address. Open WebUI's troubleshooting page suggests setting OLLAMA_HOST=0.0.0.0, but that exposes an API without authentication on every address of the server. Use one of these two safe setups instead:
| Setup | When to use it | How the connection works |
|---|---|---|
| A: Ollama in the same Compose project | New server, or you are happy to run Ollama in Docker | Open WebUI talks to http://ollama:11434 on a private Docker network; Ollama's port is not published at all |
| B: Ollama on the host | Ollama is already installed as a systemd service | Open WebUI uses host networking, listens on 127.0.0.1:3000 and reaches Ollama at http://127.0.0.1:11434 |
Both setups keep Ollama's API private and publish Open WebUI on loopback only, so Caddy is the only public entry point.
Step 2 — Create the project directory and secrets
Create a directory for the project and an .env file with a fixed secret key. Open WebUI signs login sessions with WEBUI_SECRET_KEY; a fixed value keeps users logged in when the container is recreated.
sudo mkdir -p /opt/open-webui && sudo chown $USER:$USER /opt/open-webui
cd /opt/open-webui
echo "WEBUI_SECRET_KEY=$(openssl rand -hex 32)" > .env
echo "WEBUI_URL=https://chat.example.com" >> .env
chmod 600 .envReplace chat.example.com with your domain. WEBUI_URL tells Open WebUI its public address; the documentation asks you to set it before the first start.
Step 3 — Write the Compose file
Create /opt/open-webui/compose.yaml for the setup you chose. Both variants use the standard ghcr.io/open-webui/open-webui:main image and store all chats, users and settings in a named volume called open-webui.
A: Ollama in Compose
services:
ollama:
image: ollama/ollama
volumes:
- ollama:/root/.ollama
restart: unless-stopped
open-webui:
image: ghcr.io/open-webui/open-webui:main
depends_on:
- ollama
ports:
- "127.0.0.1:3000:8080"
environment:
OLLAMA_BASE_URL: "http://ollama:11434"
WEBUI_SECRET_KEY: "${WEBUI_SECRET_KEY}"
WEBUI_URL: "${WEBUI_URL}"
CORS_ALLOW_ORIGIN: "${WEBUI_URL};http://localhost:3000"
volumes:
- open-webui:/app/backend/data
restart: unless-stopped
volumes:
ollama:
name: ollama
open-webui:
name: open-webuiB: Ollama on the host
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
network_mode: host
environment:
HOST: "127.0.0.1"
PORT: "3000"
OLLAMA_BASE_URL: "http://127.0.0.1:11434"
WEBUI_SECRET_KEY: "${WEBUI_SECRET_KEY}"
WEBUI_URL: "${WEBUI_URL}"
CORS_ALLOW_ORIGIN: "${WEBUI_URL};http://localhost:3000"
volumes:
- open-webui:/app/backend/data
restart: unless-stopped
volumes:
open-webui:
name: open-webuiIn variant A, Ollama has no ports entry, so it is reachable only from containers in this project. In variant B, network_mode: host shares the host's network with the container. Open WebUI's start script reads HOST and PORT (defaults 0.0.0.0 and 8080), so the two lines bind it to 127.0.0.1:3000 instead of every address. A ports section is ignored with host networking, which is why variant B has none. CORS_ALLOW_ORIGIN lists every address users open the interface from: your HTTPS domain and the SSH tunnel used in Step 5.
If the server has an NVIDIA GPU and you use variant A, install the NVIDIA driver and the NVIDIA Container Toolkit (Steps 1 and 2 of How to install vLLM), then give the ollama service access to the GPU by adding this block under ollama:, at the same indentation as image::
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]Step 4 — Start the stack and load a model
Start the containers and watch the first start-up; Open WebUI prepares its database and bundled models on the first run, which can take a few minutes:
cd /opt/open-webui
docker compose up -d
docker compose ps
docker compose logs -f open-webuiPress Ctrl+C to stop following the logs. Check that the interface answers on loopback:
curl -I http://127.0.0.1:3000You should see HTTP/1.1 200 OK. Now make sure Ollama has at least one model. In variant A, pull it inside the Ollama container; in variant B, use the ollama command on the host:
docker compose exec ollama ollama pull llama3.2In variant B, run ollama pull llama3.2 instead and check curl http://127.0.0.1:11434/api/tags lists it.
Step 5 — Create the administrator account privately
On a fresh instance, the first account that registers becomes the administrator. Open WebUI's security documentation advises completing this setup over a private network, a VPN or a local port before the instance is reachable from the internet. Because Open WebUI only listens on 127.0.0.1, use an SSH tunnel from your own computer:
ssh -L 3000:127.0.0.1:3000 user@203.0.113.10Keep the session open, browse to http://localhost:3000, and create your account with a strong password. This account is the administrator. After the first registration, sign-up is disabled automatically; open the admin panel's settings and confirm that Enable New Sign Ups is switched off. If you turn sign-up on later, new accounts get the pending role by default and need your approval before they can use anything.
Still in the tunnel, choose a model in the model selector and send a test message. If the list is empty, open Admin Panel, then Settings and Connections, and check that the Ollama API URL is http://ollama:11434 (variant A) or http://127.0.0.1:11434 (variant B).
Step 6 — Publish Open WebUI over HTTPS with Caddy
Add a site block for your domain to /etc/caddy/Caddyfile. Caddy obtains a certificate automatically and proxies WebSocket connections, which Open WebUI uses for live updates, without extra configuration:
chat.example.com {
reverse_proxy 127.0.0.1:3000
}Reload Caddy and make sure the firewall only allows SSH and web traffic:
sudo systemctl reload caddy
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verboseOpen https://chat.example.com, log in with your administrator account and send a message. If you use Nginx or Traefik instead, follow Nginx with Certbot or Traefik and make sure the Upgrade and Connection headers are forwarded for WebSockets.
Back up and restore
The open-webui volume holds the database (chats, users, settings), uploaded files and generated content. Back it up together with compose.yaml and .env; without the same WEBUI_SECRET_KEY, restored sessions are invalid. Stop the container first so the database is consistent:
sudo mkdir -p /opt/backups && sudo chown $USER:$USER /opt/backups
cd /opt/open-webui
docker compose stop open-webui
docker run --rm -v open-webui:/data -v /opt/backups:/backup alpine tar czf /backup/openwebui-$(date +%F).tar.gz /data
docker compose start open-webui
cp compose.yaml .env /opt/backups/Models in the ollama volume (variant A) can be pulled again, so they do not need a backup. To restore, stop the container, empty the volume and extract the archive. The command deletes the current volume contents, so check the file name first:
cd /opt/open-webui
docker compose stop open-webui
docker run --rm -v open-webui:/data -v /opt/backups:/backup alpine sh -c "rm -rf /data/* && tar xzf /backup/openwebui-YYYY-MM-DD.tar.gz -C /"
docker compose start open-webuiCopy the backups off the server as well, for example with rsync or to object storage.
Update Open WebUI
Read the release notes on the Open WebUI releases page and take a backup first: database migrations run automatically on start-up and are one-way, so an older version may not work with a migrated database. Then pull the new images and recreate the containers:
cd /opt/open-webui
docker compose pull
docker compose up -d
docker image pruneIf you pinned a version tag, change it in compose.yaml before docker compose pull. To roll back after a schema change, restore the backup taken before the update and pin the older tag. Clear your browser cache after an update if the interface looks broken.
Troubleshooting
No models appear in the model selector
Open WebUI cannot reach Ollama or Ollama has no models. In variant A, run docker compose exec ollama ollama list; in variant B, run systemctl status ollama and curl http://127.0.0.1:11434/api/tags on the host. Check the Ollama URL under Admin Panel, Settings, Connections. A URL with host.docker.internal does not work while Ollama listens on 127.0.0.1; use one of the setups from Step 1.
Logs show an origin that is not an accepted origin
The browser opened Open WebUI from an address missing in CORS_ALLOW_ORIGIN, and WebSocket connections are refused. Add every address users use, separated by semicolons, then run docker compose up -d.
Changing an environment variable has no effect
Many settings, including ENABLE_SIGNUP, DEFAULT_USER_ROLE and WEBUI_URL, are persistent: the value stored in the database after the first start wins over the environment. Change them in the admin panel, or start once with ENABLE_PERSISTENT_CONFIG=false so environment variables take precedence.
Everyone is logged out after recreating the container
WEBUI_SECRET_KEY was missing or changed. Make sure .env contains the key and that compose.yaml passes it to the container, then log in again.
Caddy returns 502 Bad Gateway
Open WebUI is not listening on 127.0.0.1:3000 yet. Run docker compose ps and docker compose logs open-webui; the first start can take several minutes. In variant B, check that HOST and PORT are set and that nothing else uses port 3000 (sudo ss -ltnp | grep 3000).
Next steps
- Learn more about models and memory in How to install Ollama.
- Add an OpenAI-compatible backend such as llama.cpp server or vLLM as an extra connection.
- Build document chat and agents with AnythingLLM.
- Compare servers for a private chat interface on the Open WebUI hosting page.
- Read the official documentation at https://docs.openwebui.com for every setting.
Frequently asked questions
Why can’t Open WebUI in Docker reach Ollama on the host?
Ollama listens on 127.0.0.1 by default, and host.docker.internal points to the host’s Docker bridge address, not to its loopback interface. Either run Ollama in the same Compose project or run Open WebUI with host networking, as this guide shows, instead of opening Ollama on all addresses.
Who becomes the administrator?
The first account created on a fresh instance is promoted to administrator, and sign-up is then disabled automatically. Create that account through an SSH tunnel before you publish the site, or set WEBUI_ADMIN_EMAIL and WEBUI_ADMIN_PASSWORD before the first start.
Why does everyone get logged out after an update?
Open WebUI signs sessions with WEBUI_SECRET_KEY. If the key is not set, a new one can be generated when the container is recreated, which ends all sessions. Set a fixed key in .env as shown here and keep it.
Can Open WebUI use OpenAI-compatible APIs as well as Ollama?
Yes. Besides Ollama, you can add OpenAI-compatible endpoints such as vLLM, llama.cpp server or LocalAI under Connections in the admin settings.
Which image tag should I use?
The documentation uses ghcr.io/open-webui/open-webui:main as the standard image and recommends pinned version tags such as vX.Y.Z for production. Pinned tags never change, so updates happen only when you edit the tag.