Open WebUI HQ
Isometric 3D scene of a robotic crane lifting a cyan shipping container above a dark server-like Docker platform.
Operations

How to Update Open WebUI Container: Docker Guide

How to update the Open WebUI container without losing chats: back up the volume, pull, recreate, pin a version tag, and roll back when a release breaks.

By Open WebUI HQ Editorial · · 5 min read

An Open WebUI container that has been up since spring is still running spring’s image. :main is a rolling tag, so docker ps keeps reporting a healthy container for months while the code underneath it goes stale and bug reports come back with “upgrade first.” Working out how to update open webui container is really three decisions, and none of them is the pull command: where your data actually lives, which image tag you are tracking, and what happens when a release runs a database migration you cannot reverse. Open WebUI v0.11.3, published on 31 August 2026, exists partly because of that third one. The release notes record that a failed database upgrade used to start the application anyway and surface later as a missing table or column such as chat.timer_at, which was the upgrade failure people hit after moving from 0.11.0, 0.11.1 or 0.11.2.

Back up the volume before you touch the image

Everything worth keeping lives in one named Docker volume mounted at /app/backend/data: accounts, chat history, uploaded files, the vector store, and the SQLite database. The container is disposable. The volume is not. Docker’s own documentation is blunt about the split: a volume’s contents “exist outside the lifecycle of a given container,” and when a container is destroyed the writable layer goes with it, so anything that was never on a volume is gone.

The Open WebUI docs give a one-liner that tars the volume out to the host:

docker run --rm -v open-webui:/data -v $(pwd):/backup \
  alpine tar czf /backup/openwebui-$(date +%Y%m%d).tar.gz /data

Run that before every update, not just the ones that look risky. The docs are explicit that restoring deletes everything in the volume before extracting the archive, so the backup is your only path back once a migration has run. If you are not sure your data is on a volume at all, docker volume ls and docker inspect open-webui will tell you whether /app/backend/data is a named volume, a bind mount, or nothing.

How to update the Open WebUI container by hand

The manual path is three commands. Removing the container is safe as long as the volume exists and you are not passing -v to the remove.

docker rm -f open-webui
docker pull ghcr.io/open-webui/open-webui:main
docker run -d -p 3000:8080 -v open-webui:/app/backend/data \
  -e WEBUI_SECRET_KEY="your-secret-key" \
  --name open-webui --restart always \
  ghcr.io/open-webui/open-webui:main

The WEBUI_SECRET_KEY line is the one people skip and then file a support thread about. Without a persistent value there, every session token is invalidated when the container is recreated and every user is logged out after each update. Generate one once with openssl rand -hex 32 and keep it in your compose file or an env file. The rest of the flags have to match your original run command exactly, which is the real argument against the manual path: docker run has no memory, so any flag you forget silently changes the deployment. If you are still on a hand-rolled run command, the Docker install guide covers what each flag is doing before you commit it to a compose file.

Docker Compose: the version you actually want

Compose stores the flags for you, which turns the update into two commands that are hard to get wrong:

docker compose pull
docker compose up -d

A minimal service definition:

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    ports:
      - "3000:8080"
    volumes:
      - open-webui:/app/backend/data
    environment:
      - WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
    restart: always

volumes:
  open-webui:

docker compose up -d recreates only what changed. If the image digest moved but Compose decides the config is identical, --force-recreate will “recreate containers even if their configuration and image haven’t changed,” and --pull always folds the pull into the same command. Both are documented flags on docker compose up, so you can collapse the update to docker compose up -d --pull always.

Watchtower, and where it stops being a good idea

Open WebUI documents Watchtower for people who would rather not remember. The docs give a one-shot form and a resident form that polls on an interval:

# one-shot: update once and exit
docker run --rm --volume /var/run/docker.sock:/var/run/docker.sock \
  <watchtower-image> --run-once open-webui

# resident: check every six hours
docker run -d --name watchtower --restart unless-stopped \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  <watchtower-image> --interval 21600 open-webui

Take the image name from the Open WebUI updating guide rather than from an older tutorial. The docs now point at a community-maintained fork instead of the image most write-ups still show, so a copied command from 2024 may pull something that no longer gets updates.

Two operational notes before you run either form. WATCHTOWER_CLEANUP=true removes superseded images automatically, which also deletes the fastest rollback you have. And look at what the command mounts: /var/run/docker.sock hands that container control of the Docker daemon, which on a normal host is equivalent to root. Automatic updates on an LLM front end that runs tool calls and ingests documents you did not write is a wider blast radius than it is on a media server, and the attack surface of an LLM front end is a different shape. The Open WebUI docs make the same point in milder terms: automated updates can break a deployment when a release carries breaking changes or database migrations, so read the release notes and keep a backup before letting anything update itself.

Pin a version instead of chasing :main

:main is the recommended tag and it moves whenever the project ships. The quick-start docs also list :dev for nightly builds, :main-slim for a smaller image that downloads Whisper and embedding models on first use, :cuda for Nvidia GPU support, :ollama for the bundled all-in-one image, and version tags in :vX.Y.Z, :X.Y.Z and :X.Y form plus :git-<commit-sha> for an exact commit. On anything you would be annoyed to lose, pin a version tag and update deliberately after reading the release notes.

Rollback is then changing the tag back and restarting, with one hard limit. The docs state that database migrations are one-way: if the version you moved to ran a migration, reverting the container does not undo it, and you are restoring from the backup instead. That single sentence is the reason the backup step comes first in this guide rather than last.

What a healthy update looks like

Good: docker compose up -d recreates the container, docker logs -f open-webui shows migrations running and then the server binding on 8080, the login page loads without asking you to sign in again, and Settings reports the new version. Bad: the container enters a restart loop, or it starts but the interface errors on a missing table or column, which is the stale-schema signature from the migration bug fixed in 0.11.3. Check docker logs before assuming the update worked, because a container can be “up” and still be serving a broken schema.

For anything past a single-user homelab, the update is not finished when the container is healthy. Retrieval behaviour and model routing both change across releases, and whether answer quality moved after an upgrade is an ordinary model monitoring question rather than a Docker one. Keep a handful of known prompts you can re-run after each update.

Caveats

  • Update every instance at the same time in multi-instance deployments. The docs state that rolling updates are not supported across a release that changes the database schema.
  • A bind mount such as -v ./data:/app/backend/data behaves differently from a named volume for permissions and backup; the tar command above assumes the named volume.
  • Old images accumulate. docker image prune reclaims the space, but do it after you are satisfied with the new version, not before, since a local older image is the fastest rollback you have.
  • Watchtower with WATCHTOWER_CLEANUP=true removes old images automatically, which quietly deletes that rollback option.

Sources

  1. Open WebUI documentation: Updating Open WebUI
  2. Open WebUI documentation: Quick Start
  3. Open WebUI v0.11.3 release notes
  4. Docker documentation: Volumes
  5. Docker documentation: docker compose up

Related