Open WebUI deployment with RAG, private web search, OCR, local TTS, and MCP tool servers.
Includes a curated library of tools, filters, and function pipes, pushed automatically on every deploy via the internal API.
Provides standalone docker-compose.yml and a production-ready Docker Swarm docker-stack-compose.yml.
For single-host / Docker Compose deployments:
git clone https://github.com/BitWise-0x/open-webui-ultimate-stack && cd open-webui-ultimate-stack && ./bootstrap.shbootstrap.sh copies env examples, generates secrets, validates your configuration, and starts the stack. Open WebUI will be available at http://localhost:3000.
For additional deployment details, including Docker Swarm, see the Deployment section below.
graph TD
User["👤 User / Browser"]
subgraph Core
owui["<b>openwebui</b><br>ghcr.io/open-webui/open-webui:main<br>:8080 → :3000"]
db["<b>db</b><br>pgvector/pgvector:pg17<br>:5432"]
redis["<b>redis</b><br>valkey/valkey:9-alpine<br>:6379"]
end
subgraph Search & Documents
searxng["<b>searxng</b><br>searxng/searxng<br>:8080 → :8888"]
tika["<b>tika</b><br>apache/tika:3.2.3.0-full<br>:9998"]
end
subgraph AI Integrations
edgetts["<b>edgetts</b><br>openai-edge-tts<br>:5050"]
mcpo["<b>mcposerver</b><br>ghcr.io/open-webui/mcpo<br>:8000"]
end
subgraph Automation
tools["<b>tools-init</b><br>python:3.12-slim<br>one-shot"]
end
User -->|":3000"| owui
owui --> db
owui --> redis
owui --> searxng
owui --> tika
owui --> edgetts
owui --> mcpo
searxng --> redis
mcpo --> db
tools -.->|"API push on deploy"| owui
open-webui-ultimate-stack/
├── docker-compose.yml Standalone: local / single-host
├── docker-stack-compose.yml Docker Swarm: production
├── .env.example Top-level variables (STACK_NAME, DATA_ROOT, TIKA_TAG, etc.)
├── .gitignore
├── bootstrap.sh Setup, secrets generation, validation, and deployment
├── scripts/
│ ├── deploy-swarm.sh Swarm deploy: network, volumes, conf sync, deploy
│ ├── remove-swarm.sh Swarm teardown (preserves data volumes)
│ └── install-tools.sh Auto-push tools/filters/pipes via REST API
├── conf/
│ ├── wait-for-services.sh TCP dependency gate for Swarm services
│ ├── searxng/ settings.yml, uwsgi.ini, limiter.toml
│ ├── tika/ tika-config.xml + Tesseract OCR properties
│ ├── mcposerver/ config.json.example (template; config.json gitignored)
│ ├── postgres/init/ Custom entrypoint: pgvector init + auto-upgrade
│ └── tools/
│ ├── filters/ Python pipeline filters (auto-deployed)
│ ├── tools/ Python tool definitions (auto-deployed)
│ ├── functions/ Python pipes and functions (auto-deployed)
│ └── extras/ ComfyUI API workflows and sample data
├── docs/
│ ├── post-config.md Post-deployment manual configuration guide
│ └── passwordreset.md Emergency password reset runbook
├── env/ Per-service env.example files
│ ├── owui.env.example
│ ├── db.env.example
│ ├── edgetts.env.example
│ ├── mcp.env.example
│ ├── searxng.env.example
│ └── tools-init.env.example
└── README.md
| File | Purpose |
|---|---|
.env |
Top-level: STACK_NAME, DATA_ROOT, ROUTER_NAME, ROOT_DOMAIN, BACKEND_NETWORK_NAME, TIKA_TAG, REDIS_DATA_ROOT |
env/owui.env |
Open WebUI: LLM keys, RAG, websocket, TTS, image gen, CORS, permissions |
env/db.env |
PostgreSQL credentials (POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD) |
env/searxng.env |
SearXNG secret, workers, base URL |
env/edgetts.env |
Default voice, speed, format |
env/mcp.env |
DATABASE_URL for mcpo proxy |
env/tools-init.env |
Admin credentials used by tools-init to authenticate and push tools on every deploy |
All passwords default to change_me and are auto-generated by bootstrap.sh on first run. The postgres password is synced across env/db.env, env/owui.env, env/mcp.env, and conf/mcposerver/config.json automatically.
| Directory | Purpose |
|---|---|
conf/searxng/ |
SearXNG search engine settings, uWSGI workers, and rate limiter config |
conf/tika/ |
Tika OCR config — tune Tesseract behavior via customocr/ properties |
conf/mcposerver/ |
MCP-to-OpenAPI proxy config — config.json.example is the template; config.json is generated on first run and gitignored |
conf/postgres/init/ |
Custom PostgreSQL entrypoint that auto-creates and upgrades the pgvector extension on every container start |
Single entry point for both standalone and Swarm deployments. Handles the full setup lifecycle:
- Copies
env/*.env.examplefiles toenv/*.env(skips existing) - Generates cryptographic secrets for
WEBUI_SECRET_KEY,SEARXNG_SECRET, andPOSTGRES_PASSWORD - Syncs the postgres password into all files that reference it (
owui.env,mcp.env,mcposerver/config.json) - Validates required configuration (admin email/password, Swarm-specific vars)
- Syncs admin credentials from
env/owui.envintoenv/tools-init.env - Starts the stack (
docker compose up -dfor standalone, or callsdeploy-swarm.shfor Swarm)
./bootstrap.sh # Standalone (Docker Compose)
./bootstrap.sh --swarm # Docker SwarmSafe to re-run — skips existing env files and only regenerates secrets that are still set to change_me.
Called by bootstrap.sh --swarm. Handles Swarm-specific infrastructure setup:
- Validates
DATA_ROOTis mounted and reachable - Creates service data directories on the shared filesystem with correct ownership
- Generates
POSTGRES_PASSWORDif still set tochange_me(with volume-exists safety check) - Generates
SEARXNG_SECRETandWEBUI_SECRET_KEYif needed - Creates the overlay network using the CIDR from
FORWARDED_ALLOW_IPS - Creates external volumes (
postgresdata,searxngcache) - Syncs
conf/directories toDATA_ROOTvia rsync (tools, postgres init, searxng, tika, mcposerver) - Injects the postgres password into
mcposerver/config.jsonusing Python (handles special characters) - Sets directory ownership (
999:999for postgres/redis,977:977for searxng) - Deploys the stack with
docker stack deploy
Runs inside the tools-init container on every deploy. Authenticates with Open WebUI via the REST API and pushes all Python files from conf/tools/ (filters, tools, and function pipes) with upsert support — creates new items or updates existing ones.
Removes the Swarm stack while preserving external volumes and the overlay network. Prints instructions for manual cleanup if needed.
POSIX-compatible TCP dependency gate for Docker Swarm. Since Swarm does not support depends_on, this script blocks service startup until all specified host:port pairs are reachable via TCP, then execs into the real entrypoint.
Used by:
- searxng — waits for
redis:6379 - mcposerver — waits for
db:5432 - tools-init — waits for
openwebui:8080
Auto-detects the TCP check method (nc, python3, or python). Configurable via WAIT_TIMEOUT (default: 120s) and WAIT_INTERVAL (default: 2s). The tools-init service overrides WAIT_TIMEOUT=300 because Open WebUI's first boot (DB migrations + function module loading + frontmatter pip installs) can run several minutes before port 8080 is reachable.
Custom PostgreSQL entrypoint that wraps the official docker-entrypoint.sh:
- Removes stale
postmaster.pid(safe for Swarm rescheduling after crash) - Starts the official entrypoint in the background
- Waits for PostgreSQL to accept connections (up to 300s)
- Creates the pgvector (
vector) extension if it doesn't exist - Upgrades the extension to match the installed shared library version
- Forwards
SIGTERM/SIGINT/SIGQUITto the postgres process
Uses docker-compose.yml with local volumes, depends_on health checks, and ports exposed to the host.
Set these before running:
| File | Variable | Description |
|---|---|---|
env/owui.env |
WEBUI_ADMIN_EMAIL |
Admin account email |
env/owui.env |
WEBUI_ADMIN_PASSWORD |
Admin password (uppercase, lowercase, digit, special char, 8+ chars) |
env/owui.env |
OLLAMA_BASE_URL |
Optional — your Ollama instance URL |
env/owui.env |
OPENAI_API_KEY |
Optional — your OpenAI API key |
Note:
env/tools-init.envmust have matchingOWUI_ADMIN_EMAILandOWUI_ADMIN_PASSWORD—bootstrap.shsyncs them automatically fromenv/owui.envwhenever the values differ.
Then run:
./bootstrap.shOpen WebUI will be available at http://localhost:3000. SearXNG is exposed on http://localhost:8888 for optional direct access.
Uses docker-stack-compose.yml with external overlay network, external named volumes, bind mounts from a shared filesystem (DATA_ROOT), and wait-for-services.sh as a TCP dependency gate (Swarm does not support depends_on).
Set these before running:
| File | Variable | Description |
|---|---|---|
.env |
STACK_NAME |
Stack name (default: open-webui) |
.env |
DATA_ROOT |
Shared filesystem path accessible from all Swarm nodes (GlusterFS, NFS, etc.) |
.env |
ROUTER_NAME |
Subdomain for CORS and Traefik labels (e.g. openwebui) |
.env |
ROOT_DOMAIN |
Base domain for CORS and Traefik labels (e.g. yourdomain.com) |
.env |
BACKEND_NETWORK_NAME |
Overlay network name (default: open-webui_backend) |
.env |
TIKA_TAG |
Apache Tika version (default: 3.2.3.0) |
.env |
REDIS_DATA_ROOT |
Optional — separate high-IOPS mount for Redis data (defaults to DATA_ROOT) |
env/owui.env |
WEBUI_ADMIN_EMAIL |
Admin account email |
env/owui.env |
WEBUI_ADMIN_PASSWORD |
Admin password (uppercase, lowercase, digit, special char, 8+ chars) |
env/owui.env |
OLLAMA_BASE_URL |
Optional — your Ollama instance URL |
env/owui.env |
OPENAI_API_KEY |
Optional — your OpenAI API key |
env/owui.env |
FORWARDED_ALLOW_IPS |
Overlay subnet CIDR — deploy-swarm.sh uses this to create the network (e.g. 10.0.13.0/24) |
env/searxng.env |
SEARXNG_BASE_URL |
Set to http://searxng:8080/ for Swarm (standalone default http://localhost:8888/ won't work) |
Note:
WEBUI_ADMIN_EMAILandWEBUI_ADMIN_PASSWORDmust match in bothenv/owui.envandenv/tools-init.env.bootstrap.sh --swarmsyncs them automatically whenever the values differ.
Then run:
./bootstrap.sh --swarmSafe to re-run on redeploy or update — re-syncs conf/ to DATA_ROOT and redeploys the stack without touching existing secrets or data volumes.
Local repo Shared filesystem (DATA_ROOT)
───────────── ─────────────────────────────
conf/tools/ ──rsync──► open-webui/tools/
conf/postgres/init/ ──rsync──► open-webui/postgres/init/
conf/searxng/ ──rsync──► open-webui/searxng/conf/
conf/tika/ ──rsync──► open-webui/tika/conf/
conf/mcposerver/ ──rsync──► open-webui/mcposerver/conf/
conf/wait-for-services.sh ──cp──► open-webui/scripts/wait-for-services.sh
scripts/install-tools.sh ──cp──► open-webui/tools/install-tools.sh
The deploy script also creates the overlay network (from FORWARDED_ALLOW_IPS CIDR), external volumes, sets directory ownership, injects the postgres password into mcposerver/config.json, and runs docker stack deploy.
docker stack ps ${STACK_NAME:-open-webui}
docker service logs -f ${STACK_NAME:-open-webui}_openwebuiRemove stack (preserves data volumes by default):
./scripts/remove-swarm.shTo also remove data volumes after removal (destroys all data):
docker volume rm ${STACK_NAME:-open-webui}_postgresdata ${STACK_NAME:-open-webui}_searxngcache
docker network rm ${BACKEND_NETWORK_NAME:-open-webui_backend}| Feature | Standalone (docker-compose.yml) |
Swarm (docker-stack-compose.yml) |
|---|---|---|
| Orchestration | Docker Compose | Docker Swarm |
| Service dependencies | depends_on with health checks |
wait-for-services.sh TCP gate |
| Volumes | Local named volumes | Bind mounts from DATA_ROOT + external named volumes |
| Networking | Bridge network | Overlay network with configurable subnet |
| Exposed ports | 3000 (WebUI), 8888 (SearXNG) |
None — use a reverse proxy (Traefik labels included, commented) |
| Replicas | 1 per service | 2 for openwebui, 1 for all others |
| Restart policy | unless-stopped |
on-failure with max attempts |
| Config files | Mounted directly from ./conf/ |
Synced via rsync to shared filesystem |
| CORS | Not configured | CORS_ALLOW_ORIGIN set from ROUTER_NAME.ROOT_DOMAIN |
Once the stack is running, some settings require manual configuration via the Admin Panel. See the Post-Configuration Guide for:
- MCP connections (GitHub, gitmcp.io) via native Streamable HTTP
- Enabling native function calling (agentic mode) per model
- Environment variables and API keys for third-party services
- Filter activation and Valve configuration
- ComfyUI workflow imports and model setup
- Function pipe and tool Valve tuning
The tools, filters, and function pipes bundled in conf/tools/ were authored primarily by
Haervwe from the
open-webui-tools project.
Additional contributions by: tan-yong-sheng, pupphelper, Zed Unknown, and justinrahb.
All tools retain their original author metadata in their docstring headers.
Read the full write-up: The Open WebUI Ultimate Stack: A Production Deployment for the LLM Interface Era — covers architecture, deployment, and the full suite of bundled tools, filters, and function pipes.
MIT License: see LICENSE for details.