
pacod-demo betreibt Identität, das KI-Gateway, die Agentenplattform, das CMS, die Wissensdatenbank und die Benchmarks des Gateways gemeinsam auf einer Maschine, aus einer Konfigurationsdatei und mit einem make. Es bindet die Compose-Datei jedes Repositorys unverändert ein, teilt ihnen je eine Instanz jeder gemeinsamen Komponente zu, macht die Produkte miteinander bekannt und prüft, dass sie als Einheit funktionieren; jede Nacht kehrt es zu einem bekannten Stand zurück.
Der ganze Stack
- Lizenz: No licence file yet
- Version: 0.1.0 · Vorschau
- Geschrieben in: Shell, Python
- Tech-Stack: Docker Compose, Caddy, PostgreSQL, Qdrant, Prometheus, Grafana, OpenTelemetry, Mailpit, Playwright
- Auf GitHub ansehen · Issue eröffnen
- Live-Demo ausprobieren
Funktionen
Eine Startseite
Jedes Produkt mit einer Beschreibung, einem Screenshot und den Links zu seiner Verwaltung und seinen Websites, bei Tag oder bei Nacht.
Eine Anmeldung
Ein pacod-id-Realm für alle Produkte. Wer sich bei einem anmeldet, ist bei allen angemeldet.
Ein Gateway
Die Modellaufrufe aller Produkte laufen über pacod-gw, jedes mit eigenem Schlüssel. Ohne Anbieterschlüssel antwortet sein Mock-Anbieter, und nichts verlässt die Maschine.
Von allem eins
Ein Caddy, ein PostgreSQL, ein Qdrant, ein Embeddings-Dienst, ein Mail-Sammler und ein Monitoring-Stack, gemeinsam für alle Produkte.
Die eigenen Dateien der Repositorys
Die sechs Compose-Dateien werden unverändert eingebunden; ein kleines Overlay pro Repository setzt nur Adressen und Secrets und entfernt veröffentlichte Ports.
Jede Nacht zurückgesetzt
Standardmäßig um 05:00 UTC kehren die Daten aller Produkte zur Baseline zurück. Was geändert wurde, ist nach dem nächsten Zurücksetzen weg.
Dashboards und Mail
Grafana mit den Dashboards jedes Produkts, Prometheus für Ad-hoc-Abfragen und eine Ansicht für jede Mail, die der Stack versendet.
Als eine Plattform geprüft
make verify prüft den Edge, das interne Netz, Single Sign-on in fünf Produkte, die Gateway-Schlüssel der Produkte, die Wissensdatenbank, die Websites und den Benchmark.
Bereit für eine Domain
HTTPS mit einem Zertifikat für die Domain, ihre Subdomains und die Domain der Websites; über die Maschine hinaus veröffentlicht, schließen sich die Werkzeuge, die nur auf dem Laptop sicher sind.

Screenshots




