# KI-BauIN – Server-Anforderungen (Staging und Produktion) Stand: 5. Oktober 2026. Für den ITM-Entwickler, der die Server aufbaut. Hintergründe stehen in `docs/tech-stack.md`, Termine in `docs/projektplan.md`. ## Überblick - **Zwei Umgebungen, gleich aufgebaut:** Staging (Pilot mit BauIn, ab KW 44) und Produktion (ab KW 51). Getrennte Server, getrennte Datenbanken, getrennte API-Schlüssel. - **Ein Server je Umgebung reicht:** Anwendung, MySQL, Meilisearch und Worker laufen auf derselben VM. - **Betrieb nativ**, ohne Docker: Nginx, PHP-FPM, Worker unter systemd, Cron für den Scheduler. - **Die Versionen entsprechen der Entwicklung.** Abweichungen bitte vorher abstimmen. ## Ausstattung je Server (Vorschlag) | | Vorschlag | Anmerkung | |---|---|---| | Betriebssystem | Ubuntu Server 24.04 LTS | Debian 12/13 geht auch | | CPU | 4 vCPU | | | RAM | 16 GB | Meilisearch hält Vektoren mit 4.096 Dimensionen; endgültig nach dem Meilisearch-Test (KW 41) | | Platte | 150 GB SSD, erweiterbar | Daten (MySQL, Uploads, Meilisearch) am besten auf eigenem Volume | | Verschlüsselung | Festplattenverschlüsselung gewünscht | Entscheidung mit BauIn offen | | Zeitzone | Europe/Berlin, NTP aktiv | | ## Software | Paket | Version | Hinweise | |---|---|---| | PHP (FPM und CLI) | 8.5 | Erweiterungen: bcmath, ctype, curl, dom, fileinfo, gd, iconv, intl, mbstring, opcache, openssl, pcntl, pdo_mysql, simplexml, sodium, tokenizer, xml, xmlreader, xmlwriter, zip, zlib | | Composer | 2.x | | | Node.js mit npm | 22 LTS | nur zum Bauen der Oberfläche beim Deployment | | MySQL | 8.4 LTS | utf8mb4 / utf8mb4_unicode_ci, nur auf 127.0.0.1, `max_allowed_packet` mindestens 64M | | Meilisearch | v1.54.2 (fest) | eigener systemd-Dienst, nur auf 127.0.0.1:7700, Master-Key gesetzt, `--no-analytics` | | Nginx | aktuelle Version der Distribution | `client_max_body_size 200M` (ZIP mit LVs), HTTP → HTTPS | | poppler-utils, qpdf | Distribution | Text und Seitenzahlen aus PDFs lesen, große PDFs teilen (Grenze der KI-API: 50 MB) | | git, unzip | Distribution | Deployment aus Gitea | ## Dienste - `php8.5-fpm`: Pool läuft unter einem eigenen Benutzer (Vorschlag `kibauin`). - `nginx` - `mysql` - `meilisearch`: eigener Benutzer, Daten auf dem Datenvolume. - **Worker:** zwei Instanzen `php artisan queue:work database --sleep=3 --tries=3 --max-time=3600` unter systemd, Benutzer `kibauin`, mit automatischem Neustart. - **Scheduler:** Cron-Zeile `* * * * * cd /srv/ki-bauin/current && php artisan schedule:run`. Die Vorlagen für den Nginx-Server-Block, die systemd-Units, die Cron-Zeile, das Deploy-Skript und das Backup-Skript liefern wir bis KW 44 im Repository (`deploy/`). ## Netzwerk - **Eingehend:** nur 443 sowie 80 für die Weiterleitung und die Zertifikatsausstellung. SSH nur mit Schlüssel und möglichst nur über VPN oder freigegebene IP-Adressen. - **Zugriff für BauIn:** offen, ob aus dem Internet mit Login und 2FA oder nur über VPN bzw. freigegebene IP-Adressen (Fragenkatalog B2). - **Ausgehend:** - `https://api-werk.de` (KI-API) - der Gitea von ITM (Deployment) - SMTP für Benachrichtigungen - Paketquellen für Updates Die Anwendung selbst lädt nichts von fremden Servern. - **MySQL und Meilisearch** sind nur lokal erreichbar. ## Verzeichnisse ``` /srv/ki-bauin/ ├── releases// je Deployment ein Verzeichnis ├── current -> releases/… aktive Version (Symlink) └── shared/ ├── .env Rechte 0600, Besitzer kibauin └── storage/ u. a. storage/app/private = Uploads (nie über Nginx ausliefern) ``` ## Konfiguration und Geheimnisse - **In `shared/.env`** stehen `APP_KEY`, das Datenbank-Passwort, der Meilisearch-Master-Key und die Mail-Zugangsdaten. - **Die Schlüssel der KI-API stehen nicht in der `.env`.** Sie werden in der Anwendung unter Verwaltung → Einstellungen eingetragen und verschlüsselt in der Datenbank gespeichert. Danach sind sie nur noch beschreibbar, nicht mehr lesbar. - **Der `APP_KEY` muss zusätzlich sicher außerhalb des Servers aufbewahrt werden**, z. B. im Passwortmanager. Ohne ihn lassen sich verschlüsselte Felder aus einem Backup nicht wiederherstellen. ## Backups (Vorschlag, Entscheidung mit BauIn offen) - **Was:** täglich `mysqldump --single-transaction`, dazu `shared/storage/app/private` und `shared/.env`. - **Wie:** vor dem Verlassen des Servers verschlüsseln (z. B. restic), Ziel außerhalb des Servers. - **Aufbewahrung:** z. B. 7 tägliche, 4 wöchentliche, 6 monatliche Stände. - **Meilisearch** wird nicht gesichert, der Index wird aus MySQL neu aufgebaut. - **Restore-Test:** einmal vollständig vor dem Produktivstart (KW 3/2027). ## Überwachung - **Lebenszeichen:** `https:///up` antwortet mit HTTP 200. - **Worker und Scheduler** melden Lebenszeichen, fehlgeschlagene Jobs werden gezählt. Die Artisan-Befehle dafür liefern wir. - **Alarm per Mail**, wenn die Anwendung, ein Worker oder der Scheduler ausfällt, wenn die Platte zu über 80 % voll ist oder wenn die KI-API nicht erreichbar ist. ## Deployment Ablauf, als Skript geliefert: 1. Code aus dem Gitea holen. 2. `composer install --no-dev --optimize-autoloader` 3. `npm ci && npm run build` 4. `php artisan migrate --force` 5. Konfiguration, Routen und Views cachen. 6. `php artisan queue:restart` 7. PHP-FPM neu laden. Wer im Betrieb deployt und Updates einspielt, ist noch offen (Fragenkatalog C12). ## Termine | Bis | Was | |---|---| | KW 43 | Staging-Server mit SSH-Zugang und Grundinstallation | | KW 44 | Staging fertig: Domain, Zertifikat, Dienste, erstes Deployment | | KW 51 | Produktionsserver fertig | | KW 3/2027 | Backups und Alarmierung in Produktion, Restore-Test | ## Offen - Standort und Rechenzentrum der Server, Festplattenverschlüsselung - Domain(s) und Zertifikat (Let's Encrypt oder eigenes) - Ziel und Zuständigkeit der Backups - Zugriff für BauIn: Internet oder VPN - SMTP-Server und Absenderadresse