Docker

Web-Selfhost, Gateway und Daemon per Compose.

MFC Web-Selfhost (Docker)

MFC als Web-App auf einem eigenen Rechner/VPS betreiben – Daten persistent in einem Docker-Volume. Steuerung komplett über Browser/Handy.

Voraussetzungen

  • Docker + Docker Compose (oder Coolify)
  • MFC_API_TOKEN (Pflicht): Compose bricht ohne den Wert ab (fail-closed).

Der Client sendet ihn als Header X-MFC-Token für die Schreib-/Ausführ-APIs (web/lib/api-gate.ts).

  • Für den Server-Agenten: eine Claude-CLI-Auth (ANTHROPIC_API_KEY oder

CLAUDE_CODE_OAUTH_TOKEN) – ohne bleibt der Agent ehrlich stehen.

Lokal bauen & starten

docker compose up --build

Danach läuft MFC auf http://localhost:3000. Alle Daten (Plan, Zeit, Kosten, Zugänge, Einstellungen, Backlog, Projektdateien) landen im Volume mfc-daten und überleben Neustarts.

  • Stoppen: docker compose down (Volume bleibt erhalten)
  • Volume löschen: docker compose down -v

Datenverzeichnis

Die Schreib-APIs lesen/schreiben in MFC_DATEN (im Compose-File /data, gemountet auf mfc-daten). Ohne die Variable fällt MFC auf ~/Documents zurück (Desktop-/Dev-Verhalten).

Coolify

1. Neue Ressource anlegen → Build-Pack: Dockerfile. 2. Dockerfile-Pfad: docker/Dockerfile.web. 3. Ports: Container-Port 3000 freigeben/öffentlich schalten (Proxy). 4. Persistentes Volume anlegen: mfc-daten → Container-Pfad /data. 5. Environment-Variable: MFC_DATEN=/data. 6. Deploy.

Server-Agent & autonome Schleife

Das Image basiert auf node:22-slim und installiert die Claude-CLI (@anthropic-ai/claude-code) global unter /usr/local/bin/claude – festgehalten in MFC_CLAUDE_BIN und gelesen von web/lib/claude-bin.ts. Damit laufen Agenten-Zentrum und autonome Schleife auf dem Server:

1. Autonomie einschalten: Dashboard → Einstellungen → „Autonome Schleife“. 2. Projekte liegen im Datenverzeichnis /data/<projekt> (nicht in ~/Documents). 3. Der Wecker (60 s) hält die Schleife im Server-Prozess am Laufen; POST /api/wake stößt zusätzlich einen Durchlauf an.

Gateway (/ws/core) & Agenten-Daemon (Modul 3)

Zwei zusätzliche Dienste (docker/Dockerfile.gateway, docker/Dockerfile.daemon), beide in docker-compose.yml ergänzt:

  • gateway: hält die persistente WebSocket-Verbindung /ws/core offen –

hier koppeln sich Handy/PWA und Agenten-Daemon-Knoten ein (gateway/server.mjs, Standard-Port 4872).

  • daemon: meldet den Host, auf dem der Container läuft, als steuerbaren

Knoten beim Gateway an (daemon/index.mjs) und nimmt dort Aufträge entgegen (abgesicherte Shell-Allow-Liste, optionale Docker-Steuerung, Dateisystem-Zugriff unterhalb MFC_ARBEITSWURZEL).

MFC_API_TOKEN=<wert> \
MFC_GATEWAY_SECRET=<mind. 32 Zeichen> \
MFC_KNOTEN_TOKEN=<mind. 32 Zeichen> \
docker compose up --build

Beide neuen Dienste sind wie mfc oben fail-closed: MFC_GATEWAY_SECRET signiert die Geräte-/Knoten-JWTs (gateway/jwt.mjs), MFC_KNOTEN_TOKEN ist der zweite Auth-Faktor des Daemons neben mTLS (daemon/mtls.mjs) – ohne beide Werte bricht docker compose up sofort ab, statt mit leeren Secrets zu starten.

Docker-Steuerung durch den Daemon (optional, root-äquivalentes Risiko)

daemon/docker.mjs kann – wenn gewünscht – Container auf dem Host steuern (start/stop/restart/logs/stats/compose). Das braucht den Docker-Socket des Hosts *im* Daemon-Container, den docker-compose.yml bewusst nicht standardmäßig einbindet. Wer das aktivieren will:

MFC_DOCKER_STEUERUNG=1 \
MFC_DOCKER_ERLAUBT=mfc,gateway \
docker compose -f docker-compose.yml -f docker/docker-compose.docker-steuerung.yml up -d

Sicherheitshinweis: Der Docker-Socket (/var/run/docker.sock) ist root-äquivalent – Zugriff darauf erlaubt, jeden beliebigen Container zu starten (auch privilegierte mit Host-Mounts) und damit effektiv Root auf dem Host zu werden. daemon/docker.mjs verweigert zusätzlich jede Aktion, wenn MFC_DOCKER_STEUERUNG nicht exakt "1" ist, und schränkt mit MFC_DOCKER_ERLAUBT die steuerbaren Container auf eine feste Liste ein – beides zusammen einsetzen, nicht nur den Socket verlassen.

Dienst-Installation ohne Docker (systemd/launchd/Windows)

Wer den Daemon direkt auf dem Rechner statt im Container laufen lassen will (z.B. für MFC_DOCKER_ERLAUBT-Zugriff auf den normalen Docker-Daemon des Rechners, oder auf Windows/macOS ohne Docker): siehe daemon/dienst/README.md – systemd-Unit (User-/System-Variante), macOS-LaunchAgent, Windows-Dienst/Aufgabenplanung, jeweils mit Installations- und Deinstallationsbefehlen.

Offener Abstimmungsbedarf mit gateway/

gateway/server.mjs terminiert aktuell reguläres Server-TLS (MFC_GATEWAY_CERT/MFC_GATEWAY_KEY, optional – ohne beide läuft es unverschlüsselt über ws://) und verlangt keine Client-Zertifikate (requestCert/CA-Prüfung fehlen serverseitig). daemon/mtls.mjs erzeugt dagegen ein vollständiges eigenes CA+Knoten-Zertifikatspaar für gegenseitiges TLS (Client-Seite: requestCert:true, rejectUnauthorized:true, eigene ca). Damit eine echte wss://-Verbindung mit beidseitiger Zertifikatsprüfung zustande kommt, muss der Koordinator beide Seiten auf eine gemeinsame CA und eine serverseitige Client-Zertifikatsprüfung abstimmen (oder das Gateway serverseitig um requestCert/CA ergänzen) – das ist in dieser Implementierung bewusst offengelassen, damit daemon/ unabhängig von der parallel entstehenden gateway/-Implementierung fertig und testbar wurde.