SuperIntelligentHub.Docs
Sprache auswählen
Dokumentation/Produktionsserver
SUPERINTELLIGENTHUB DOKUMENTATION

Vom neuen Server zu sihub.at

Stand: 10. Oktober 2026. Diese Anleitung richtet einen neuen Ubuntu-24.04-LTS-Server mit SIHub ein. Die vorhandene Anwendung bleibt Flask/Gunicorn; Next.js, FastAPI und LangGraph sind keine Voraussetzungen. Apache behält Port 80/443, Docker veröffentlicht die App ausschließlich auf 127.0.0.1:5090. Telefonie und Medien laufen über LiveKit Cloud; auf diesem Server wird kein eigener öffentlicher SIP-/RTP-Server installiert.

Für Website-/Portalhosting mit vorhandenem Apache2: Verwende zunächst den Apache-Schnellstart und die Anleitung im Repository unter apache2/README.md. sudo bash apache2/install.sh prepare richtet einen direkten Gunicorn-Dienst ein. Abschnitt 5 dieser Serveranleitung enthält die dazu passenden Apache-/Zertifikatsbefehle. Die folgenden Docker-, MariaDB- und Voiceworker-Schritte gehören zum vollständigen Echtzeittelefonie-Stack.

Die bereitgestellte Serverplanung nennt 8 vCPU/32 GB für den App-Host, einen getrennten Datenbankdienst und zwei Voiceworker als Startentwurf. Compose liefert zunächst eine überprüfbare Installation auf einem Host mit logisch getrennten Diensten. Zwei Container auf demselben Host sind keine Ausfallsicherheit. 20 gleichzeitige Gespräche bleiben ein zu messendes Ziel, keine bereits nachgewiesene Kapazität. Die genannten Eurobeträge der Planung sind Budgetannahmen, keine aktuellen Anbieterangebote.

1. Zugang, IP und DNS vorbereiten

Notiere die tatsächlich zugewiesene öffentliche IPv4-Adresse. Verwalte die DNS-Zone sihub.at und lege einen A-Record für die Hauptdomain (@ oder ein leeres Namensfeld, je nach Anbieter) → tatsächliche öffentliche Server-IPv4 an. Interne Adressen wie 192.168.x.x sind kein Ziel für diesen öffentlichen DNS-Eintrag. Lege nur dann einen AAAA-Record an, wenn IPv6 auf dem Server und in dessen Firewall tatsächlich funktioniert. SERVER_IPV4 in Beispielen ist ein Platzhalter, keine reale IP. Diese Vorlage verwendet ausschließlich sihub.at; www.sihub.at ist optional und muss bei Bedarf separat im DNS, Apache und Zertifikat eingerichtet werden.

Wenn du den jetzigen Server mit einer privaten 192.168.x.x-Adresse veröffentlichen willst: Verwende entweder einen VPS mit öffentlicher IPv4 oder die tatsächlich von außen erreichbare öffentliche IPv4 deines Routers. Im Router leitest du dann TCP 80 und 443 auf die private Adresse dieses Servers weiter; der DNS-A-Record zeigt auf die öffentliche Routeradresse. Ohne erreichbare öffentliche Adresse, etwa hinter Carrier-NAT, brauchst du zuerst einen entsprechenden Anschluss oder einen öffentlichen VPS. Wenn dig für die Domain NXDOMAIN liefert, prüfe ihre Registrierung, die eingetragenen Nameserver und die DNS-Zone beim Anbieter. Die Zertifikatsausstellung folgt erst nach funktionierendem DNS und externer HTTP-Erreichbarkeit.

Melde dich zunächst mit deinem vorhandenen SSH-Schlüssel an. Lege für den Betrieb ein eigenes Sudo-Konto an; teste dessen Anmeldung in einem zweiten Terminal, bevor du Root-/Passwortlogin abschaltest. Für einen frischen Server kann die SSH-Konfiguration anschließend so aussehen:

# /etc/ssh/sshd_config.d/90-aihub.conf
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Vor einem Reload sudo sshd -t ausführen und die bestehende Sitzung geöffnet halten. Auf einem bestehenden Host müssen dessen SSH-/Firewallregeln und Dienste vorher berücksichtigt werden; diese Projektdateien ändern keinen fremden VirtualHost.

sudo apt-get update
sudo apt-get install -y ca-certificates curl dnsutils git python3 apache2 certbot wireguard
dig +short A sihub.at
dig +short AAAA sihub.at
sudo ss -lntp
sudo apache2ctl -S