Ausprobieren
Die Demo läuft auf demo.pacod.io, und ihre Startseite führt zu allem anderen: jedes Produkt mit einer Beschreibung, einem Screenshot und den Links zu seiner Verwaltung und seinen Websites. Jedes Produkt antwortet auf einer eigenen Subdomain, alle hinter einem Edge:
| Adresse | Was |
|---|---|
demo.pacod.io |
Die Startseite: jedes Produkt mit seinen Links |
app.demo.pacod.io |
Die Agentenplattform (pacod-ap): ihre Website, Chat und Admin-Konsole |
console.demo.pacod.io |
Die Gateway-Konsole (pacod-gw): Anbieter, Modelle, Schlüssel, Nutzung |
gw.demo.pacod.io/v1 |
Die OpenAI-kompatible API des Gateways, mit einem Gateway-Schlüssel |
studio.demo.pacod.io |
Das CMS-Studio (pacod-cms) |
cms.demo.pacod.io |
Demo Journal, eine CMS-Website; Demo Notes liegt unter minimal., Starward unter space. |
kb.demo.pacod.io |
Die Wissensdatenbank (pacod-kb) |
bench.demo.pacod.io |
Die Benchmarks des Gateways (pacod-benchmark): Suiten, Läufe, Vergleiche |
id.demo.pacod.io/admin |
Identitätsverwaltung (pacod-id) |
grafana.demo.pacod.io |
Die Dashboards aller Produkte |
mail.demo.pacod.io |
Jede Mail, die der Stack versendet |
prometheus.demo.pacod.io |
Die Metriken, für Ad-hoc-Abfragen |
Eine Anmeldung gilt für jedes Produkt: Wer sich bei einem anmeldet, ist bei allen angemeldet. Eine Registrierung gibt es nicht: Konten kommen vom Administrator und per Einladung, und ohne Konto stehen die Websites und die öffentlichen Seiten der Produkte allen offen. Grafana, Prometheus und die Mail-Ansicht fragen stattdessen nach E-Mail und Passwort des Admins. Jede Änderung macht das nächste nächtliche Zurücksetzen rückgängig.
Warum es das gibt
Jedes PACOD-Projekt läuft für sich, mit eigenen Kopien dessen, was es braucht: einer Datenbank, einem Edge, einer Anmeldung, einem Gateway. So probiert man eines am besten aus. So sind sie aber nicht für das Zusammenspiel gedacht, und so sieht man nicht, was sie zusammen ergeben.
pacod-demo macht es umgekehrt. Es stellt die sechs Produkte als eine Plattform auf eine Maschine, mit je einer Instanz jeder gemeinsamen Komponente, und zeigt, was erst im Zusammenspiel sichtbar wird: eine Anmeldung, die jedes Produkt anerkennt, ein Gateway, über das jeder Modellaufruf läuft und das sie alle bepreist, ein Benchmark, der genau dieses Gateway misst, und ein Satz Dashboards für den ganzen Stack. Es ist auch die Referenz dafür, wie die Produkte zusammengesetzt werden: Die Netzwerk- und Namenskonvention, auf der es beruht, docs/NETWORK.md, befolgt jedes Repository.
Wie es aufgebaut ist
Der Stack ist ein Compose-Projekt, pacod-demo: 42 Dienste, von denen zwei nur beim Start
einmal laufen und dann enden (43 mit der optionalen Ingestion).
| Aus | Was in der Demo läuft | Namen |
|---|---|---|
| pacod-id | Der Identitätsanbieter, mit einem Realm für alle Produkte | pacod-id |
| pacod-gw | Kern, Analytics, Konsole, Tester, ClickHouse, das Valkey des Antwort-Caches, der Mock-Anbieter sowie Last-Agent und Last-Mock seiner Lasttests | pacod-gw, gw-* |
| pacod-ap | API, Admin-API, MCP-Server, Worker, Frontend, Redis und pgbouncer, der gemeinsame Embeddings-Dienst und die Exporter seines Monitorings | ap-*, pacod-embeddings, die Exporter |
| pacod-cms | Die Websites, das Studio, MongoDB und Gotenberg | cms-* |
| pacod-kb | Die Pipeline und die Oberfläche | kb-* |
| pacod-benchmark | Die API und die Oberfläche | bench-* |
| pacod-demo | Caddy, PostgreSQL, Qdrant, Mailpit, Prometheus, Alertmanager, Grafana und der OpenTelemetry Collector | pacod-* |
- Zwei Netzwerke, eindeutige Namen. Jeder Container tritt dem externen Docker-Netzwerk
pacod-netunter einem Namen bei, der über alle Repositorys eindeutig ist: Gemeinsame Komponenten heißenpacod-*, alles andere trägt das Präfix seines Besitzers. Die Listener, die nur Server erreichen sollen, die Management-API des Gateways, der interne Listener von pacod-id und die API des Benchmarks, liegen in einem zweiten Netzwerk,pacod-admin-net, das intern ist (ohne Weg nach draußen). Jeder bindet an einen Alias, den es nur dort gibt, und nur ihre Aufrufer treten ihm bei. - Die eigenen Compose-Dateien der Repositorys. Jedes Repository teilt sein Compose-Setup in
eine App-Datei mit seinen eigenen Diensten und eine Standalone-Datei mit eigenen Kopien der
gemeinsamen Komponenten für den Einzelbetrieb.
compose.ymlbindet die sechs App-Dateien unverändert ein, dazu die Entwicklungs- und Lasttest-Dateien des Gateways. Ein kleines Overlay pro Repository entfernt nur veröffentlichte Ports, setzt die Secrets und öffentlichen Adressen der Demo und verweist Einstellungen auf die Dateien der Demo. - Von jeder gemeinsamen Komponente eine.
platform.ymlschreibt keine davon neu: Jede erweitert (extends) die Definition, die ein Repository bereits mitbringt, und übernimmt die Beiträge der Produkte aus derenplatform/-Verzeichnissen: Caddy-Site-Blöcke, Datenbankskripte, Prometheus-Jobs, Regeln und Dashboards. PostgreSQL hat pro Produkt eine Datenbank und eine Eigentümerrolle. - Produkteigene Speicher bleiben beim Produkt: ClickHouse und Valkey des Gateways, MongoDB (eine Datenbank pro Website) und Gotenberg des CMS, Redis und pgbouncer der Agentenplattform.
- Erzeugter Zustand liegt in
.state/, das Git ignoriert: die Secrets, einmal erzeugt und nie geändert, die Zugangsdaten des Bootstraps und die Variablen jedes Produkts, ausdemo.envgerendert.
Was make up tut
- Preflight. Docker und Compose 2.24 oder neuer, Speicher und Platte, die sechs Nachbar-Checkouts im Layout mit gemeinsamem Netzwerk, kein anderer pacod-Stack, der die gemeinsamen Namen belegt, das Passwort des Admins, das Zertifikat und die Ports. Ein blockierendes Problem hält hier an.
- Netzwerke und Secrets. Es legt
pacod-netund das internepacod-admin-netan und erzeugt jedes Secret einmal in.state/secrets.env. Fehlen die Secrets, die Volumes aber nicht, verweigert es, statt neue Secrets zu erzeugen, mit denen die Daten nichts anfangen können. - Rendern. Aus
demo.envwerden die Variablen jedes Produkts in.state/env/<product>.env. - Start. Compose startet das Projekt und wartet, bis jeder Dienst gesund ist. Der erste Start baut jedes Image aus dem Quellcode und lädt das Embedding-Modell herunter.
- Bootstrap. Er steuert die eigenen Skripte der Produkte, den Gateway- und Identitäts-Bootstrap von pacod-ap und den Provisioner von pacod-cms, um die Gateway-Schlüssel und Service-Tokens zu erzeugen, mit denen die Produkte einander erreichen. Er erzeugt auch das Token von pacod-benchmark für die Management-API des Gateways (ein Plattform-Admin: Der Benchmark legt für jeden Lauf eine eigene Organisation an und entfernt sie wieder) und gibt dem Admin jede Rolle, die ihm fehlt. Die Dienste, die diese Zugangsdaten lesen, werden neu erstellt.
- Seed. Die Tabellen der Agentenplattform, die Referenzfakten des Starter-Agenten und seine Entwicklungsbenutzer.
- Baseline. Auf einem frischen Stack wartet es, bis das CMS seine drei Demo-Websites geschrieben hat, und hält die Daten dann als Baseline fest.
- Scheduler. Es startet den Container des nächtlichen Zurücksetzens und gibt dann die Adressen und das Passwort des Admins aus.
Das nächtliche Zurücksetzen
Jeden Tag um DEMO_RESET_TIME (Standard 05:00) in DEMO_RESET_TIMEZONE (Standard UTC)
macht die Demo jede Änderung rückgängig: Konten, Agenten, Artikel, Dokumente, Schlüssel und
Einstellungen. Die Startseite kündigt es in einem Band unter ihrem Kopf an, mit der Uhrzeit in der
Zeitzone des Besuchers und der Zeit bis zum nächsten Mal.
- Die Baseline ist der Datenstand des Stacks zu einem Zeitpunkt: was das erste
make uperzeugt hat, oder wasmake baselinespäter festhält. Sie umfasst jedes Daten-Volume (PostgreSQL, MongoDB, Qdrant, ClickHouse, Redis, die Dateien der Wissensdatenbank und der App, Grafana, Alertmanager), die Dateien des CMS und die Zugangsdaten des Bootstraps, komprimiert im Docker-Volumepacod-demo-baseline. - Nicht darin: die Modelle, die Metriken von Prometheus, die eigenen Daten des Edge und der Antwort-Cache des Gateways, der nur im Speicher liegt: Jedes Zurücksetzen leert ihn.
- Auch Benchmarks gehen zurück: die Läufe und Zeitpläne von pacod-benchmark, die in seiner Oberfläche hinzugefügten Gateways und die in der Gateway-Konsole veröffentlichten Berichte. Einen Bericht, den du behalten willst, lädst du auf der Seite seines Laufs herunter; die Konsole nimmt ihn per Upload wieder an.
- Wie. Alle Dienste außer dem Edge stoppen, die Startseite bleibt also erreichbar, während
die Produkte einige Minuten lang 502 antworten. Die Baseline wird zurückkopiert, der Stack
startet, und der Bootstrap läuft erneut, der dabei auch einen inzwischen hinzugefügten
Anbieterschlüssel übernimmt.
make resettut dasselbe, sofort. - Der Scheduler ist der Container
pacod-demo-reset, außerhalb des Compose-Projekts, weil ein Zurücksetzen das Projekt stoppt. Er überspringt eine Nacht, wenn der Stack nicht läuft oder die Maschine schlief. Ein leeresDEMO_RESET_TIMEschaltet ihn ab.
Konfiguration
Zwei Dateien. demo.env ist die Konfiguration: die Domains, die des Stacks und die der Websites,
die Ports, das Zertifikat, die E-Mail des ersten Administrators, die Uhrzeit des Zurücksetzens,
die Modelle jedes Produkts, das Embedding-Backend, die optionale Komponente und das Logging. Git
ignoriert sie; das erste make kopiert sie aus der eingecheckten Vorlage demo.env.example und
hält an, damit du sie bearbeiten kannst. demo.local.env enthält die Secrets der Maschine, das
Passwort des Administrators und die Schlüssel der LLM-Anbieter; Git ignoriert auch sie, und was
sie setzt, hat Vorrang.
# demo.local.env
DEMO_ADMIN_PASSWORD=a-long-passphrase
ANTHROPIC_API_KEY=sk-...
LLM-Anbieter. Ohne Schlüssel geht jeder Modellaufruf an den Mock-Anbieter des Gateways: Die
Demo läuft offline und make verify ist deterministisch, aber die Chat-Antworten sind
vorgefertigt. Trag einen Schlüssel ein (die Standardmodelle der Agentenplattform sind die von
Anthropic) und führe make bootstrap aus, dann wird das Gateway mit dem echten Anbieter
eingerichtet. AP_PRIMARY_MODEL, AP_CLASSIFIER_MODEL, CMS_AI_MODEL und KB_LLM_MODEL wählen
die Modelle, die die Produkte beim Gateway anfragen.
Das Embedding-Backend wird beim ersten make up festgelegt, weil die gespeicherten Vektoren
davon abhängen. Der Standard, auto, nimmt BGE-M3, wenn Docker etwa 8 GB Speicher hat, und
darunter einen leichten Ersatz; ein späterer Wechsel braucht make clean.
Die optionale Komponente ingestion betreibt die Dokumentenaufnahme der Agentenplattform und
lädt die Wissensdatenbank des Starter-Agenten; ohne sie antwortet der Agent nur aus seinen
Referenzfakten. Ihr Image ist etwa 10 GB groß und kann 7 GiB Speicher belegen, sie will also
16 GiB für Docker.
Logs. Jedes Produkt loggt im selben Format, ein Ereignis pro Zeile mit überall denselben
Schlüsseln (docs/LOGGING.md).
DEMO_LOG_LEVEL und DEMO_LOG_FORMAT (text oder json) stellen alle ein, auch das
Anfrageprotokoll des Edge.
Die Demo-Websites des CMS werden nur beim ersten Start des Studios geschrieben.
make cms-seed füllt eine Website ohne Artikel, und make cms-space legt Starward auf einem Stack
an, der vor ihr gestartet wurde. Starward und die Startseite können in demo.env auch ein
Google-Analytics-Tag und eine Search-Console-Verifizierung bekommen; bleiben die Felder leer, wie
im Standard, ist nichts von Google auf der Seite.
Sicherheit
- Ein veröffentlichter Port. Nur der Edge,
pacod-caddy, veröffentlicht Ports; jeder andere Dienst ist nur in den Docker-Netzwerken erreichbar. Die Listener für Server liegen im internenpacod-admin-net, gebunden an Aliase, diepacod-netnicht erreicht. - Secrets. Jedes Secret wird einmal auf der Maschine erzeugt und nie eingecheckt. Das Passwort des Admins muss 12 Zeichen oder mehr haben (pacod-id lehnt ein kürzeres ab); bleibt es leer, wird eines mit 24 Zeichen erzeugt.
- Die Domain der Websites. Eine CMS-Website führt das Skript ihres Besitzers aus, das auf der
registrierbaren Domain des Studios Cookies setzen könnte, die das Studio und die Anmeldung
erhalten. Deshalb bekommen die Websites eine eigene Domain (
DEMO_SITE_DOMAIN); auf der des Studios verweigert das Studio den Start.DEMO_SITE_DOMAIN_SHARED=truelegt sie stattdessen unter die Domain der Demo, für eine Demo, deren Websites alle vertrauenswürdig sind, und nur über HTTPS. demo.pacod.io macht das so: Seine Websites gehören alle ihm selbst. - Über die Maschine hinaus veröffentlicht (
DEMO_BINDkeine Loopback-Adresse), schließt die Demo, was nur auf dem Laptop sicher ist: Mail-Ansicht, Prometheus und Grafana fragen nach E-Mail und Passwort des Admins,/grafanader Gateway-Konsole antwortet 403, die Startseite nennt den Admin nicht, und die Entwicklungs-Tokens der Agentenplattform sind aus. Die eigene Verwaltung der Produkte liegt wie immer hinter ihrer Anmeldung. - Zertifikate werden bereitgestellt, nicht bezogen: ein Zertifikat für die Domain, ihre Subdomains und die Domain der Websites.
Auf einer Domain oder auf dem Laptop
Mit gesetztem DEMO_TLS_CERT und DEMO_TLS_KEY antwortet der Stack über HTTPS, und einfaches
HTTP leitet nur dorthin um. Im DNS müssen die Domain, ihr Wildcard und der Wildcard der Websites
auf den Server zeigen; bevor es so weit ist, gibt make hosts Zeilen für /etc/hosts aus, um es
zu testen.
Die eingecheckte Vorlage ist die des öffentlichen Servers. Für eine Demo nur auf einer Maschine
braucht demo.env fünf Einstellungen:
DEMO_DOMAIN=localhost
DEMO_TLS_CERT=
DEMO_TLS_KEY=
DEMO_HTTP_PORT=8800
DEMO_BIND=127.0.0.1
Dann läuft alles über einfaches HTTP unter http://<name>.localhost:8800, was Browser ohne DNS
auflösen (Safari vielleicht nicht: nimm einen anderen Browser oder make hosts).
Was es braucht
- Docker mit Compose 2.24 oder neuer und make. Alles andere, von den Secrets bis zu den Prüfungen, läuft in Containern.
- Die sechs Produkt-Repositorys, neben diesem ausgecheckt.
- Etwa 8 GB Speicher für Docker. Der ganze Stack mit dem echten Embedding-Modell belegte bei der Messung, bevor pacod-benchmark dazukam, etwa 5 GiB; der Benchmark mit Last-Agent und Last-Mock des Gateways fügt im Ruhezustand unter 100 MiB hinzu. Mit dem leichten Ersatz etwa 4 GiB.
- Etwa 30 GiB Platte für die Images. Das erste
make upbaut jedes Image aus dem Quellcode, drei Rust-Workspaces, einen Maven-Build, mehrere Python-Images und drei SvelteKit-Apps, und dauert 30 bis 60 Minuten. Spätere Starts dauern etwa zwei Minuten.
make down stoppt den Stack und behält die Daten; make clean entfernt alles, was die Demo
angelegt hat. Nach dem Holen neuer Versionen baut make build die Images neu (make up baut nur
fehlende), und make reset gefolgt von make baseline macht die migrierten Daten zur neuen
Baseline.
Was getestet ist, und seine Grenzen
make verify prüft den laufenden Stack von Ende zu Ende und endet mit 1, wenn etwas fehlschlägt:
| Teil | Was es prüft |
|---|---|
| Docker | Eine Instanz jeder gemeinsamen Komponente, nur der Edge veröffentlicht einen Port, kein Dienst gestoppt oder ungesund, pacod-admin-net intern und nur von den Aufrufern der Listener betreten |
| Edge und Gesundheit | Die Adresse und der Health-Endpunkt jedes Produkts, jedes Prometheus-Ziel erreichbar, die Regeln und Dashboards des Gateways und der App geladen |
| Single Sign-on | Der Admin meldet sich einmal an und kommt ohne erneute Anmeldung in die App, die Gateway-Konsole, das Studio, die Wissensdatenbank und den Benchmark, und hat jede Rolle, die er haben soll |
| Gateway | Die Schlüssel der Agentenplattform, des CMS und der Wissensdatenbank listen je Modelle auf und vollenden einen Chat; ein wiederholter Aufruf wird aus dem Antwort-Cache beantwortet |
| Produkte | Ein gestreamter Chat-Zug über das Gateway (nur auf dem Laptop); ein Dokument in der Wissensdatenbank aufgenommen, gefunden und gelöscht; Demo Journal rendert, und Starward auf dem Satz magazine |
| Benchmark | Sein Token ist Plattform-Admin des Gateways, und das Gateway nimmt seine Berichte an |
Seine Grenzen:
- Der Last-Agent des Benchmarks läuft auf derselben Maschine wie das Gateway: Seine Zahlen zeigen, wie sich das Gateway verhält, nicht seine Kapazität.
- Die Speicherzahlen wurden gemessen, bevor pacod-benchmark zum Stack kam.
- Ein Zurücksetzen macht die Produkte einige Minuten unerreichbar, und der Scheduler überspringt eine Nacht, in der die Maschine schlief.
- Ohne Anbieterschlüssel ist jede Antwort die des Mocks; mit einem sind die Aufrufe echt und kosten Geld.
- Ein Stack, der vor Starward oder mit seiner früheren Version gestartet wurde, braucht einen Handgriff, um es zu bekommen; das README beschreibt ihn, mit der vollständigen Liste der Einstellungen und einer Tabelle zur Fehlersuche.
Schnellstart
Die sieben Repositorys nebeneinander holen
mkdir pacod && cd pacod
for r in pacod-demo pacod-id pacod-gw pacod-ap pacod-cms pacod-kb pacod-benchmark; do git clone https://github.com/pacod22/$r.git; done
Nur für diese Maschine einrichten
cd pacod-demo
cp demo.env.example demo.env
printf '%s\n' DEMO_DOMAIN=localhost DEMO_TLS_CERT= DEMO_TLS_KEY= DEMO_HTTP_PORT=8800 DEMO_BIND=127.0.0.1 >> demo.env
Den Stack bauen, starten und prüfen
make up
make verify
open http://localhost:8800
Funktioniert mit
- pacod-id: Der einzige Identitätsanbieter im Stack, mit einem Realm, über den sich jedes Produkt anmeldet; der Bootstrap gibt dem Admin die Rolle jedes Produkts.
- pacod-gw: Das einzige Gateway im Stack, gestartet mit eingeschaltetem Antwort-Cache; der Bootstrap gibt jedem Produkt einen eigenen Gateway-Schlüssel.
- pacod-ap: Betreibt den Starter-Agenten, einen kleinen fiktiven Helpdesk, mit seiner Website, dem Chat und der Admin-Konsole.
- pacod-cms: Betreibt das Studio mit seiner KI-Schreibhilfe und drei Demo-Websites, Demo Journal, Demo Notes und Starward.
- pacod-kb: Betreibt die Wissensdatenbank auf dem gemeinsamen Qdrant, PostgreSQL und Embeddings-Dienst.
- pacod-benchmark: Misst das Gateway des Stacks selbst, mit dem Last-Agenten und dem Mock des Gateways; seine Berichte erscheinen in der Gateway-Konsole.
Das Repository pacod-demo hat noch keine Lizenzdatei. Jedes Produkt, das es betreibt, hat seine eigene Lizenz, angegeben in seinem Repository und auf seiner Seite.