Quick fix
docker rm -f open-webui 2>/dev/null
docker run -d --name open-webui --restart always \
-p 3000:8080 \
-v open-webui:/app/backend/data \
ghcr.nju.edu.cn/open-webui/open-webui:main
# first boot takes ~2-3 minutes (embedding model warm-up); the page is unreachable during that time
If host port 3000 is taken, change the left side (e.g. 3001). Your data lives in the open-webui volume.
What you will run into
You follow a tutorial to deploy Open WebUI on Docker: docker pull ghcr.io/open-webui/open-webui spins until it times out; or the container finally starts, but localhost:3000 gives connection refused and keeps spinning; or it fails with port is already allocated and no container is created at all.
There is a sneakier one: it worked for days, then you delete and recreate the container — accounts, chat history and the knowledge base are gone.
The four symptoms (image pull stuck / port conflict / page not loading / data loss) have different root causes; each gets its own section below.
Why this happens
Short version: each path has a fixed break point — wrong image source, occupied host port, a 2-3 minute first boot, and a missing volume.
Break point 1: image source. The official image lives on ghcr.io, and direct pulls from mainland China are unstable. Measured locally (2026-09-24, WSL2 Ubuntu + Docker 29.1.3): a direct ghcr.io pull did not finish within a 25s limit (some layers completed, the process timed out); switching to the Nanjing University mirror ghcr.nju.edu.cn finished in 3m24s for a 1.66GB image.
Break point 2: host port. In -p 3000:8080 the 3000 is a host port, unique machine-wide. If another process or container holds it, Docker refuses to create the container: measured error failed to bind host port 0.0.0.0:3000/tcp: address already in use.
Break point 3: startup time. Container status Up does not mean the page is ready. On first boot Open WebUI prepares an embedding model inside the container (visible in logs as all-MiniLM-L6-v2); measured locally, it took 154 seconds from docker run to the first HTTP 200 — during that window the browser shows connection refused. Many people assume it is broken and delete the container, which restarts the clock.
Break point 4: the data volume. /app/backend/data holds webui.db (accounts, chats), uploads/ (documents) and vector_db/ (RAG vectors). Without -v, all of it lives in the container writable layer and docker rm wipes it. Measured with docker inspect: a container without a volume shows an empty Mounts array; a container with a volume keeps webui.db across recreation (647168 -> 684032 bytes).
Deterministic takeaway: pull stuck -> change the mirror; port error -> find who holds it; "won't start" -> check logs whether it is still booting (no Traceback means wait); before deleting a container, confirm docker inspect shows the mount.
Step by step
1. Pull stuck -> switch to the China ghcr mirror — Required (direct pulls are slow by default)
docker pull ghcr.nju.edu.cn/open-webui/open-webui:main
Measured: 3m24s for 1.66GB. Another option: pull once through a proxy to warm the cache, then run from the mirror.
2. Port occupied -> find the holder, then change the port — Required (host ports are unique)
docker ps | grep 3000 # an old container?
ss -tlnp | grep 3000 # a host process?
Old container: docker rm -f <name>; host process: stop it, or map a different host port (-p 3001:8080).
3. Container Up but page unreachable -> read the logs to tell "booting" from "crashed" — Check (90% of the time it is still booting)
docker ps --filter name=open-webui
docker logs --tail 50 open-webui
Log lines about installing dependencies or loading models mean it is still booting; wait for the first GET / HTTP/1.1" 200. A Traceback means it really crashed. To poll readiness from the shell:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/
4. Protect your data -> always mount a volume — Required (deleting containers is routine)
docker inspect open-webui --format '{{json .Mounts}}'
The output must contain "Destination":"/app/backend/data". To upgrade the image: docker rm -f open-webui and run the same docker run again — the volume (and your data) stays.
5. Connecting to host Ollama -> point at the host — By scenario
Inside a container localhost is the container itself; use host.docker.internal to reach host Ollama. See Open WebUI cannot connect to Ollama.
How to confirm it is fixed
docker psshows statusUp;curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/returns200(allow 2-3 minutes on first boot);docker inspect open-webui --format '{{json .Mounts}}'shows the volume mounted at/app/backend/data;docker exec open-webui ls /app/backend/datalistswebui.db.
Other environments
- Docker Desktop (Windows/macOS): open
http://localhost:3000after port mapping; the same image mirrors apply. Not reproduced on this machine (WSL2 + engine installed directly). - docker compose: write
ports,volumesandimageas above; port conflicts come from duplicated left-side values.
Symptoms
# Form 1: image pull timeout
Error response from daemon: ... context deadline exceeded (Client.Timeout exceeded while awaiting headers)
# Form 2: host port taken
docker: Error response from daemon: failed to set up container networking:
failed to bind host port 0.0.0.0:3000/tcp: address already in use
# Form 3: container Up but the browser cannot reach it (still booting; most common)
(browser) This site can't be reached / connection refused
# Form 4: after recreating the container, accounts, chats and knowledge base are gone
(page) back to the first-time signup wizardCause
Slow image source (direct ghcr.io), an occupied host port, a 2-3 minute first boot while the embedding model is prepared, and a data directory (/app/backend/data) that is not backed by a volume — one break point per symptom above.
Solution
- Switch to the mirror prefix:
ghcr.nju.edu.cn/open-webui/open-webui:main(measured 3m24s); - Port clash: locate with
docker ps/ss -tlnp, remove the old container or change the host port; - Page not loading: check
docker logswhether it is still booting, wait for the first 200 (measured 154s cold start); - Always add
-v open-webui:/app/backend/dataso recreation keeps your data; - Ollama connection issues: see open-webui-ollama-connect.
Verification Evidence
- Local measurement (2026-09-24, WSL2 Ubuntu + Docker 29.1.3, dedicated container and volume, no other containers touched):
- direct
ghcr.iopull unfinished within a 25s limit (some layers completed, exit code 124);ghcr.nju.edu.cnfinished in 3m24.222s, digestsha256:8b432fe0a65b91116afc7961365c6cca5379cc923171386a96691f3471f3cae9, size 1656076851 bytes; - with python3 holding host port 3000,
docker run -p 3000:8080failed withfailed to bind host port 0.0.0.0:3000/tcp: address already in use;-p 3300:8080then succeeded; - cold start to the first HTTP 200: 154s; container logs show the embedding model load (
all-MiniLM-L6-v2) and theuvicornstartup line; - volume run:
docker inspectshows the volume mounted at/app/backend/data; afterdocker rm -fand recreating against the same volume,webui.dbstill exists (647168 -> 684032 bytes); a container without a volume shows[]in Mounts;
Evidence details kept locally (2026-09-24)
- Tool-side material (2026-09-01, local repro log 2026-09-01): the ghcr.nju.edu.cn image path passed end to end (with real Ollama inference).
- Not reproduced: Docker Desktop (Windows/macOS) and compose forms (mechanism documented from container networking rules).
Related canonicals
Read in order: precondition -> same root / same domain / related:
- Precondition (rule out first):
- Cannot connect to the Docker daemon
- Same root / adjacent:
- docker pull failures / image mirrors
- port is already allocated
- Same domain (Open WebUI):
- Cannot connect to Ollama
- RAG knowledge base not working
- Forgot admin password
Applicable tools (2)
This problem is linked from the tool pages below — reachable from either side.
open-webuidockerSource & evidence
← Local LLM domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk