mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:41:08 +02:00
Final cleanup of references missed in previous rename commits: - Dockerfiles: PUBLIC_MANA_CORE_AUTH_URL → PUBLIC_MANA_AUTH_URL - Go modules: github.com/manacore/* → github.com/mana/* (7 go.mod files) - launchd plists: com.manacore.* → com.mana.* (14 files renamed + content) - Image assets: *_Manacore_AI_Credits* → *_Mana_AI_Credits* (11 files) - .env.example files: ManaCore brand strings → Mana - .prettierignore: stale apps/manacore/* paths → apps/mana/* - Markdown docs (CLAUDE.md, /docs/*): mana-core-auth → mana-auth, etc. Excluded from rename: .claude/, devlog/, manascore/ (historical content), client testimonials, blueprints, npm package refs (@mana-core/*). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
18 KiB
18 KiB
Matrix Self-Hosting auf Mac Mini
Plan für DSGVO-konformes Messaging mit Matrix/Synapse auf dem Mana Server.
Übersicht
┌─────────────────────────────────────────────────────────────────────┐
│ Internet │
│ │ │
│ ▼ │
│ Cloudflare Tunnel │
│ │ │
│ ├─── matrix.mana.how ──────► Synapse (Port 8008) │
│ ├─── element.mana.how ─────► Element Web (Port 8087) │
│ └─── (bestehende Services) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Docker Container │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ Synapse │ │ Element Web │ │ Matrix Bots │ │ │
│ │ │ (8008) │ │ (8087) │ │ (NestJS) │ │ │
│ │ └──────┬───────┘ └──────────────┘ └────────┬─────────┘ │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ PostgreSQL │ │ Ollama │ │ │
│ │ │ (matrix db) │ │ (11434) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
DSGVO-Vorteile
| Aspekt | Telegram | Matrix (Self-Hosted) |
|---|---|---|
| Datenstandort | Dubai/Singapur | Mac Mini (Deutschland) |
| AV-Vertrag | Nicht möglich | Nicht nötig (eigene Daten) |
| E2E-Verschlüsselung | Nur Secret Chats | Standard für alle Räume |
| Metadaten | Bei Telegram | Lokal gespeichert |
| Löschung | Abhängig von Telegram | Volle Kontrolle |
Phase 1: Synapse Homeserver
1.1 Datenbank erstellen
ssh mana-server
# Neue Datenbank für Matrix
docker exec mana-postgres psql -U postgres -c "CREATE DATABASE matrix;"
docker exec mana-postgres psql -U postgres -c "CREATE USER synapse WITH PASSWORD 'synapse-secure-password';"
docker exec mana-postgres psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE matrix TO synapse;"
1.2 Synapse Konfiguration erstellen
# Verzeichnis erstellen
mkdir -p ~/projects/mana-monorepo/docker/matrix
# Synapse Config generieren (einmalig)
docker run -it --rm \
-v ~/projects/mana-monorepo/docker/matrix:/data \
-e SYNAPSE_SERVER_NAME=mana.how \
-e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate
1.3 homeserver.yaml anpassen
Datei: docker/matrix/homeserver.yaml
server_name: "mana.how"
pid_file: /data/homeserver.pid
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false
database:
name: psycopg2
args:
user: synapse
password: "synapse-secure-password"
database: matrix
host: postgres
port: 5432
cp_min: 5
cp_max: 10
# Logging
log_config: "/data/mana.how.log.config"
# Media Store (lokaler Speicher für Medien)
media_store_path: /data/media_store
max_upload_size: 50M
# Registrierung
enable_registration: false
enable_registration_without_verification: false
# Admin-Account beim ersten Start erstellen
# Nach dem Start: docker exec -it synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008 -a
# Rate Limiting (für Bots erhöhen)
rc_message:
per_second: 5
burst_count: 20
rc_registration:
per_second: 0.5
burst_count: 5
# Für Bot-Integration: Application Services erlauben
app_service_config_files: []
# DSGVO: Datenaufbewahrung begrenzen
retention:
enabled: true
default_policy:
min_lifetime: 1d
max_lifetime: 365d
allowed_lifetime_min: 1d
allowed_lifetime_max: 365d
purge_jobs:
- longest_max_lifetime: 3d
interval: 12h
- shortest_max_lifetime: 365d
interval: 1d
# Telemetrie deaktivieren
report_stats: false
# Trusted Key Server (Matrix.org)
trusted_key_servers:
- server_name: "matrix.org"
# Signing Key
signing_key_path: "/data/mana.how.signing.key"
1.4 Docker Compose Ergänzung
Füge zu docker-compose.macmini.yml hinzu:
# ============================================
# Matrix Synapse (Homeserver)
# ============================================
synapse:
image: matrixdotorg/synapse:latest
container_name: mana-synapse
restart: always
depends_on:
postgres:
condition: service_healthy
environment:
SYNAPSE_CONFIG_PATH: /data/homeserver.yaml
volumes:
- ./docker/matrix:/data
- synapse_media:/data/media_store
ports:
- "8008:8008"
healthcheck:
test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# ============================================
# Element Web (Matrix Client)
# ============================================
element-web:
image: vectorim/element-web:latest
container_name: mana-element
restart: always
depends_on:
synapse:
condition: service_healthy
volumes:
- ./docker/matrix/element-config.json:/app/config.json:ro
ports:
- "8087:80"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/"]
interval: 30s
timeout: 10s
retries: 3
# Volumes ergänzen:
volumes:
synapse_media:
name: mana-synapse-media
1.5 Element Web Konfiguration
Datei: docker/matrix/element-config.json
{
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.mana.how",
"server_name": "mana.how"
},
"m.identity_server": {
"base_url": ""
}
},
"brand": "Mana Chat",
"integrations_ui_url": "",
"integrations_rest_url": "",
"integrations_widgets_urls": [],
"disable_guests": true,
"disable_3pid_login": true,
"default_country_code": "DE",
"show_labs_settings": false,
"features": {
"feature_video_rooms": true,
"feature_group_calls": true
},
"room_directory": {
"servers": ["mana.how"]
},
"setting_defaults": {
"breadcrumbs": true
},
"default_theme": "dark"
}
1.6 Cloudflare Tunnel erweitern
Datei: ~/.cloudflared/config.yml
# Bestehende Einträge...
- hostname: matrix.mana.how
service: http://localhost:8008
- hostname: element.mana.how
service: http://localhost:8087
Nach Änderung:
launchctl stop com.cloudflare.cloudflared
launchctl start com.cloudflare.cloudflared
Phase 2: Synapse starten & Admin erstellen
2.1 Container starten
cd ~/projects/mana-monorepo
# Nur Synapse + Element starten
docker compose -f docker-compose.macmini.yml up -d synapse element-web
# Logs prüfen
docker logs -f mana-synapse
2.2 Admin-User erstellen
# Interaktiv einen Admin erstellen
docker exec -it mana-synapse register_new_matrix_user \
-c /data/homeserver.yaml \
http://localhost:8008 \
-a
# Eingeben:
# Username: admin
# Password: (sicheres Passwort)
# Admin: yes
2.3 Testen
# Health Check
curl https://matrix.mana.how/health
# Erwartete Antwort: OK
# Federation Check
curl https://matrix.mana.how/_matrix/federation/v1/version
# Erwartete Antwort: {"server":{"name":"Synapse","version":"..."}}
# Element Web aufrufen
open https://element.mana.how
Phase 3: Bot-Räume einrichten
3.1 Räume erstellen (via Element)
- Anmelden bei https://element.mana.how mit Admin-Account
- Räume erstellen:
#ollama-bot:mana.how- AI Chat Bot#stats-bot:mana.how- Analytics Reports#project-doc-bot:mana.how- Projektdokumentation
3.2 Bot-User erstellen
# Bot-User für jeden Bot erstellen (nicht-Admin)
docker exec -it mana-synapse register_new_matrix_user \
-c /data/homeserver.yaml \
http://localhost:8008
# Erstelle:
# - ollama-bot (Password notieren)
# - stats-bot (Password notieren)
# - projectdoc-bot (Password notieren)
3.3 Access Tokens generieren
# Für jeden Bot ein Access Token holen
curl -X POST "https://matrix.mana.how/_matrix/client/v3/login" \
-H "Content-Type: application/json" \
-d '{
"type": "m.login.password",
"user": "ollama-bot",
"password": "bot-password"
}'
# Response: {"access_token": "syt_xxx", ...}
# Token für .env speichern
Phase 4: Bot-Migration (NestJS)
4.1 Neue Package-Struktur
services/
├── telegram-ollama-bot/ # Alt (Telegram)
├── telegram-stats-bot/ # Alt (Telegram)
├── telegram-project-doc-bot/# Alt (Telegram)
│
├── matrix-ollama-bot/ # NEU (Matrix)
├── matrix-stats-bot/ # NEU (Matrix)
└── matrix-project-doc-bot/ # NEU (Matrix)
4.2 Dependencies
cd services/matrix-ollama-bot
pnpm add matrix-bot-sdk
4.3 Bot-Grundstruktur (Beispiel: Ollama Bot)
Datei: services/matrix-ollama-bot/src/bot/matrix.service.ts
import {
MatrixClient,
SimpleFsStorageProvider,
AutojoinRoomsMixin,
RichConsoleLogger,
LogService,
} from 'matrix-bot-sdk';
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class MatrixService implements OnModuleInit, OnModuleDestroy {
private client: MatrixClient;
constructor(private config: ConfigService) {}
async onModuleInit() {
LogService.setLogger(new RichConsoleLogger());
const homeserverUrl = this.config.get('MATRIX_HOMESERVER_URL');
const accessToken = this.config.get('MATRIX_ACCESS_TOKEN');
const storage = new SimpleFsStorageProvider('bot-storage.json');
this.client = new MatrixClient(homeserverUrl, accessToken, storage);
// Auto-join bei Einladungen
AutojoinRoomsMixin.setupOnClient(this.client);
// Message Handler
this.client.on('room.message', this.handleMessage.bind(this));
await this.client.start();
console.log('Matrix bot started!');
}
async onModuleDestroy() {
await this.client.stop();
}
private async handleMessage(roomId: string, event: any) {
// Eigene Nachrichten ignorieren
if (event.sender === await this.client.getUserId()) return;
// Nur Text-Nachrichten
if (event.content?.msgtype !== 'm.text') return;
const body = event.content.body;
// Command-Handler
if (body.startsWith('!')) {
await this.handleCommand(roomId, event, body);
} else {
// Normaler Chat → Ollama
await this.handleChat(roomId, event, body);
}
}
private async handleCommand(roomId: string, event: any, body: string) {
const [command, ...args] = body.slice(1).split(' ');
switch (command.toLowerCase()) {
case 'help':
await this.sendMessage(roomId, this.getHelpText());
break;
case 'models':
// Liste verfügbare Modelle
break;
case 'clear':
// Chat-History löschen
break;
// ... weitere Commands
}
}
private async handleChat(roomId: string, event: any, message: string) {
// Typing-Indikator senden
await this.client.setTyping(roomId, true);
// Ollama-Anfrage (wie bisher)
const response = await this.ollamaService.chat(message);
await this.client.setTyping(roomId, false);
await this.sendMessage(roomId, response);
}
async sendMessage(roomId: string, message: string) {
await this.client.sendMessage(roomId, {
msgtype: 'm.text',
body: message,
format: 'org.matrix.custom.html',
formatted_body: this.markdownToHtml(message),
});
}
private getHelpText(): string {
return `**Mana Ollama Bot**
Befehle:
- \`!help\` - Diese Hilfe
- \`!models\` - Verfügbare Modelle
- \`!model <name>\` - Modell wechseln
- \`!clear\` - Chat-Verlauf löschen
Einfach eine Nachricht schreiben für AI-Chat.`;
}
}
4.4 Environment Variables
Datei: services/matrix-ollama-bot/.env
# Server
PORT=3311
# Matrix
MATRIX_HOMESERVER_URL=https://matrix.mana.how
MATRIX_ACCESS_TOKEN=syt_xxx
# Optional: Nur bestimmte Räume erlauben
MATRIX_ALLOWED_ROOMS=#ollama-bot:mana.how
# Ollama
OLLAMA_URL=http://host.docker.internal:11434
OLLAMA_MODEL=gemma3:4b
OLLAMA_TIMEOUT=120000
4.5 Docker Compose für Matrix Bots
# ============================================
# Matrix Ollama Bot
# ============================================
matrix-ollama-bot:
image: ghcr.io/memo-2023/matrix-ollama-bot:latest
container_name: mana-matrix-ollama-bot
restart: always
depends_on:
synapse:
condition: service_healthy
environment:
NODE_ENV: production
PORT: 3311
MATRIX_HOMESERVER_URL: http://synapse:8008
MATRIX_ACCESS_TOKEN: ${MATRIX_OLLAMA_BOT_TOKEN}
OLLAMA_URL: http://host.docker.internal:11434
OLLAMA_MODEL: gemma3:4b
volumes:
- matrix_ollama_bot_data:/app/data
ports:
- "3311:3311"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3311/health"]
interval: 30s
timeout: 10s
retries: 3
# Volume ergänzen:
volumes:
matrix_ollama_bot_data:
name: mana-matrix-ollama-bot
Phase 5: Feature-Mapping Telegram → Matrix
Commands
| Telegram | Matrix | Beschreibung |
|---|---|---|
/start |
!help |
Hilfe anzeigen |
/help |
!help |
Hilfe anzeigen |
/models |
!models |
Modelle auflisten |
/model x |
!model x |
Modell wechseln |
/clear |
!clear |
Chat löschen |
/status |
!status |
Bot-Status |
Media-Handling
| Feature | Telegram | Matrix |
|---|---|---|
| Foto senden | ctx.message.photo |
m.image msgtype |
| Voice senden | ctx.message.voice |
m.audio msgtype |
| Datei senden | ctx.message.document |
m.file msgtype |
| Foto antworten | ctx.replyWithPhoto() |
sendMessage() mit m.image |
Beispiel: Media-Download in Matrix
async downloadMedia(event: any): Promise<Buffer> {
const mxcUrl = event.content.url; // mxc://mana.how/abc123
const httpUrl = this.client.mxcToHttp(mxcUrl);
const response = await fetch(httpUrl);
return Buffer.from(await response.arrayBuffer());
}
Phase 6: Health Check & Monitoring
Health Checks ergänzen
Datei: scripts/mac-mini/health-check.sh
# Matrix Synapse
if curl -sf http://localhost:8008/health > /dev/null; then
echo "✅ Synapse: OK"
else
echo "❌ Synapse: FAILED"
FAILED_SERVICES="$FAILED_SERVICES synapse"
fi
# Element Web
if curl -sf http://localhost:8087/ > /dev/null; then
echo "✅ Element Web: OK"
else
echo "❌ Element Web: FAILED"
FAILED_SERVICES="$FAILED_SERVICES element-web"
fi
# Matrix Ollama Bot
if curl -sf http://localhost:3311/health > /dev/null; then
echo "✅ Matrix Ollama Bot: OK"
else
echo "❌ Matrix Ollama Bot: FAILED"
FAILED_SERVICES="$FAILED_SERVICES matrix-ollama-bot"
fi
Prometheus Metrics (optional)
Synapse exportiert Metrics auf Port 9000 (kann aktiviert werden):
# In homeserver.yaml ergänzen
enable_metrics: true
metrics_port: 9000
# prometheus.yml ergänzen
- job_name: 'synapse'
static_configs:
- targets: ['synapse:9000']
Zeitplan
| Phase | Aufgabe | Aufwand |
|---|---|---|
| 1 | Synapse + Element aufsetzen | 1-2h |
| 2 | Admin & Bot-User erstellen | 30min |
| 3 | Bot-Räume einrichten | 30min |
| 4 | Ersten Bot migrieren (Ollama) | 2-4h |
| 5 | Weitere Bots migrieren | je 1-2h |
| 6 | Monitoring & Alerts | 1h |
Gesamt: ~1 Tag für Grundsetup + Bot-Migration
Nächste Schritte
docker/matrix/Verzeichnis erstellen- Synapse Config generieren
- Docker Compose erweitern
- Cloudflare Tunnel konfigurieren
- Synapse starten & testen
- Admin-Account erstellen
- Bot-User erstellen
matrix-ollama-botService erstellen- Bot testen
- Weitere Bots migrieren
- Telegram Bots deaktivieren