Open WebUI is easier to maintain as a small Docker Compose project than as a one-off container command. The Compose file keeps the image, published port, restart policy, secret key, and persistent data volume in one place for local servers and repeatable lab deployments.
The service uses the official ghcr.io/open-webui/open-webui:main image, publishes the container's port 8080 on host port 3000, and stores backend data in a named volume mounted at /app/backend/data. A .env file keeps the port and WEBUI_SECRET_KEY outside the YAML so the same Compose file can be reused on another host.
Use docker compose with a space, which is the current Compose v2 syntax. Keep the WEBUI_SECRET_KEY value stable after users sign in, because changing it can invalidate sessions; back up the named volume before updates, migrations, or host rebuilds.
Related: How to run Open WebUI with Docker
Related: How to update Open WebUI in Docker
Related: How to set WEBUI_SECRET_KEY in Open WebUI
Steps to run Open WebUI with Docker Compose:
- Create a project directory for Open WebUI.
$ mkdir -p ~/open-webui
- Change into the project directory.
$ cd ~/open-webui
- Generate a long secret key for the .env file.
$ openssl rand -hex 32 f6b7d7c9b92c04c9496244e2c5ef9b541545d73bdf1f62f02c3ce5e9e62f6d89
Use a fresh value from your own terminal. Do not rotate WEBUI_SECRET_KEY casually after accounts and sessions exist.
- Create the Compose environment file.
COMPOSE_PROJECT_NAME=open-webui OPEN_WEBUI_PORT=3000 WEBUI_SECRET_KEY=replace-with-the-secret-from-openssl
- Create the Compose file.
services: open-webui: image: ghcr.io/open-webui/open-webui:main restart: unless-stopped ports: - "${OPEN_WEBUI_PORT:-3000}:8080" environment: WEBUI_SECRET_KEY: "${WEBUI_SECRET_KEY:?set WEBUI_SECRET_KEY in .env}" volumes: - open-webui:/app/backend/data volumes: open-webui:The named volume keeps Open WebUI accounts, chats, settings, and uploaded data outside the container layer.
- Confirm that Compose resolves the service name.
$ docker compose config --services open-webui
- Confirm that Compose resolves the image name.
$ docker compose config --images ghcr.io/open-webui/open-webui:main
- Pull the current Open WebUI image.
$ docker compose pull Image ghcr.io/open-webui/open-webui:main Pulling Image ghcr.io/open-webui/open-webui:main Pulled
- Start Open WebUI and wait for the image healthcheck to pass.
$ docker compose up -d --wait Network open-webui_default Created Volume open-webui_open-webui Created Container open-webui-open-webui-1 Started Container open-webui-open-webui-1 Healthy
If your Compose plugin does not support –wait, run docker compose up -d and repeat the next status check until STATUS includes (healthy).
- Check the running service and published port.
$ docker compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS open-webui-open-webui-1 ghcr.io/open-webui/open-webui:main "bash start.sh" open-webui 40 seconds ago Up 38 seconds (healthy) 0.0.0.0:3000->8080/tcp, [::]:3000->8080/tcp
- Confirm that Compose created the persistent volume.
$ docker volume ls DRIVER VOLUME NAME local open-webui_open-webui
Do not run docker compose down -v unless you intend to remove the Open WebUI data volume.
- Request the Open WebUI health endpoint.
$ curl -i -sS http://127.0.0.1:3000/health HTTP/1.1 200 OK date: Fri, 03 Jul 2026 01:01:46 GMT server: uvicorn content-length: 15 content-type: application/json x-process-time: 0 {"status":true}Open the mapped port in a browser after the health endpoint returns a true status. The first account created on a fresh Open WebUI instance becomes the initial administrator.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.