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.
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/databehaves differently from a named volume for permissions and backup; the tar command above assumes the named volume. - Old images accumulate.
docker image prunereclaims 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=trueremoves old images automatically, which quietly deletes that rollback option.
Sources
Related
Install Open WebUI With Docker: Setup Guide
How to install Open WebUI with Docker: which image tag to run, the volume that holds everything, GPU flags, the first admin account, and safe updates.
Open WebUI vs LibreChat: Which to Self-Host
A documentation-level comparison of Open WebUI and LibreChat: install footprint, configuration model, model connections, retrieval and licensing terms.
Open WebUI Not Connecting to Ollama? 4 Causes and Fixes
Fix an empty Open WebUI model list by checking Ollama's bind address, Docker's host URL, saved connection settings, and endpoint timeouts.