Die DNS-Antwort muss zu deinem Server passen. Port 22 für SSH und 80/443 für HTTP/TLS müssen erreichbar sein; WireGuard braucht später UDP 51820. MariaDB, Redis und die Voiceworker erhalten keine öffentlichen Portfreigaben. Docker-Publishing und Hostfirewalls interagieren gesondert; die Loopback-Bindings verhindern hier eine öffentliche Veröffentlichung der internen Dienste. Docker-Firewallverhalten

2. Docker aus dem offiziellen Docker-Repository installieren

Falls Docker bereits für andere Projekte eingerichtet ist, verwende die vorhandene unterstützte Installation. Auf dem neuen Server:

sudo install -d -m 0755 /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod 0644 /etc/apt/keyrings/docker.asc
. /etc/os-release
AIHUB_ARCH="$(dpkg --print-architecture)"
printf 'Types: deb\nURIs: https://download.docker.com/linux/ubuntu\nSuites: %s\nComponents: stable\nArchitectures: %s\nSigned-By: /etc/apt/keyrings/docker.asc\n' "$VERSION_CODENAME" "$AIHUB_ARCH" | sudo tee /etc/apt/sources.list.d/docker.sources
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker version
sudo docker compose version

Verwende sudo docker oder einen bewusst eingerichteten Rootless-Betrieb. Die Mitgliedschaft in der docker-Gruppe verleiht weitreichende Hostrechte und wird hier nicht automatisch vergeben. Offizielle Ubuntu-Installation, Docker-Betriebsrechte

3. Projekt und Betreiberumgebung bereitstellen

Übertrage den fertigen SIHub-Projektstand nach /var/www/SIHub; der Ordner muss app.py, deploy/compose.yml, voice_worker/, requirements-mariadb.txt und requirements-production.txt enthalten. Verwende deinen tatsächlichen Repository-/Übertragungsweg; eine erfundene öffentliche Clone-URL ist nicht nötig.

Der Projektstand liegt unter /var/www/SIHub. Verwende bei einer bestehenden Serverinstallation weiterhin deren konfigurierte Datenbank und Laufzeit. Die technischen Variablennamen AIHUB_*, das Compose-Projekt aihub, sein Redis-/Appvolume sowie Redis- und Dienstnamen bleiben kompatibel. Die Datenbank wird auf MariaDB mit eigenem mariadb_data-Volume umgestellt; ein altes DB-Volume bleibt als Quelle erhalten. Bereite keine neue Betreiberdatei vor, wenn eine bestehende Installation bereits konfiguriert ist; passe dort die öffentliche URL an und übernimm Sitzungsschlüssel, Anbieterkeys und Rediszugänge. Die MariaDB-Zugangsdaten und DSN müssen zusammenpassen; MariaDB-Übernahme enthält den Ablauf.

cd /var/www/SIHub
python3 deploy/prepare_environment.py
chmod 600 deploy/.env.production
sudoedit deploy/.env.production

Der Helfer erzeugt neue Session-/Worker-/DB-/Redis-/Grafana-/Signaturschlüssel direkt in deploy/.env.production. Er druckt keine Schlüsselwerte und überschreibt keine vorhandene Betreiberdatei. deploy/secrets/redis.acl enthält nur einen Passwort-Hash. Ergänze Anbieterkeys in der Datei, nicht als Shellargumente und nicht im Browser. Die Livefreigabe bleibt zunächst 0.

Wichtige Werte: AIHUB_PUBLIC_URL=https://sihub.at, AIHUB_SECURE_COOKIES=1, AIHUB_TRUST_PROXY=1, DATABASE_URL=mariadb+pymysql://sihub:...@mariadb:3306/SIHub, AIHUB_REDIS_URL=redis://aihub:...@redis:6379/0. Das erzeugte Hexpasswort ist URL-sicher; andere Passwörter müssen für eine DSN korrekt URL-kodiert werden.

sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml config --quiet
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml build app
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml up -d --wait mariadb redis
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps app python manage.py init-db
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps app python manage.py schema-status

config --quiet prüft die Vorlage, ohne die aufgelösten Secretwerte auszugeben. Das App-Image verwendet Python 3.12 und läuft als UID 10001. MariaDB 10.11 und Redis 7.4 sind die hier gewählten Hauptversionen; überprüfe und pinne Image-Digests für deinen freigegebenen Produktionsstand. MariaDB-Wartungszeiträume, Redis-ACL

