-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
264 lines (246 loc) · 12.7 KB
/
Copy pathdocker-compose.yml
File metadata and controls
264 lines (246 loc) · 12.7 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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# ==============================================================================
# MORGANA + CAULDRON + GRIMOIRE + RUNE + ALEMBIC - DOCKER COMPOSE
# ==============================================================================
# Architecture:
# - morgana: Backend SignalR + API (port 5001)
# - cauldron: Rich Web reference channel, Blazor Server (port 5002)
# - grimoire: Rich TTY reference channel, CLI over webhook (port 5004)
# - rune: Basic TTY reference channel, CLI over webhook (port 5003)
# - alembic: Authoring workbench, Blazor Server (port 5005), not a channel: talks to no
# Morgana instance and joins no network below
# - Dedicated bridge network for internal communication
# - Persistent volume for SQLite databases
services:
# ============================================================================
# MORGANA - BACKEND (SignalR + Akka.NET + Microsoft.Agents.AI)
# ============================================================================
morgana:
build:
context: .
dockerfile: Morgana/Morgana.Dockerfile
args:
VERSION: ${MORGANA_VERSION}
image: morgana:${MORGANA_VERSION}
container_name: morgana
ports:
- "5001:5001"
environment:
# ASP.NET Core
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:5001
# Authentication (JWT) - per-issuer keys (3 is harness, which isn't dockerized)
- Morgana__Authentication__Issuers__0__Name=cauldron
- Morgana__Authentication__Issuers__0__SymmetricKey=${JWT_SYMMETRIC_KEY}
- Morgana__Authentication__Issuers__1__Name=grimoire
- Morgana__Authentication__Issuers__1__SymmetricKey=${JWT_SYMMETRIC_KEY}
- Morgana__Authentication__Issuers__2__Name=rune
- Morgana__Authentication__Issuers__2__SymmetricKey=${JWT_SYMMETRIC_KEY}
- Morgana__Authentication__Issuers__4__Name=morgana
- Morgana__Authentication__Issuers__4__SymmetricKey=${JWT_SYMMETRIC_KEY}
# Conversation persistence (SQLite)
- Morgana__ConversationPersistence__EncryptionKey=${ENCRYPTIONKEY}
- Morgana__ConversationPersistence__StoragePath=/app/data
# LLM Provider (anthropic, azureopenai, ollama, openai)
# Tiers are keyed by name: "Efficiency" (E-core — Morgana's own framework actors and
# any agent handling routine work) and "Performance" (P-core — reserved for agents
# whose author declares an existential need for deep reasoning/expressive power).
# Ollama defaults to a single Efficiency entry (see Morgana.Web/appsettings.json) — add a
# Performance entry too only if you actually keep two distinct local models loaded.
# See Morgana.Web/appsettings.json for the MagicDust pricing baked into the image per
# tier; these env vars only override the tier -> model/deployment name mapping and
# provider credentials. Every value falls back to its appsettings.json sentinel
# placeholder when the env var is unset: an unset variable would otherwise inject an
# EMPTY string, silently defeating Morgana's fail-fast placeholder check at startup and
# deferring the failure to the first real LLM call.
- Morgana__LLM__Provider=${LLM_PROVIDER:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__Anthropic__ApiKey=${ANTHROPIC_APIKEY:-_SECURE_OVERRIDE_}
- Morgana__LLM__Anthropic__Tiers__Efficiency__Options__ModelId=${ANTHROPIC_MODEL_EFFICIENCY:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__Anthropic__Tiers__Performance__Options__ModelId=${ANTHROPIC_MODEL_PERFORMANCE:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__ApiKey=${AZUREOPENAI_APIKEY:-_SECURE_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__Endpoint=${AZUREOPENAI_ENDPOINT:-_SECURE_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__Tiers__Efficiency__Options__ModelId=${AZUREOPENAI_DEPLOYMENTNAME_EFFICIENCY:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__Tiers__Performance__Options__ModelId=${AZUREOPENAI_DEPLOYMENTNAME_PERFORMANCE:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__Ollama__Endpoint=${OLLAMA_ENDPOINT:-_SECURE_OVERRIDE_}
- Morgana__LLM__Ollama__Tiers__Efficiency__Options__ModelId=${OLLAMA_MODEL:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__OpenAI__ApiKey=${OPENAI_APIKEY:-_SECURE_OVERRIDE_}
- Morgana__LLM__OpenAI__Tiers__Efficiency__Options__ModelId=${OPENAI_MODEL_EFFICIENCY:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__OpenAI__Tiers__Performance__Options__ModelId=${OPENAI_MODEL_PERFORMANCE:-_FUNCTIONAL_OVERRIDE_}
volumes:
# Persistent volume for SQLite databases
- morgana-data:/app/data
networks:
- morgana-network
# ============================================================================
# CAULDRON - FRONTEND (Blazor Server UI)
# ============================================================================
cauldron:
build:
context: .
dockerfile: Channels/Cauldron/Cauldron.Dockerfile
args:
VERSION: ${CAULDRON_VERSION}
image: cauldron:${CAULDRON_VERSION}
container_name: cauldron
ports:
- "5002:5002"
environment:
# ASP.NET Core
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:5002
# Authentication (JWT) - same symmetric key as Morgana
- Cauldron__Authentication__SymmetricKey=${JWT_SYMMETRIC_KEY}
# Morgana (Backend URL)
- Cauldron__MorganaURL=http://morgana:5001
# Widget embedding allowlist (CSP frame-ancestors), one indexed entry per origin.
# Closed by default: with none set only Cauldron's own pages may frame it, so the
# widget runs on /widget/morgana.html but on no external site until listed here.
# - Cauldron__Widget__AllowedEmbedOrigins__0=https://www.example.com
# - Cauldron__Widget__AllowedEmbedOrigins__1=https://shop.example.com
depends_on:
- morgana
networks:
- morgana-network
# ============================================================================
# GRIMOIRE - FRONTEND (Rich TTY over webhook, Spectre.Console TUI)
# ============================================================================
# Profile-gated: `compose up` does NOT start Grimoire (Spectre.Console
# needs to own the terminal — running it as a daemon also blocks port 5004 for
# the interactive TUI). `compose run <service>` auto-activates the service's
# profiles, so the documented invocation below works without `--profile tui`.
# Note: Rune and Grimoire are mutually exclusive at runtime (only one process
# can own stdin/stdout at a time); pick whichever capability profile you want
# to exercise per session.
#
# Interactive usage (TUI owns the terminal):
# docker compose --env-file .env --env-file .env.versions run --rm --service-ports --use-aliases grimoire
# `--use-aliases` is required: `compose run` does not register the service name
# as a network alias by default, so without it Morgana's webhook callback to
# http://grimoire:5004/morgana-hook fails DNS resolution.
grimoire:
profiles: ["tui"]
build:
context: .
dockerfile: Channels/Grimoire/Grimoire.Dockerfile
args:
VERSION: ${GRIMOIRE_VERSION}
image: grimoire:${GRIMOIRE_VERSION}
container_name: grimoire
ports:
- "5004:5004"
stdin_open: true
tty: true
environment:
# ASP.NET Core
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:5004
# Authentication (JWT) - same symmetric key as Morgana
- Grimoire__Authentication__SymmetricKey=${JWT_SYMMETRIC_KEY}
# Morgana (Backend URL + webhook callback)
- Grimoire__MorganaURL=http://morgana:5001
- Grimoire__CallbackURL=http://grimoire:5004/morgana-hook
depends_on:
- morgana
networks:
- morgana-network
# ============================================================================
# RUNE - FRONTEND (Basic TTY over webhook, Spectre.Console TUI)
# ============================================================================
# Profile-gated: `compose up` does NOT start Rune (Spectre.Console needs to own
# the terminal — running it as a daemon also blocks port 5003 for the
# interactive TUI). `compose run <service>` auto-activates the service's
# profiles, so the documented invocation below works without `--profile tui`.
# Note: Rune and Grimoire are mutually exclusive at runtime (only one process
# can own stdin/stdout at a time); pick whichever capability profile you want
# to exercise per session.
#
# Interactive usage (TUI owns the terminal):
# docker compose --env-file .env --env-file .env.versions run --rm --service-ports --use-aliases rune
# `--use-aliases` is required: `compose run` does not register the service name
# as a network alias by default, so without it Morgana's webhook callback to
# http://rune:5003/morgana-hook fails DNS resolution.
rune:
profiles: ["tui"]
build:
context: .
dockerfile: Channels/Rune/Rune.Dockerfile
args:
VERSION: ${RUNE_VERSION}
image: rune:${RUNE_VERSION}
container_name: rune
ports:
- "5003:5003"
stdin_open: true
tty: true
environment:
# ASP.NET Core
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:5003
# Authentication (JWT) - same symmetric key as Morgana
- Rune__Authentication__SymmetricKey=${JWT_SYMMETRIC_KEY}
# Morgana (Backend URL + webhook callback)
- Rune__MorganaURL=http://morgana:5001
- Rune__CallbackURL=http://rune:5003/morgana-hook
depends_on:
- morgana
networks:
- morgana-network
# ============================================================================
# ALEMBIC - AUTHORING WORKBENCH (Blazor Server UI)
# ============================================================================
# Profile-gated: `compose up` does NOT start Alembic and the reason is not the
# terminal-ownership one that gates the TUI channels. Alembic is not part of a
# running Morgana at all — it is the workbench where a domain is authored, it
# talks to no Morgana instance and it joins no network here. Starting it
# alongside the pipeline would only occupy a port for an unrelated application.
#
# Usage:
# docker compose --env-file .env --env-file .env.versions --profile authoring up alembic
#
# Note the LLM block below declares Performance only: Alembic writes dispositive
# prose, which is exactly where the Efficiency die fails and it runs once per
# onboarding rather than per turn. A single-tier deployment therefore does not
# serve it (no cross-tier fallback, by design).
alembic:
profiles: ["authoring"]
build:
context: .
dockerfile: Alembic/Alembic.Dockerfile
args:
VERSION: ${ALEMBIC_VERSION}
image: alembic:${ALEMBIC_VERSION}
container_name: alembic
ports:
- "5005:5005"
environment:
# ASP.NET Core
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:5005
# LLM Provider — same section name as Morgana's (Morgana:LLM), because Alembic
# consumes the framework's own provider abstraction rather than reimplementing it.
# Same unset-variable caveat as the morgana service above: every value falls back
# to its appsettings.json sentinel placeholder so a missing override fails fast
# instead of injecting an empty string.
- Morgana__LLM__Provider=${LLM_PROVIDER:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__Anthropic__ApiKey=${ANTHROPIC_APIKEY:-_SECURE_OVERRIDE_}
- Morgana__LLM__Anthropic__Tiers__Performance__Options__ModelId=${ANTHROPIC_MODEL_PERFORMANCE:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__ApiKey=${AZUREOPENAI_APIKEY:-_SECURE_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__Endpoint=${AZUREOPENAI_ENDPOINT:-_SECURE_OVERRIDE_}
- Morgana__LLM__AzureOpenAI__Tiers__Performance__Options__ModelId=${AZUREOPENAI_DEPLOYMENTNAME_PERFORMANCE:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__Ollama__Endpoint=${OLLAMA_ENDPOINT:-_SECURE_OVERRIDE_}
- Morgana__LLM__Ollama__Tiers__Performance__Options__ModelId=${OLLAMA_MODEL:-_FUNCTIONAL_OVERRIDE_}
- Morgana__LLM__OpenAI__ApiKey=${OPENAI_APIKEY:-_SECURE_OVERRIDE_}
- Morgana__LLM__OpenAI__Tiers__Performance__Options__ModelId=${OPENAI_MODEL_PERFORMANCE:-_FUNCTIONAL_OVERRIDE_}
# ==============================================================================
# VOLUMES
# ==============================================================================
volumes:
# SQLite database persistence (conversations + agent threads)
morgana-data:
driver: local
# ==============================================================================
# NETWORKS
# ==============================================================================
networks:
# Dedicated bridge network for internal container communication
morgana-network:
driver: bridge