Open WebUI + AWS Fargate + Bedrock + Streamable-HTTP-MCP
Standard-Pattern fuer Team-Chat-Setups bei DACH-Mittelstands-Kunden ab Mai 2026. Loest librechat-railway-multiuser ab — Begruendung siehe Abschnitt „Warum Open WebUI statt LibreChat” am Ende.
Wann dieses Pattern
- 2-30 User in einer Org
- DSGVO-Anforderung „alles in EU” (Bedrock EU als LLM-Backend)
- Vorhandene MCPs sollen direkt nutzbar sein (Papierkram, TicketPAY, M365, etc.) ueber streamable-http
- Image-Gen optional ueber externe MCP (Replicate, Runway) — Bedrock-EU bietet das NICHT nativ
Fuer Solo-User auf eigenem Mac: weiter claude-dsgvo-setup. Fuer Custom-Tier-Kunden mit existierendem M365-Tenant: dieses Pattern + delegated-OAuth-Refactor als Folge-Sprint.
Stack-Komponenten (gepinnt, Stand 2026-05-12)
| Komponente | Version / Spec | Rolle |
|---|---|---|
| Open WebUI | ghcr.io/open-webui/open-webui@sha256:e045bde3b004cc7f8c319412345eb56c87ea6ac57031534a31ca37ad5424beb3 (v0.9.5, Digest-pinned) | Chat-UI + MCP-Host + Bedrock-Adapter |
| DB | SQLite auf EFS-Volume in /app/backend/data/webui.db (Default). Optional PostgreSQL via DATABASE_URL wenn 10+ User produktiv | Conversations + Users + Settings. Open WebUI nutzt Peewee ORM — KEIN MongoDB-Support, anders als LibreChat |
| LiteLLM-Proxy | ghcr.io/berriai/litellm:main-stable als Sidecar im Task, port 4000 intern | Pflicht — Open WebUI hat keinen nativen Bedrock-Support. LiteLLM uebersetzt Bedrock-API in OpenAI-Format, nutzt TaskRole-IAM. |
| cloudflared | cloudflare/cloudflared@sha256:... Digest-gepinnt | Tunnel-Sidecar, einziger Public-Eingang |
| Bedrock-Region | eu-central-1 (Frankfurt) | LLM (DSGVO-Default) |
| Bedrock-IDs | eu.anthropic.claude-{opus-4-7,sonnet-4-6,haiku-4-5} (CRIS-Profile, niemals nackte anthropic.*-IDs) | Modelle |
| MCP-Transport | streamable-http (Open WebUI native seit v0.6.31) | Alle MCP-Server, kein stdio |
| Auth | Microsoft Entra OpenID (5+ User) ODER eingebaute Email-Auth (Pilot 2-3 User) | First user = super admin |
| Storage | EFS fuer Mongo-Volume, S3 EU (oder Cloudflare R2 EU) fuer File-Uploads | Persistenz |
| Compute | AWS ECS Fargate eu-central-1, av-production-Account oder av-<kunde> | nach aws-multi-account-strategie |
Architektur
flowchart TB Users["3-10 User<br/>(Browser, claude.ai-aehnliche UI)"] subgraph CF["Cloudflare Edge + Tunnel"] CFE["Edge: TLS + WAF + Rate<br/>chat.<kunde>.de"] CFT["Tunnel <id>.cfargotunnel.com"] end subgraph Fargate["AWS Fargate Task (av-production, eu-central-1, ARM64)"] CFS["cloudflared (Sidecar)"] OWUI["open-webui v0.9.5<br/>:8080<br/>SQLite intern"] end subgraph EFS["AWS EFS"] VOL[("Persistent Volume<br/>/app/backend/data<br/>webui.db + Configs"))] end subgraph S3["AWS S3 eu-central-1"] FILES[("uploads/, KMS-encrypted")] end subgraph Bedrock["AWS Bedrock eu-central-1"] Claude["Claude 4.x via eu.anthropic.* CRIS"] end subgraph MCP1["mcp-vf-hosted (eigener Stack)"] VFM["streamable-http<br/>mcp-vf.agenticventures.de/mcp"] end subgraph MCP2["mcp-replicate-hosted (optional, Image-Gen)"] RPM["streamable-http<br/>replicate.agenticventures.de/mcp"] end Users -->|HTTPS| CFE CFE --> CFT CFT -.->|outbound QUIC| CFS CFS -->|localhost:8080| OWUI OWUI --> VOL OWUI --> FILES OWUI -->|Bedrock Converse API + IAM Role| Claude OWUI -->|streamable-http<br/>+ X-User-Email Headers<br/>+ OAuth Bearer| VFM OWUI -->|streamable-http| RPM
Kern-Mechanik: User-Identität durch den Stack
Anders als LibreChat (das eigene Header-Substitution-Syntax {{LIBRECHAT_USER_ID}} nutzt) hat Open WebUI seit v0.8 einen sauberen ENV-Switch: ENABLE_FORWARD_USER_INFO_HEADERS=true schickt automatisch User-Identity an alle MCP-Server. Default-Header:
X-OpenWebUI-User-Id: <uuid>
X-OpenWebUI-User-Email: <email>
X-OpenWebUI-User-Name: <display-name>
X-OpenWebUI-User-Role: <admin|user>
X-OpenWebUI-Chat-Id: <chat-uuid>
X-OpenWebUI-Message-Id: <message-uuid>
Optional via USER_INFO_HEADER_*-Env-Vars custom Header-Namen (z.B. fuer Bedrock AgentCore-Kompatibilitaet).
Im MCP (mcp-vf-hosted oder kuenftige hosted-MCPs) bedeutet das:
- Audit-Log per Tool-Call mit echter User-Email statt nur JWT-Subject-Hash
- Rate-Limiting per User statt nur per Subject
- Per-User-Scope-Filterung wenn der MCP das unterstuetzt (Andre sieht andere Daten als Christoph)
Wichtig: das ist additiv zur Scalekit-OAuth-Auth. Scalekit-JWT bleibt das Auth-Token (signiert + audience-validated), die Forward-Headers sind die Identity-Layer obendrauf. Beide laufen parallel.
Bedrock-Anbindung via LiteLLM-Sidecar
Open WebUI hat keinen nativen Bedrock-Support (Architektur-Philosophie: nur OpenAI-API-compat im Core). Bedrock-Models muss ueber LiteLLM-Proxy als Sidecar laufen. LiteLLM uebersetzt Bedrock-API zu OpenAI-API-Format und nutzt die Fargate-TaskRole fuer Bedrock-Auth.
Stack-Konfiguration
// LiteLLM-Sidecar als 2. Container im Task
taskDef.addContainer('litellm', {
image: ecs.ContainerImage.fromRegistry('ghcr.io/berriai/litellm:main-stable'),
entryPoint: ['/bin/sh', '-c'],
command: [`cat > /tmp/config.yaml <<EOF
model_list:
- model_name: claude-sonnet-4-6
litellm_params:
model: bedrock/eu.anthropic.claude-sonnet-4-6
aws_region_name: eu-central-1
# ...
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
EOF
exec litellm --config /tmp/config.yaml --port 4000 --host 0.0.0.0`],
secrets: { LITELLM_MASTER_KEY: ecs.Secret.fromSecretsManager(masterKey) },
});
// Open WebUI zeigt auf LiteLLM via OpenAI-API-Endpoint
owuiContainer.addEnvironment('OPENAI_API_BASE_URLS', 'http://localhost:4000/v1');
owuiContainer.addSecret('OPENAI_API_KEYS', ecs.Secret.fromSecretsManager(masterKey));IAM
TaskRole braucht bedrock:InvokeModel + bedrock:Converse + bedrock:*Stream auf * (CRIS-Profile resolven zu Multi-Region-Model-ARNs, lassen sich nicht enumerieren).
Modelle in Admin-UI freischalten
Nach Stack-Deploy zeigt GET /api/models die 3 LiteLLM-Modelle automatisch. Im Admin-Panel → Settings → Connections → die OpenAI-Connection (auf localhost:4000) ist schon konfiguriert, Modelle erscheinen. Optional: Per-Modell-Whitelist via /api/v1/configs/models.
Bedrock-Modell-IDs in LiteLLM-Config MUESSEN mit bedrock/eu.anthropic.claude-... praefixed sein — bedrock/ ist der LiteLLM-Provider-Prefix, eu. ist das CRIS-Region-Prefix.
Alternativen (wenn LiteLLM nicht passt)
- AWS Bedrock Access Gateway (aws-samples): AWS-official, weniger Features, single-purpose
- Bedrock Mantle: native AWS, aber nur open-weight models (kein Claude)
- Custom Pipeline-Container: Open WebUIs Pipelines-Architektur fuer extreme Anpassung
LiteLLM ist Standard-Wahl: ausgereift, multi-purpose, gleichzeitig OpenAI/Anthropic/Bedrock/Azure-Adapter.
MCP-Anbindung (streamable-http)
Im Admin-UI → Settings → Tools → Add MCP Server → Type: MCP (Streamable HTTP):
Server URL: https://mcp-vf.agenticventures.de/mcp
Auth: OAuth 2.1 (Authorization Server: scalekit.dev/...)
Open WebUI macht den OAuth-Discovery via /.well-known/oauth-protected-resource, redirected den User zum Scalekit-Login, persistiert das Token pro User. Bei jedem Tool-Call: Bearer + Forward-User-Info-Headers werden geschickt.
Nicht-streamable-http MCPs: ueber mcpo als OpenAPI-Proxy wrappen. Aber: wir bauen alle eigenen MCPs ab 2026-04 sowieso streamable-http (siehe mcp-hosting-fargate-tunnel).
Image-Generation
Bedrock-EU hat keine Image-Gen-Models (Stand 2026-05). Nova Canvas, Stable Diffusion, Stable Image Ultra sind alle nur us-Regions. Folge: kein DSGVO-konformes „alles in EU” mit nativem Bedrock-Image-Gen.
Loesung: Image-Gen via MCP-Server.
mcp-replicate-hostedals separater hosted MCP (Replicate.com hat Edge global incl. EU, AVV ist machbar)- User tippt im Chat „erstelle ein Bild von X” → LLM ruft
replicate_create_prediction(model="flux-1.1-pro")→ URL kommt zurueck → Open WebUI rendert das Bild inline - Plus
mcp-runway-hostedfuer Video-Gen analog
Details: bedrock-eu-image-gen-limitation.
Decision-Forks
| Fork | Empfehlung | Wenn anders |
|---|---|---|
| DB-Backend | SQLite auf EFS (Default, ~4 €/Mo EFS) — reicht bis ~20 Usern produktiv | PostgreSQL self-hosted im selben Task oder Aurora Serverless v2 (~50 €/Mo) wenn 20+ User parallel |
| File-Uploads-Storage | S3 EU im av-production (KMS-encrypted, eigene Bucket pro Kunde) | Cloudflare R2 EU (~3 €/Mo guenstiger, separater Vendor) |
| Auth | Microsoft Entra OpenID bei 5+ User | Email-Reg + MFA bei 2-3 User Pilot, spaeter wechseln |
| MCP-Server-Anzahl | 1 hosted Mono-MCP pro Kunde (analog mcp-vf-hosted) | Pro Tool eigener Endpoint nur wenn Compliance es verlangt |
| Image-Gen | mcp-replicate-hosted als 2. Endpoint | nichts (Kunden ohne Image-Gen-Bedarf) |
| Bedrock-Region | eu-central-1 (Frankfurt) | NIEMALS us-* fuer DSGVO-Kunden ohne explizite DPIA |
Bekannte Quirks (Pflicht-Mitigation)
| Quirk | Mitigation | Quelle |
|---|---|---|
| Open WebUI unterstuetzt MongoDB NICHT (Peewee ORM = SQLite/PostgreSQL/MySQL) | SQLite auf EFS-Volume default, Postgres erst bei 20+ User-Last. KEIN Mongo-Sidecar versuchen — RuntimeError: Unrecognized scheme: mongodb beim Boot | Live-Erfahrung 2026-05-12 + Peewee Docs |
| Datenbank-Migration bei v0.8.0 / v0.9.0 upgrades kann lange dauern | Backup vor Upgrade, ausreichend Downtime einplanen, KEIN Rolling-Update bei Multi-Worker-Setup | v0.8.0, v0.9.0 release notes |
| Bedrock-Modell-IDs ohne Region-Prefix scheitern | immer eu.anthropic.claude-... (oder us.), nie nackte anthropic.claude-... | AWS Bedrock-Doku |
| MCP-Streamable-HTTP-only — kein stdio | mcpo-Proxy fuer Legacy-stdio-MCPs, oder eigene MCPs gleich streamable-http bauen | Open WebUI MCP Docs |
| Pipelines-Architektur fuer Bedrock erfordert mehr Setup als bei LibreChat | Initial-Setup Aufwand +0.5 Tag vs LibreChat-Bedrock | Erfahrung |
| SQLite-File auf EFS — Lock-Contention bei vielen parallelen Writes | Bei 5+ User parallel kann SQLite Lock-Timeouts geben. Mitigation: Postgres-Migration vor User-Wachstum, ECS-Task in derselben AZ wie EFS-Mount-Target | SQLite-Doku + Erfahrung |
| Open WebUI braucht NODE_OPTIONS bei groesseren Workloads | NODE_OPTIONS=--max-old-space-size=2048 als Env-Var | OS-Issues |
| First-User = Super-Admin automatisch | Initial-Setup-Account bewusst mit Admin-User-Email machen (z.B. marvin@agenticventures.de) | Open WebUI Quickstart |
User-Headers werden nur an MCP geschickt wenn ENABLE_FORWARD_USER_INFO_HEADERS=true | explizit setzen, Default ist false (Privacy-by-Default) | v0.8 Release-Notes |
Pin-Liste (fuer Repo-Konstanten)
openwebui_image: "ghcr.io/open-webui/open-webui@sha256:e045bde3b004cc7f8c319412345eb56c87ea6ac57031534a31ca37ad5424beb3"
openwebui_version: "v0.9.5" # Stand 2026-05-12
db_backend: "sqlite-on-efs" # Open WebUI nutzt Peewee — KEIN MongoDB-Support
db_volume_path: "/app/backend/data"
db_file: "webui.db"
bedrock_region: "eu-central-1"
bedrock_models:
workhorse: "eu.anthropic.claude-sonnet-4-6"
heavy: "eu.anthropic.claude-opus-4-7"
cheap: "eu.anthropic.claude-haiku-4-5"
mcp_transport: "streamable-http"
auth_provider: "microsoft-entra-openid" # oder "email" fuer Pilot
storage_provider: "s3-eu-central-1"
forward_user_info_headers: trueCost-Tabelle (3-5 User, Lean-Pilot, all-AWS)
| Posten | EUR/Mo |
|---|---|
| Fargate-Task (1 vCPU / 3 GB x86, Open WebUI + LiteLLM + cloudflared, SQLite intern) | 35 € |
| EFS-Storage + Backup (~5 GB) | 4 € |
| S3-File-Uploads (~5 GB Pilot-Use) | 1 € |
| KMS-Keys (2 × $1) | 2 € |
| CloudWatch-Logs (3 Container) | 4 € |
| Cloudflare (Tunnel + DNS + Edge Free-Tier) | 0 € |
| Lean-Fix-Cost | ~46 € |
Plus:
- mcp-vf-hosted existing: 33 €/Mo
- Bedrock-API-Calls als Pass-Through: 50-300 €/Mo variabel je nach Nutzung
- Optionales mcp-replicate-hosted (Folge-Sprint): +33 €/Mo + Replicate-API-Pass-Through
Lean-Pilot fix (alle MCPs einberechnet): ~79 €/Mo, plus variable LLM/Image-API-Kosten.
Skalierungs-Pfad wenn der Pilot greift:
- Fargate-Task auf 2 vCPU/4 GB hochziehen — +25 €/Mo
- DocumentDB statt self-hosted Mongo wenn 10+ User produktiv — +55 €/Mo
- mcp-replicate-hosted dazuholen — +33 €/Mo + API
- WAF Pro statt Free wenn DDoS-Risk — +25 €/Mo
Im Worst-Case-Setup (15+ User, alle Features): ~250 €/Mo Fix + variable APIs.
DSGVO-Pflichtarbeit
- AVV zwischen Agentic Ventures (Auftragsverarbeiter) und Kunde (Verantwortlicher) — Subprozessoren: AWS EMEA SARL, Cloudflare Germany, Scalekit (EU), ggf. Replicate Inc., ggf. MongoDB Inc. (falls Atlas statt self-hosted)
- VVT-Eintrag beim Kunden mit Datenstandort eu-central-1
- Bedrock-AVV automatisch via AWS Global DPA seit 2023-04
- DPIA NICHT zwingend bei rein-EU-Region, nice-to-have
- Datenschutzhinweis falls Kunden-Endkunden-Daten in Tool-Calls fliessen
Ausfuehrlicher Compliance-Hintergrund: anthropic-datenschutz, claude-dsgvo-setup.
Warum Open WebUI statt LibreChat (Stand 2026-05-12)
- Community 5× groesser (124k vs 25k GitHub-Stars) → schnellere Bug-Response, mehr Plugins, langfristig wartungsaermer
- v0.8 (Feb 2026) hat LibreChat-Vorsprung-Features eingeholt: Analytics-Dashboard, Skills ($-Command analog claude.ai), Per-User-Resource-Sharing, Prompt-Version-Control, Open-Responses-Protocol fuer Claude-Extended-Thinking
- UX naeher an claude.ai: Channels statt Conversation-Branching, Skills statt Workflow-Prompts, Knowledge-Bases pro User/Group statt RAG-API
ENABLE_FORWARD_USER_INFO_HEADERSist sauberer als LibreChats{{LIBRECHAT_USER_*}}-Template-Substitution- Resource-Footprint schlanker (kein Pflicht-Meili, kein Pflicht-PGVector, RAG optional)
LibreChat bleibt valide fuer Setups wo:
- Mehrere LLM-Provider parallel ohne Pipelines-Workaround noetig sind
- Token-Cost-Tracking mit User-Balance-System (Credit-Pre-Pay) Kern-Requirement ist
- Eine YAML-Config bevorzugt wird gegenueber UI-driven Admin
Pattern-File fuer LibreChat bleibt erhalten (librechat-railway-multiuser) fuer Bestandskunden — KEINE neuen LibreChat-Setups mehr ohne expliziten Grund.
Related
- bedrock-eu-image-gen-limitation — warum Image-Gen ueber MCP, nicht Bedrock-nativ
- mcp-hosting-fargate-tunnel — Hosting-Pattern fuer eigene MCPs (gleicher Stack wie Open WebUI)
- librechat-railway-multiuser — Vorgaenger-Pattern, fuer Bestandskunden
- anthropic-datenschutz — DSGVO-Grundlagen
- llm-hosting-eu-optionen — EU-Hosting-Alternativen
- Open WebUI Docs — offizielle Doku
- Open WebUI Releases — Changelog