MariaDB speichert Benutzer, Agenten, Einstellungen und sämtliche weiteren dauerhaften Plattformdaten in der Datenbank SIHub. init-db prüft das vollständige mitgelieferte Schema, ergänzt fehlende Tabellen/Spalten/Indizes und meldet die ausgeführten Änderungen. Derselbe Abgleich läuft bei jedem Appstart unter einer datenbankspezifischen Sperre; schema-status liest den Ist-/Sollstand ohne Änderungen. Nach einer Sicherung und einem neuen Repositorystand genügt für das Schema die neue Appversion: Baue das App-Image neu und starte es mit up -d --build app. Manuelle SQL-Tabellenanlage ist nicht erforderlich. Grenzen des automatischen Abgleichs und der direkte Apache-Updatepfad stehen in Datenbankbetrieb.

4. Bestehende SQLite-Daten übernehmen oder neu beginnen

Neue Installation: Überspringe die Migration und lege unten ein Betreiberkonto an.

Bestehendes SIHub: Folge zuerst der Übernahme nach MariaDB. Stoppe die bisherigen SIHub-Schreiber, sichere die Quelldatenbank unverändert und importiere sie mit scripts/migrate_to_mariadb.py in die leeren MariaDB-Zieltabellen. Übernimm vorhandene Sitzungs-/API-/Telefonieschlüssel in die Betreiberdatei. Erzeuge vor dem Import kein neues Benutzerkonto. Der Import übernimmt IDs, Passwort-/API-Key-Hashes und prüft Zeilenzahlen; die Quelle bleibt erhalten.

Nur bei einer neuen Installation legst du anschließend ein Konto an:

sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps app python manage.py create-admin --email DEINE_ADMIN_EMAIL --workspace-name SIHub

Ersetze DEINE_ADMIN_EMAIL; das Passwort wird verdeckt abgefragt. Bei einer Migration meldest du dich mit einem übernommenen Konto an. Prüfe zunächst die Grundkonfiguration und starte dann die App:

sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps app python manage.py check-config
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml up -d --wait app
curl --fail http://127.0.0.1:5090/health

Prüfe Anmeldung, Wissen, Agentversionen und Gesprächsverläufe. Ist 5090 bereits belegt, beende gezielt die alte SIHub-Instanz. Bei einem fehlgeschlagenen Umstieg stoppe die neuen SIHub-App-/Voicecontainer und starte den notierten alten Dienst mit dessen ursprünglicher SQLite-Datei. Nach Schreibzugriffen auf MariaDB ist ein Rollback zur alten Quelldatenbank nur mit einer ausdrücklich geplanten Rückübernahme der neuen Daten möglich.

5. HTTP-VirtualHost aktivieren und erst dann TLS ausstellen

Die HTTP-Bootstrapdatei referenziert keine noch nicht vorhandenen Zertifikate:

sudo install -d -m 0755 /var/www/SIHub-acme/.well-known/acme-challenge
sudo cp apache2/sihub-http.conf /etc/apache2/sites-available/sihub-http.conf
sudo a2enmod proxy proxy_http headers rewrite ssl
sudo a2ensite sihub-http.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

Schreibe eine harmlose Prüfdatei und rufe sie zusätzlich von einem anderen Netz ab (etwa Mobilfunk). Die Antwort muss sihub-acme-ok sein; ein Verzeichnisaufruf allein kann korrekt mit 403 enden.

printf '%s\n' sihub-acme-ok | sudo tee /var/www/SIHub-acme/.well-known/acme-challenge/check.txt
curl --fail http://sihub.at/.well-known/acme-challenge/check.txt
sudo rm /var/www/SIHub-acme/.well-known/acme-challenge/check.txt

Richte dann das Zertifikat ein:

sudo certbot certonly --webroot -w /var/www/SIHub-acme -d sihub.at
sudo test -s /etc/letsencrypt/live/sihub.at/fullchain.pem
sudo cp apache2/sihub-tls.conf /etc/apache2/sites-available/sihub-tls.conf
sudo a2dissite sihub-http.conf
sudo a2ensite sihub-tls.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
curl --fail https://sihub.at/health

Die fertige Datei erhält den ACME-Webroot für Verlängerungen und leitet andere HTTP-Zugriffe auf HTTPS um. Es werden nur die neuen SIHub-Sites aktiviert/deaktiviert. Certbot-Webroot-Verfahren

sudo install -m 0755 deploy/certbot-apache-reload.sh /etc/letsencrypt/renewal-hooks/deploy/aihub-apache-reload
sudo certbot renew --dry-run
sudo systemctl list-timers certbot.timer

Ist kein automatischer Certbot-Timer installiert, richte die Verlängerung für deine Installation ausdrücklich ein. Der Deployhook prüft Apache vor dem Reload. Teste anschließend Registrierung/Login im HTTPS-Browser; Secure-Cookies funktionieren nicht als vollständiger Loginablauf über den vorherigen HTTP-Bootstrap.

