Container-Image fuer den MCP-Leseserver: Build, Registry-Push, und was am Korpus-Sync noch offen ist #37
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Der Server aus #19 läuft (2.4.0), auf
stdioundstreamable-http, beide gegen den echtenKorpus gegengeprüft. Was fehlt, ist der Weg vom Repo zu einem laufenden Ding: ein Image, ein
Build, ein Push in die Registry.
Dieses Issue fasst zusammen, was schon feststeht. Die Details sind bewusst noch offen — sie
brauchen Entscheidungen des Betreibers, und die Liste unten sagt, welche. Wer das aufgreift,
soll nicht bei null anfangen, aber auch nicht glauben, hier stünde schon ein Plan.
Seit 2026-09-04 trägt dieses Issue auch den Abschluss des Master-Issues #36. Dessen letztes
offenes Kriterium — ein Konsument führt über die Traefik-Middleware nachweislich
searchgegenden Server aus — hing vollständig an einem Deployment und damit an diesem Image. #36 ist als
Entscheidungsprotokoll geschlossen; der Nachweis steht unten als eigenes Akzeptanzkriterium.
Damit ist dies das letzte offene Issue auf dem Weg zum MCP-Leseserver. Die Entscheidungen,
die dort getroffen wurden und hier nicht neu aufgemacht werden (Python statt Go, Traefik statt
eigener Auth, Polling statt Webhook, Direktimport statt Subprozess, Deployment gehört nicht in
dieses Repo), stehen im geschlossenen Body von #36 samt gemessener Grundlage.
Abgrenzung, die bleibt: Cluster, Ingress-Hosts, Secret-Store und die FluxCD-Quelle gehören
nicht hierher. Dies ist ein öffentlicher Tracker, das ist private Infrastruktur. Was hierher
gehört, ist alles, was eine Eigenschaft der Software ist: das Dockerfile, der Workflow, was
das Image an Konfiguration erwartet.
Was schon feststeht
Was ausgeliefert wird.
tools/chemenu/mcp/, gestartet alspython -m chemenu.mcp --transport streamable-http --host 0.0.0.0 --port 8000. Endpunkt/mcp. Lesend, ohne Schreibpfad — strukturell, weil nichts unterchemenu/commands/importiertwird.
Konfiguration, die das Image kennen muss (alles heute schon implementiert):
CHEMENU_ROOTWIKI_TRACE=0oderWIKI_TRACE_DIRaußerhalb des KorpusAbhängigkeiten.
tools/requirements.txtplustools/requirements-mcp.txt(letzteres ziehtmcp, und damit pydantic/starlette/uvicorn/cryptography). Dazuripgrepim Image — das istdie Falle, die ein reines
pip install-Dockerfile übersieht:searchshellt nachrgaus undhat absichtlich keinen Python-Fallback.
Authentifizierung ist gelöst und liegt woanders:
https://gitea.nehmer.net/torben/gitea-mcp-forward-auth — Traefik-ForwardAuth, Bearer-Token
gegen SHA-256-Hashes. Der Server authentifiziert selbst nichts. Rate Limiting gehört an
dieselbe Stelle, nicht in den Iteration Budget Gate (Begründung in #19).
Menschendoku steht:
INSTALL-MCP.md, Betriebsablauf ininstructions/mcp-read-server.md.Startpunkte, konkret
Zwei Vorlagen im eigenen Bestand, und sie taugen für verschiedene Hälften:
torben/gitea-mcp-forward-auth,.gitea/workflows/release.yaml— die nähere Vorlage.Sie pusht dorthin, wo wir auch hin wollen:
runs-on: container-builder, Job-Imagedebian:trixie-slimgit nodejs curl docker-cli docker-buildx unzip ca-certificates iproute2 gawk1password/load-secrets-action@v2(OP_SERVICE_ACCOUNT_TOKEN), Registry-Userund PAT aus
op://CI-CD/gitea-package-token/...HOST_IP=$(ip route | awk '/default/ { print $3 }'), danndocker buildx create --driver remote tcp://$HOST_IP:1234 --use --bootstrapv*.*.*; stabile TagsvX.Y.Zpushen zusätzlich:latest, Pre-Releasesstattdessen
:prerelease-taggitea.nehmer.net/torben, Plattform bislang nurlinux/amd64torben/gitea-mcp— Dockerfile-Muster, aber nicht der Push. Dessen Workflows pushen nachDockerHub (
DOCKER_ORG: gitea), weil das Repo ein Fork des Upstream ist; als Registry-Vorlagealso unbrauchbar. Wofür es taugt, ist die Image-Form: Multi-Stage,
--platform=$BUILDPLATFORM,--mount=type=cachefür den Dependency-Download,ARG VERSIONins Binary, non-root Runtime aufdistroless, OCI-Labels (org.opencontainers.image.version/.source). Dazu ein Muster, dasgitea-mcp hat und forward-auth nicht: ein nightly-Workflow auf
mainmitgit describe --tags --alwaysals Version.Ebenfalls im forward-auth-Repo und übernehmenswert:
scripts/test-registry-image.sh— zieht dasveröffentlichte Image, startet es und prüft es end-to-end, mit ephemerem Login (temporäres
DOCKER_CONFIGbzw.REGISTRY_AUTH_FILE, nichts in~/.docker/config.json).Stand im Repo, geprüft 2026-09-04 gegen 4.5.0: es gibt weiterhin kein
Dockerfileund keinenImage-Workflow.
.gitea/workflows/enthältci.yml,nightly.yml,release.yml.Was zu klären ist
Das ist die eigentliche Arbeit dieses Issues — jede Zeile ist eine Entscheidung, keine Aufgabe.
Was steckt im Image, Stack oder Stack+Korpus? Der Server liest einen Arbeitsbaum. Zwei
Formen: (a) Image trägt nur den Stack, der Korpus kommt als Volume und wird von einem
Sidecar/CronJob gesynct; (b) Image trägt einen Korpus-Stand und wird bei jeder Änderung neu
gebaut. (a) passt zum Polling-Design aus #19 und hält den Korpus aus der Registry heraus —
was bei einer privaten Instanz der Punkt ist. (b) macht das Image reproduzierbar und den
Sync überflüssig. Erst entscheiden, dann Dockerfile.
Wer führt
git fetch && git reset --hardaus? Sidecar, CronJob, oder ein Loop imEntrypoint. Braucht ein Read-Credential für das Korpus-Repo — für die öffentliche Instanz
keins, für die private schon. Hängt an 1.
Basis-Image.
distrolesswie die beiden Vorlagen geht bei Go, hier aber nicht ohneWeiteres: es braucht einen Python-Interpreter und das
rg-Binary. Realistischpython:3.13-slimplusripgrepper apt, oder ein Multi-Stage, dasrgstatischhereinkopiert. Non-root-Runtime sollte in beiden Fällen bleiben.
Wie kommt die Version ins Image? Der Stack hat
VERSIONundwikitool version bump;CI taggt bereits bei
VERSION-Bewegung (.gitea/workflows/release.yml). Naheliegend ist,den bestehenden Release-Trigger mitzubenutzen, statt einen zweiten Tag-Begriff einzuführen.
Zu prüfen: ob der Image-Build an denselben Tag hängt oder an einen eigenen.
linux/arm64mitbauen? forward-auth baut nur amd64, gitea-mcp beides. Kostet Buildzeit;nur entscheiden, wenn ein Ziel es braucht.
Healthcheck. Der Server hat heute keinen —
/healthzgibt es beim Auth-Proxy, nichthier. Für k8s-Probes braucht es entweder einen Endpunkt (dann: neuer Code im Server, ohne
Auth erreichbar, wie beim Proxy) oder eine Probe über den MCP-Endpunkt. Das ist die einzige
Zeile hier, die auf eine Änderung in diesem Repo hinausläuft.
Registry-Pfad und Image-Name. Analog
gitea.nehmer.net/torben/<name>. Nur festlegen.OCI-Labels. forward-auth hat heute keine, das Testskript prüft sie optional. Beim
Neubauen gleich richtig setzen (
image.source,image.version,image.title).Wie wird der Golden-Test im Image-Kontext gefahren, wenn überhaupt? Die Suite läuft in
CI gegen den Checkout. Ob ein Smoke-Test gegen das gebaute Image dazukommt (Vorbild:
test-registry-image.sh), ist eine eigene Entscheidung — die Analogie wäre: Image ziehen,starten,
list_toolsund einstatusgegen den mitgelieferten Demo-Korpus.Akzeptanzkriterien
ripgrep, beide requirements-Dateien installiert--transport streamable-http --host 0.0.0.0und beantwortetlist_toolssowie einstatusWIKI_TRACE=0oderWIKI_TRACE_DIRaußerhalb) —sonst startet der Container gar nicht, und das soll niemanden überraschen
gitea.nehmer.net/torben/<name>, Tag-Schema festgelegt unddokumentiert
INSTALL-MCP.mdum den Container-Weg ergänzt; der Verweis auf „ein Container-Image istals eigenes Vorhaben erfasst" dort aufgelöst
searchgegen den laufenden Server aus. Das ist der Abschlussnachweis für den gesamtenWeg zum MCP-Leseserver, nicht nur für das Image — er kann erst erbracht werden, wenn ein
Deployment steht, und deshalb steht er hier.
Hängt ab von: #19 (geschlossen, 2.4.0). Schließt ab: #36 (geschlossen 2026-09-04, letztes
Kriterium hierher übernommen). Verwandt: #32 — eine Ingest-Queue würde einen Schreibpfad und
damit ein anderes Container-Profil brauchen; nicht vorwegnehmen.
torben referenced this issue2026-09-02 06:07:30 +00:00
Changelog: Dieses Issue trägt seit der Triage-Sitzung 2026-09-04 den Abschluss von #36, das dabei geschlossen wurde.
searchgegen den laufenden Server aus." Es stand als einziger offener Punkt in #36 und hing dort vollständig an einem Deployment und damit an diesem Image — es gehört zu den Entscheidungen, die hier ohnehin getroffen werden, nicht in ein Master-Issue, das nichts mehr steuert.Dockerfile, kein Image-Workflow,.gitea/workflows/hatci.yml,nightly.yml,release.yml.Labels unverändert:
area/distribution,kind/decision,prio/planned,size/M. Die neun offenen Punkte sind Betreiberentscheidungen, nicht Umsetzungszeit —kind/decisionbleibt richtig.