diff --git a/docker-compose.macmini.yml b/docker-compose.macmini.yml index ad1c3df36..fd5e8af95 100644 --- a/docker-compose.macmini.yml +++ b/docker-compose.macmini.yml @@ -748,6 +748,61 @@ services: retries: 3 start_period: 40s + # ============================================ + # Matrix Synapse (Homeserver) - DSGVO-konform + # ============================================ + + synapse: + image: matrixdotorg/synapse:latest + container_name: manacore-synapse + restart: always + depends_on: + postgres: + condition: service_healthy + environment: + SYNAPSE_CONFIG_PATH: /data/homeserver.yaml + TZ: Europe/Berlin + # Secrets (override in .env) + SYNAPSE_DB_PASSWORD: ${SYNAPSE_DB_PASSWORD:-synapse-secure-password} + SYNAPSE_PASSWORD_PEPPER: ${SYNAPSE_PASSWORD_PEPPER:-change-me-pepper} + SYNAPSE_FORM_SECRET: ${SYNAPSE_FORM_SECRET:-change-me-form-secret} + SYNAPSE_MACAROON_SECRET: ${SYNAPSE_MACAROON_SECRET:-change-me-macaroon-secret} + SYNAPSE_REGISTRATION_SECRET: ${SYNAPSE_REGISTRATION_SECRET:-change-me-registration-secret} + volumes: + - ./docker/matrix/homeserver.yaml:/data/homeserver.yaml:ro + - ./docker/matrix/log.config.yaml:/data/log.config.yaml:ro + - synapse_data:/data + ports: + - "8008:8008" + - "9000:9000" + healthcheck: + test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + + # ============================================ + # Element Web (Matrix Client) + # ============================================ + + element-web: + image: vectorim/element-web:latest + container_name: manacore-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 + # ============================================ # Auto-Update (Watchtower) # ============================================ @@ -786,3 +841,5 @@ volumes: name: manacore-grafana n8n_data: name: manacore-n8n + synapse_data: + name: manacore-synapse diff --git a/docker/matrix/element-config.json b/docker/matrix/element-config.json new file mode 100644 index 000000000..ac98fd000 --- /dev/null +++ b/docker/matrix/element-config.json @@ -0,0 +1,47 @@ +{ + "default_server_config": { + "m.homeserver": { + "base_url": "https://matrix.mana.how", + "server_name": "mana.how" + }, + "m.identity_server": { + "base_url": "" + } + }, + "brand": "ManaCore 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, + "feature_thread": true + }, + "room_directory": { + "servers": ["mana.how"] + }, + "setting_defaults": { + "breadcrumbs": true, + "custom_themes": [] + }, + "default_theme": "dark", + "permalink_prefix": "https://element.mana.how", + "terms_and_conditions_links": [], + "privacy_policy_url": "https://mana.how/privacy", + "sso_redirect_options": { + "immediate": false + }, + "posthog": { + "disabled": true + }, + "sentry": { + "disabled": true + }, + "bug_report_endpoint_url": "", + "help_url": "https://mana.how/help", + "help_encryption_url": "https://element.io/help#encryption" +} diff --git a/docker/matrix/homeserver.yaml b/docker/matrix/homeserver.yaml new file mode 100644 index 000000000..ffae2de73 --- /dev/null +++ b/docker/matrix/homeserver.yaml @@ -0,0 +1,190 @@ +# ManaCore Matrix Synapse Configuration +# Documentation: https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html + +server_name: "mana.how" +pid_file: /data/homeserver.pid +public_baseurl: https://matrix.mana.how/ + +# ============================================ +# Listeners +# ============================================ + +listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false + +# ============================================ +# Database (PostgreSQL) +# ============================================ + +database: + name: psycopg2 + txn_limit: 10000 + args: + user: synapse + password: "${SYNAPSE_DB_PASSWORD:-synapse-secure-password}" + database: matrix + host: postgres + port: 5432 + cp_min: 5 + cp_max: 10 + +# ============================================ +# Logging +# ============================================ + +log_config: "/data/log.config.yaml" + +# ============================================ +# Media Storage +# ============================================ + +media_store_path: /data/media_store +max_upload_size: 50M +url_preview_enabled: true +url_preview_ip_range_blacklist: + - '127.0.0.0/8' + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/16' + - '100.64.0.0/10' + - '192.0.0.0/24' + - '169.254.0.0/16' + - '198.18.0.0/15' + - '192.0.2.0/24' + - '198.51.100.0/24' + - '203.0.113.0/24' + - '224.0.0.0/4' + - '::1/128' + - 'fe80::/10' + - 'fc00::/7' + - '2001:db8::/32' + - 'ff00::/8' + - 'fec0::/10' + +# ============================================ +# Registration & Authentication +# ============================================ + +enable_registration: false +enable_registration_without_verification: false + +# Password config +password_config: + enabled: true + localdb_enabled: true + pepper: "${SYNAPSE_PASSWORD_PEPPER:-change-me-pepper}" + +# Session lifetime +session_lifetime: 24h +refresh_token_lifetime: 168h + +# ============================================ +# Rate Limiting +# ============================================ + +rc_message: + per_second: 5 + burst_count: 20 + +rc_registration: + per_second: 0.5 + burst_count: 5 + +rc_login: + address: + per_second: 0.5 + burst_count: 5 + account: + per_second: 0.5 + burst_count: 5 + failed_attempts: + per_second: 0.5 + burst_count: 5 + +# ============================================ +# Federation +# ============================================ + +# Allow federation with other Matrix servers +federation_domain_whitelist: [] + +trusted_key_servers: + - server_name: "matrix.org" + +# ============================================ +# DSGVO / Data Retention +# ============================================ + +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 + +# Forgotten room retention +forgotten_room_retention_period: 7d + +# ============================================ +# Security +# ============================================ + +signing_key_path: "/data/signing.key" + +form_secret: "${SYNAPSE_FORM_SECRET:-change-me-form-secret}" +macaroon_secret_key: "${SYNAPSE_MACAROON_SECRET:-change-me-macaroon-secret}" +registration_shared_secret: "${SYNAPSE_REGISTRATION_SECRET:-change-me-registration-secret}" + +# ============================================ +# Application Services (for Bots) +# ============================================ + +app_service_config_files: [] + +# ============================================ +# Metrics & Telemetry +# ============================================ + +report_stats: false +enable_metrics: true +metrics_port: 9000 + +# ============================================ +# Caching +# ============================================ + +caches: + global_factor: 0.5 + per_cache_factors: {} + expire_caches: true + cache_entry_ttl: 30m + +# ============================================ +# Background Tasks +# ============================================ + +run_background_tasks_on: synapse + +# ============================================ +# Email (optional, for password reset) +# ============================================ + +# email: +# smtp_host: smtp-relay.brevo.com +# smtp_port: 587 +# smtp_user: "${SMTP_USER}" +# smtp_pass: "${SMTP_PASSWORD}" +# require_transport_security: true +# notif_from: "ManaCore Matrix " diff --git a/docker/matrix/log.config.yaml b/docker/matrix/log.config.yaml new file mode 100644 index 000000000..39a2480ba --- /dev/null +++ b/docker/matrix/log.config.yaml @@ -0,0 +1,34 @@ +# Synapse Logging Configuration + +version: 1 + +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + +handlers: + console: + class: logging.StreamHandler + formatter: precise + stream: 'ext://sys.stdout' + + file: + class: logging.handlers.TimedRotatingFileHandler + formatter: precise + filename: /data/logs/homeserver.log + when: midnight + backupCount: 7 + encoding: utf8 + +loggers: + synapse.storage.SQL: + level: WARNING + + synapse.access.http.8008: + level: WARNING + +root: + level: INFO + handlers: [console, file] + +disable_existing_loggers: false diff --git a/docs/MAC_MINI_SERVER.md b/docs/MAC_MINI_SERVER.md index 097195721..ace021a3c 100644 --- a/docs/MAC_MINI_SERVER.md +++ b/docs/MAC_MINI_SERVER.md @@ -71,6 +71,8 @@ Cloudflare Tunnel (cloudflared) | Todo | https://todo.mana.how | | Calendar | https://calendar.mana.how | | Clock | https://clock.mana.how | +| Matrix (Synapse) | https://matrix.mana.how | +| Element Web | https://element.mana.how | ## SSH-Zugang @@ -260,6 +262,8 @@ curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" | manacore-calendar-web | Calendar Frontend | | manacore-clock-backend | Clock API | | manacore-clock-web | Clock Frontend | +| manacore-synapse | Matrix Homeserver | +| manacore-element | Element Web Client | ### Nützliche Docker-Befehle @@ -597,6 +601,35 @@ launchctl stop com.manacore.telegram-ollama-bot launchctl start com.manacore.telegram-ollama-bot ``` +## Matrix (DSGVO-konformes Messaging) + +Matrix ist eine DSGVO-konforme Alternative zu Telegram für Bot-Kommunikation. + +### Komponenten + +| Service | Port | Beschreibung | +|---------|------|--------------| +| Synapse | 8008 | Matrix Homeserver | +| Element Web | 8087 | Web-Client | + +### Setup + +```bash +# Matrix initialisieren +./scripts/mac-mini/setup-matrix.sh + +# Services starten +docker compose -f docker-compose.macmini.yml up -d synapse element-web + +# Admin-User erstellen +docker exec -it manacore-synapse register_new_matrix_user \ + -c /data/homeserver.yaml http://localhost:8008 -a +``` + +### Dokumentation + +Siehe [MATRIX_SELF_HOSTING.md](./MATRIX_SELF_HOSTING.md) für detaillierte Anleitung. + ## Chronologie der Einrichtung 1. **Docker Setup** - PostgreSQL, Redis, App-Container @@ -608,3 +641,4 @@ launchctl start com.manacore.telegram-ollama-bot 7. **Email Notifications** - Redundante Benachrichtigung 8. **Ollama** - Lokale LLM-Inferenz (Gemma 3 4B) 9. **Telegram Ollama Bot** - Chat-Interface für Ollama +10. **Matrix Synapse** - DSGVO-konformes Messaging diff --git a/scripts/mac-mini/health-check.sh b/scripts/mac-mini/health-check.sh index 65151f2a0..887af6d51 100755 --- a/scripts/mac-mini/health-check.sh +++ b/scripts/mac-mini/health-check.sh @@ -229,6 +229,11 @@ echo "Presi:" check_service "Presi Backend" "http://localhost:3008/api/v1/health" check_service "Presi Web" "http://localhost:5178/health" +echo "" +echo "Matrix (DSGVO-konform):" +check_service "Synapse" "http://localhost:8008/health" +check_service "Element Web" "http://localhost:8087/" + echo "" echo "Cloudflare Tunnel:" if pgrep -x "cloudflared" >/dev/null; then diff --git a/scripts/mac-mini/setup-matrix.sh b/scripts/mac-mini/setup-matrix.sh new file mode 100755 index 000000000..786b75559 --- /dev/null +++ b/scripts/mac-mini/setup-matrix.sh @@ -0,0 +1,123 @@ +#!/bin/bash +# Setup Matrix Synapse on Mac Mini +# Run this script once to initialize Matrix + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" +MATRIX_DIR="$PROJECT_DIR/docker/matrix" + +echo "============================================" +echo " ManaCore Matrix Setup" +echo "============================================" +echo "" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +# Check if postgres is running +echo "Checking PostgreSQL..." +if ! docker exec manacore-postgres pg_isready -U postgres > /dev/null 2>&1; then + echo -e "${RED}Error: PostgreSQL is not running.${NC}" + echo "Start it with: docker compose -f docker-compose.macmini.yml up -d postgres" + exit 1 +fi +echo -e "${GREEN}PostgreSQL is running${NC}" + +# Create matrix database +echo "" +echo "Creating Matrix database..." +if docker exec manacore-postgres psql -U postgres -lqt | cut -d \| -f 1 | grep -qw matrix; then + echo -e "${YELLOW}Database 'matrix' already exists${NC}" +else + docker exec manacore-postgres psql -U postgres -c "CREATE DATABASE matrix;" + echo -e "${GREEN}Database 'matrix' created${NC}" +fi + +# Create synapse user +echo "" +echo "Creating Synapse database user..." +if docker exec manacore-postgres psql -U postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='synapse'" | grep -q 1; then + echo -e "${YELLOW}User 'synapse' already exists${NC}" +else + # Generate a random password if not set + SYNAPSE_DB_PASSWORD=${SYNAPSE_DB_PASSWORD:-$(openssl rand -base64 24)} + docker exec manacore-postgres psql -U postgres -c "CREATE USER synapse WITH PASSWORD '$SYNAPSE_DB_PASSWORD';" + docker exec manacore-postgres psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE matrix TO synapse;" + docker exec manacore-postgres psql -U postgres -c "ALTER DATABASE matrix OWNER TO synapse;" + echo -e "${GREEN}User 'synapse' created${NC}" + echo "" + echo -e "${YELLOW}IMPORTANT: Add this to your .env file:${NC}" + echo "SYNAPSE_DB_PASSWORD=$SYNAPSE_DB_PASSWORD" +fi + +# Create logs directory in volume +echo "" +echo "Creating logs directory..." +mkdir -p "$MATRIX_DIR/logs" 2>/dev/null || true + +# Generate signing key if not exists +echo "" +echo "Checking signing key..." +if docker volume ls | grep -q manacore-synapse; then + echo -e "${YELLOW}Synapse volume already exists - signing key should be present${NC}" +else + echo "Signing key will be generated on first Synapse start" +fi + +# Generate secrets if not set +echo "" +echo "============================================" +echo " Required Environment Variables" +echo "============================================" +echo "" +echo "Add these to your .env file (generate secure values!):" +echo "" + +# Generate random secrets for display +echo "SYNAPSE_DB_PASSWORD=$(openssl rand -base64 24)" +echo "SYNAPSE_PASSWORD_PEPPER=$(openssl rand -base64 32)" +echo "SYNAPSE_FORM_SECRET=$(openssl rand -base64 32)" +echo "SYNAPSE_MACAROON_SECRET=$(openssl rand -base64 32)" +echo "SYNAPSE_REGISTRATION_SECRET=$(openssl rand -base64 32)" + +echo "" +echo "============================================" +echo " Cloudflare Tunnel Configuration" +echo "============================================" +echo "" +echo "Add these ingress rules to ~/.cloudflared/config.yml:" +echo "" +echo " - hostname: matrix.mana.how" +echo " service: http://localhost:8008" +echo "" +echo " - hostname: element.mana.how" +echo " service: http://localhost:8087" +echo "" + +echo "" +echo "============================================" +echo " Next Steps" +echo "============================================" +echo "" +echo "1. Add environment variables to .env file" +echo "2. Update Cloudflare Tunnel config" +echo "3. Start Matrix services:" +echo " docker compose -f docker-compose.macmini.yml up -d synapse element-web" +echo "" +echo "4. Wait for Synapse to start (check logs):" +echo " docker logs -f manacore-synapse" +echo "" +echo "5. Create admin user:" +echo " docker exec -it manacore-synapse register_new_matrix_user \\" +echo " -c /data/homeserver.yaml http://localhost:8008 -a" +echo "" +echo "6. Test endpoints:" +echo " curl https://matrix.mana.how/health" +echo " open https://element.mana.how" +echo "" +echo -e "${GREEN}Setup complete!${NC}"