6. Arbeitsbereich und Telefonie freigeben

Lege Wissen und Assistent an, teste zunächst ohne Anbieteraktionen und veröffentliche eine Version. manage.py list-workspaces zeigt die tatsächliche Arbeitsbereich-ID. Ergänze sie in AIHUB_LIVE_WORKSPACE_IDS, setze AIHUB_LIVE_ENABLED=1 erst nach der Einrichtung und aktiviere Live im Arbeitsbereich. Ein Demobereich bleibt gesperrt.

LiveKit-Keys, SIP-Trunks, Dispatch und die Anbieter sind detailliert in LiveKit-Setup beschrieben. Starte Voiceworker erst nach diesen Konfigurationen:

sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml --profile voice build voice-worker-a voice-worker-b
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml --profile voice up -d voice-worker-a voice-worker-b

Der Workerbuild installiert die gepinnten Framework-/Providerpakete und benötigt Internet; das Silero-Paket enthält sein VAD-Modell. Der Containerstart registriert Worker, löst jedoch keinen automatischen kostenpflichtigen Testanruf aus. Zwei Worker mit jeweils 15 Jobslots sind eine Konfiguration, keine gemessene Verarbeitungszusage. Für echte Hostredundanz verteile Worker und Datenbank auf getrennte Hosts mit passenden privaten/HTTPS-Verbindungen und eigenständigen VPN-Schlüsseln.

7. Monitoring, Wartung und Backups

sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml --profile monitoring up -d blackbox prometheus grafana otel

Prometheus prüft interne App-/Workerendpunkte und die öffentliche HTTPS-Domain. Grafana erhält das Dashboard „SIHub Betriebsstatus“. Zugriff erfolgt per SSH-Tunnel, nicht über öffentliche Monitoringports:

ssh -L 3000:127.0.0.1:3000 -L 9090:127.0.0.1:9090 DEIN_SSH_KONTO@SERVER_IPV4

Öffne lokal http://127.0.0.1:3000; das Grafanapasswort steht nur in der Betreiberdatei. OTel nimmt intern OTLP-Metriken entgegen; dies schaltet noch kein vollständiges Tracing jedes Appaufrufs ein. Alarmregeln werden in Prometheus ausgewertet, besitzen ohne zusätzlich eingerichteten Alertmanager aber noch keinen externen Alarmversand. Prometheus-Dockerbetrieb, Grafana-Dockerkonfiguration

Für tägliche Aufbewahrung und den optionalen Outboxworker verwende die Compose-Wartungsservices retention und notifications aus den vorbereiteten Dateien unter deploy/systemd/. Retention startet täglich ab 03:15 Europe/Vienna, Outbox minütlich. Der Voice-Reaper schließt bei aktivierter Telefonie minütlich verwaiste Räume nach Leaseablauf. Die früheren .venv-Servicebeispiele gelten für den direkten Pythonbetrieb und dürfen nicht gleichzeitig den gleichen Workload neben Docker starten.

sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps retention python manage.py purge --dry-run
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps retention
sudo docker compose --env-file deploy/.env.production -f deploy/compose.yml run --rm --no-deps notifications
sudo cp deploy/systemd/aihub-compose-retention.service deploy/systemd/aihub-compose-retention.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now aihub-compose-retention.timer

Aktiviere den Notifications-Timer auf dieselbe Weise erst nach SMTP-/Webhook-/Arbeitsbereichfreigabe. Installiere bei aktivierter Telefonie zusätzlich den Reaper; er startet keine Anrufe, kann aber abgelaufene eigene LiveKit-Räume schließen:

sudo cp deploy/systemd/aihub-compose-voice-reaper.service deploy/systemd/aihub-compose-voice-reaper.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now aihub-compose-voice-reaper.timer
sudo systemctl list-timers aihub-compose-voice-reaper.timer aihub-compose-retention.timer

Eine MariaDB-Sicherung gelingt ohne DSN/Passwort in Prozessargumenten über den vorbereiteten Helfer:

sudo bash deploy/backup-mariadb.sh

Der Helfer schreibt einen neuen Dump unter /var/backups/sihub mit Modus 0600; Betreiberkeys bleiben gesondert. Teste Restore auf einer getrennten Datenbank nach Sicherung und Restore, bevor du eine Sicherung als brauchbar einstufst. MariaDB-Dumps

Der abschließende Freigabeschritt ist die Kapazitätsabnahme. Eine funktionierende Website oder /health beweist noch keine 20 parallelen Telefonate und keine rechtliche Konformität.