Repository navigation
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
89 lines (84 loc) · 3.4 KB
/
Copy pathdocker-compose.yml
File metadata and controls
89 lines (84 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Open WebUI — Hardened Docker Compose (single service)
# Self-hosted LLM front-end: https://github.com/open-webui/open-webui
#
# Architecture (1 service):
# - openwebui — ghcr.io/open-webui/open-webui (Python/FastAPI app,
# bundles SQLite for chat history + ChromaDB for RAG)
#
# Note on dependencies: Open WebUI itself needs nothing external. To
# actually chat, point it at a model provider — either an Ollama
# instance (on the host, in another container, or remote) or an
# external API key (OpenAI, Anthropic, etc.). See README for examples.
#
# Security baseline (verified by test, May 2026):
# - Runs as ${PUID}:${PGID} (no root). Port 8080 is unprivileged.
# cap_drop: ALL with ZERO cap_add — verified healthy under test.
# - security_opt: no-new-privileges; ipc: private
# - tmpfs for ephemeral writes; deploy.resources limits incl. pids
# - 127.0.0.1 port binding — reverse proxy in front for TLS
# - Healthcheck via the built-in /health endpoint
# - WEBUI_SECRET_KEY pinned via .env so sessions survive restarts
#
# Setup:
# cp .env.example .env && fill WEBUI_SECRET_KEY (openssl recipe in the file)
# docker network create openwebui-front
# mkdir -p data
# docker compose up -d
name: openwebui
services:
openwebui:
image: ghcr.io/open-webui/open-webui:0.9.5
container_name: openwebui
restart: unless-stopped
user: "${PUID:-1000}:${PGID:-1000}"
ports:
# localhost-only — front with a reverse proxy for public TLS.
- "127.0.0.1:${OWUI_PORT:-8071}:8080"
environment:
# CRITICAL: signs session cookies. Losing this logs everyone out
# but doesn't lose data; leaking it lets attackers forge sessions.
WEBUI_SECRET_KEY: ${WEBUI_SECRET_KEY:?secret key required}
WEBUI_AUTH: ${WEBUI_AUTH:-true}
TZ: ${TZ:-Europe/Bratislava}
# env_file pulls in optional OLLAMA_BASE_URL, OPENAI_API_KEY,
# OAUTH_* (Authentik SSO), etc. without forcing them to be set.
env_file:
- .env
volumes:
- ./data:/app/backend/data
networks:
- openwebui-front
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
ipc: private
tmpfs:
- /tmp:size=256m
deploy:
resources:
limits:
# Open WebUI loads a sentence-transformers embedding model on
# first boot (~100 MB). Bump if you enable image generation
# or local RAG with large documents.
memory: 2g
cpus: "2.0"
pids: 300
reservations:
memory: 512m
cpus: "0.25"
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8080/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 90s
# ═══════════════════════════════════════════════════════════════════════════
# NETWORKS
# ═══════════════════════════════════════════════════════════════════════════
networks:
# External bridge: reverse proxy reaches openwebui via 127.0.0.1 port
# binding; also gives openwebui internet egress for external model
# providers (OpenAI, Anthropic) and the embedding-model download.
openwebui-front:
external: true