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)

KomponenteVersion / SpecRolle
Open WebUIghcr.io/open-webui/open-webui@sha256:e045bde3b004cc7f8c319412345eb56c87ea6ac57031534a31ca37ad5424beb3 (v0.9.5, Digest-pinned)Chat-UI + MCP-Host + Bedrock-Adapter
DBSQLite auf EFS-Volume in /app/backend/data/webui.db (Default). Optional PostgreSQL via DATABASE_URL wenn 10+ User produktivConversations + Users + Settings. Open WebUI nutzt Peewee ORM — KEIN MongoDB-Support, anders als LibreChat
LiteLLM-Proxyghcr.io/berriai/litellm:main-stable als Sidecar im Task, port 4000 internPflicht — Open WebUI hat keinen nativen Bedrock-Support. LiteLLM uebersetzt Bedrock-API in OpenAI-Format, nutzt TaskRole-IAM.
cloudflaredcloudflare/cloudflared@sha256:... Digest-gepinntTunnel-Sidecar, einziger Public-Eingang
Bedrock-Regioneu-central-1 (Frankfurt)LLM (DSGVO-Default)
Bedrock-IDseu.anthropic.claude-{opus-4-7,sonnet-4-6,haiku-4-5} (CRIS-Profile, niemals nackte anthropic.*-IDs)Modelle
MCP-Transportstreamable-http (Open WebUI native seit v0.6.31)Alle MCP-Server, kein stdio
AuthMicrosoft Entra OpenID (5+ User) ODER eingebaute Email-Auth (Pilot 2-3 User)First user = super admin
StorageEFS fuer Mongo-Volume, S3 EU (oder Cloudflare R2 EU) fuer File-UploadsPersistenz
ComputeAWS 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 seinbedrock/ 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-hosted als 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-hosted fuer Video-Gen analog

Details: bedrock-eu-image-gen-limitation.

Decision-Forks

ForkEmpfehlungWenn anders
DB-BackendSQLite auf EFS (Default, ~4 €/Mo EFS) — reicht bis ~20 Usern produktivPostgreSQL self-hosted im selben Task oder Aurora Serverless v2 (~50 €/Mo) wenn 20+ User parallel
File-Uploads-StorageS3 EU im av-production (KMS-encrypted, eigene Bucket pro Kunde)Cloudflare R2 EU (~3 €/Mo guenstiger, separater Vendor)
AuthMicrosoft Entra OpenID bei 5+ UserEmail-Reg + MFA bei 2-3 User Pilot, spaeter wechseln
MCP-Server-Anzahl1 hosted Mono-MCP pro Kunde (analog mcp-vf-hosted)Pro Tool eigener Endpoint nur wenn Compliance es verlangt
Image-Genmcp-replicate-hosted als 2. Endpointnichts (Kunden ohne Image-Gen-Bedarf)
Bedrock-Regioneu-central-1 (Frankfurt)NIEMALS us-* fuer DSGVO-Kunden ohne explizite DPIA

Bekannte Quirks (Pflicht-Mitigation)

QuirkMitigationQuelle
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 BootLive-Erfahrung 2026-05-12 + Peewee Docs
Datenbank-Migration bei v0.8.0 / v0.9.0 upgrades kann lange dauernBackup vor Upgrade, ausreichend Downtime einplanen, KEIN Rolling-Update bei Multi-Worker-Setupv0.8.0, v0.9.0 release notes
Bedrock-Modell-IDs ohne Region-Prefix scheiternimmer eu.anthropic.claude-... (oder us.), nie nackte anthropic.claude-...AWS Bedrock-Doku
MCP-Streamable-HTTP-only — kein stdiomcpo-Proxy fuer Legacy-stdio-MCPs, oder eigene MCPs gleich streamable-http bauenOpen WebUI MCP Docs
Pipelines-Architektur fuer Bedrock erfordert mehr Setup als bei LibreChatInitial-Setup Aufwand +0.5 Tag vs LibreChat-BedrockErfahrung
SQLite-File auf EFS — Lock-Contention bei vielen parallelen WritesBei 5+ User parallel kann SQLite Lock-Timeouts geben. Mitigation: Postgres-Migration vor User-Wachstum, ECS-Task in derselben AZ wie EFS-Mount-TargetSQLite-Doku + Erfahrung
Open WebUI braucht NODE_OPTIONS bei groesseren WorkloadsNODE_OPTIONS=--max-old-space-size=2048 als Env-VarOS-Issues
First-User = Super-Admin automatischInitial-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=trueexplizit 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: true

Cost-Tabelle (3-5 User, Lean-Pilot, all-AWS)

PostenEUR/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_HEADERS ist 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.