# 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.

Difficulty: Intermediate\
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13

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 `sudo` rights; see [Secure a new Linux server](/guides/secure-a-new-linux-server) and [Set up SSH keys](/guides/ssh-keys).
- Docker Engine with the Compose plugin: follow [Install Docker on Ubuntu](/guides/install-docker-ubuntu) or [Install Docker on Debian](/guides/install-docker-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](/guides/caddy-reverse-proxy).
- Optional: Ollama already installed on the host from [How to install Ollama](/guides/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](/guides/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.

```bash
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 .env
```

Replace `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**

```yaml
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-webui
```
**B: Ollama on the host**

```yaml
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-webui
```

In 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](/guides/install-vllm)), then give the `ollama` service access to the GPU by adding this block under `ollama:`, at the same indentation as `image:`:

```yaml
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
```

> **Tip**
>
> For production, replace `:main` with a pinned release tag such as `ghcr.io/open-webui/open-webui:vX.Y.Z`. Take the current version from the Open WebUI releases page on GitHub. Pinned tags never change, so the container only updates when you change the tag.

## 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:

```bash
cd /opt/open-webui
docker compose up -d
docker compose ps
docker compose logs -f open-webui
```

Press `Ctrl+C` to stop following the logs. Check that the interface answers on loopback:

```bash
curl -I http://127.0.0.1:3000
```

You 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:

```bash
docker compose exec ollama ollama pull llama3.2
```

In 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:

```bash
ssh -L 3000:127.0.0.1:3000 user@203.0.113.10
```

Keep 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.

> **Tip**
>
> For automated deployments, you can set `WEBUI_ADMIN_EMAIL` and `WEBUI_ADMIN_PASSWORD` in `.env` and pass them to the container before the very first start. Open WebUI then creates the administrator at start-up and refuses other registrations. The variables only take effect while the database has no users.

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:

```caddyfile
chat.example.com {
    reverse_proxy 127.0.0.1:3000
}
```

Reload Caddy and make sure the firewall only allows SSH and web traffic:

```bash
sudo systemctl reload caddy
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
```

Open `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](/guides/nginx-reverse-proxy-certbot) or [Traefik](/guides/traefik-reverse-proxy) and make sure the `Upgrade` and `Connection` headers are forwarded for WebSockets.

> **Warning**
>
> Do not publish Open WebUI with `-p 3000:8080` or `"3000:8080"` without `127.0.0.1`. Docker-published ports bypass ufw, so the instance would be reachable over plain HTTP from the internet, before you have created the administrator account.

## 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:

```bash
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:

```bash
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-webui
```

Copy 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:

```bash
cd /opt/open-webui
docker compose pull
docker compose up -d
docker image prune
```

If 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](/guides/install-ollama).
- Add an OpenAI-compatible backend such as [llama.cpp server](/guides/llama-cpp-server) or [vLLM](/guides/install-vllm) as an extra connection.
- Build document chat and agents with [AnythingLLM](/guides/install-anythingllm).
- Compare servers for a private chat interface on the [Open WebUI hosting](/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.

---

Source: <https://hyperdc.com/guides/tutorials/open-webui-ollama>\
Updated: 2026-10-09
