# Key Service Server Dieses Repository ist auf einen schlanken, Docker-first Betrieb ausgerichtet. ## Voraussetzungen - Docker Engine + Docker Compose Plugin - Nginx - OpenSSL - Optional: UFW (Ports 80/443 werden bei aktivem UFW automatisch freigegeben) ## Script Matrix ### Core-Skripte (aktiv) - [gitea.sh](gitea.sh) - Start/Stop/Restart/Status für Gitea + Website-Stack - [nginx.sh](nginx.sh) - Nginx-Konfiguration anwenden/deaktivieren - [Website/provision_instance.sh](Website/provision_instance.sh) - Instanz-Provisioning für Inventarsystem (release-basiert, Multiinstancing-aware) - [Website/launch.sh](Website/launch.sh) - Start der Website (kanonisches Startskript) - [Website/launch_dev.sh](Website/launch_dev.sh) - Kompatibilitäts-Wrapper auf launch.sh - [Website/stop.sh](Website/stop.sh) - Stoppt den Website-Stack (docker compose down) - [Website/start_docker_build.sh](Website/start_docker_build.sh) - Build/Start-Helfer für Website-Container - [Website/sync_dev_hosts.sh](Website/sync_dev_hosts.sh) - Synchronisiert dynamische Subdomains in /etc/hosts ### Setup-Skripte (optional, aktiv) - [setup-first-install.sh](setup-first-install.sh) - Führt Erstinstallation in einem Ablauf aus (Start, Nginx, Hosts-Sync-Service, Autostart-Service) - [setup-hosts-sync.sh](setup-hosts-sync.sh) - Installiert den systemd-Service für automatische Hosts-Synchronisierung - [setup-stack-autostart.sh](setup-stack-autostart.sh) - Installiert den systemd-Service für Stack-Autostart über gitea.sh ### Legacy-Skripte (entfernt) - start-stack-on-boot.sh (durch direkten systemd-ExecStart auf gitea.sh ersetzt) - provision_instance.sh im Repo-Root (Duplikat, Website-Version ist Single Source) - Website/run.sh (alt, nicht Teil des aktuellen Flows) - Website/test.sh (alt, nicht Teil des aktuellen Flows) ## Core Betrieb ### Docker Services Datei: [gitea.sh](gitea.sh) Befehle: - sudo ./gitea.sh start - sudo ./gitea.sh stop - sudo ./gitea.sh restart - sudo ./gitea.sh status Wichtige Ports: - Gitea intern: 127.0.0.1:3001 - Gitea SSH: 2222 - Website Upstream: 127.0.0.1:4999 - MongoDB Host-Port: 127.0.0.1:27018 (oder `MONGO_PUBLISHED_PORT`) Hinweis: Die Website nutzt in Docker Compose intern den Service-Namen `mongodb` als MongoDB-Host. Wenn du die Website lokal mit `python` oder außerhalb des Containers startest, muss `MONGO_URI` auf einen hostzugänglichen MongoDB-Endpunkt zeigen. Standardmäßig ist MongoDB am Host auf `27018` veröffentlicht (konfigurierbar via `MONGO_PUBLISHED_PORT`). ### Nginx Datei: [nginx.sh](nginx.sh) Befehle: - sudo ./nginx.sh apply - sudo ./nginx.sh disable - sudo ./nginx.sh deactivate Nginx-Templates: - [nginx/gitea.http.conf.template](nginx/gitea.http.conf.template) - [nginx/gitea.https.conf.template](nginx/gitea.https.conf.template) - [nginx/website.http.conf.template](nginx/website.http.conf.template) - [nginx/website.https.conf.template](nginx/website.https.conf.template) ## Inventarsystem Instanzen Admin-Oberfläche: - Route: /admin/instances - Menu: Schul-Instanzen Provisioning-Flow: 1. Admin wählt Nutzer, Schule, Version und optional Subdomain. 2. Backend ruft [Website/provision_instance.sh](Website/provision_instance.sh) auf. 3. Provisioning installiert release-basiert aus GitHub-Releases. 4. Wenn verfügbar, wird docker-compose-multitenant.yml bevorzugt genutzt. 5. Instanzstatus wird in school_instances gespeichert. Wichtige Website-Variablen: - INSTANCE_REPO_URL (default: https://github.com/AIIrondev/legendary-octo-garbanzo) - INSTANCE_PARENT_DOMAIN (default: meine-domain) - INSTANCE_BASE_DIR (default: /opt/inventarsystem-instances) - INSTANCE_PROVISION_SCRIPT (default: Website/provision_instance.sh) Berechtigungen für Provisioning: - Docker-Zugriff - Schreibrechte auf /etc/nginx/sites-available und /etc/nginx/sites-enabled - nginx -t und nginx reload/signal-Rechte ## Admin Homepage: Live-Logs Die Admin-Seite unter /admin/system zeigt jetzt Live-Logs direkt im Frontend. Enthaltene Quellen: - Core Docker Logs (website + mongodb) - invario-hosts-sync.service - invario-stack-autostart.service - nginx.service Verhalten: - Auto-Refresh alle 20 Sekunden - Manuelles Aktualisieren per Button - Auswahl der Log-Quelle per Dropdown Hinweis: - Wenn die Website ohne Zugriff auf systemd/journalctl läuft (z. B. in eingeschränkten Containern), bleiben Core-Docker-Logs verfügbar, während Service-Logs als nicht verfügbar angezeigt werden können. ## Startskript Website - Standard: [Website/launch.sh](Website/launch.sh) - Kompatibel (alt): [Website/launch_dev.sh](Website/launch_dev.sh) ### Neues: Start-Health-Check im `launch.sh` `Website/launch.sh` führt jetzt vor dem Build eine kurze Prüfung durch und wartet nach dem Start auf eine erreichbare HTTP-Antwort: - Vor dem Build wird geprüft, ob `gunicorn.conf.py` im `Website/`-Verzeichnis vorhanden ist; falls nicht, bricht das Skript mit einer erklärenden Fehlermeldung ab. - Nach `docker compose up -d` wartet das Skript bis zu 60 Sekunden (Intervall 2s) auf einen erfolgreichen HTTP-Request (`/`) auf `127.0.0.1:4999`. - Schlägt der Health-Check fehl, sammelt das Skript automatisch folgende Diagnosedaten und gibt Hinweise aus: - `docker compose ps` - `docker logs --tail 200 website-website-1` Dies hilft, wiederkehrende Probleme (fehlende Dateien, fehlerhafte Container-Starts, nginx-Fehlkonfiguration) schneller zu finden. Empfohlene manuelle Prüfbefehle (bei Problemen): ```bash # Status aller Container (zeigt Port-Mappings) docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' # Prüfen, ob Host auf 4999 lauscht ss -ltnp | grep 4999 || true # Direktes Request vom Host (verbose) curl -v http://127.0.0.1:4999/ --max-time 10 # Logs des Website-Containers (letzte 200 Zeilen) docker logs --tail 200 website-website-1 # Testen von innerhalb des Containers (falls curl nicht installiert, nutze wget) docker exec -it website-website-1 curl -v http://127.0.0.1:4999/ || \ docker exec -it website-website-1 wget -qO- http://127.0.0.1:4999/ ``` Wenn du möchtest, passe ich das Timeout oder den Health-Endpoint (`/health`) an. Beispiel Start: ```bash cd Website export INSTANCE_PARENT_DOMAIN=example.de export INSTANCE_WILDCARD_CERT_FILE=/etc/nginx/certs/wildcard.example.de.crt export INSTANCE_WILDCARD_KEY_FILE=/etc/nginx/certs/wildcard.example.de.key ./launch.sh ``` ## SEO & LLM-Optimierung Die Website ist für Suchmaschinen und LLM-Scraper optimiert: - **Meta-Tags & OpenGraph**: Jede Seite enthält sinnvolle ``, OpenGraph- und Twitter-Tags sowie einen Canonical-Link. Die Startseite und wichtige Unterseiten haben eine eigene `meta_description`. - **JSON-LD**: Die Startseite enthält strukturierte Daten (Schema.org WebSite/Organization) als JSON-LD. - **Maschinenlesbare Endpunkte**: - `/health` — gibt `{ "status": "ok", "time": ... }` zurück (Status 200), geeignet für Health-Checks und Monitoring. - `/sitemap.xml` — maschinenlesbare Sitemap für Suchmaschinen, dynamisch generiert. - `/robots.txt` — erlaubt Crawling, verweist auf Sitemap, blockiert `/admin/` und Uploads. - **Server-Side Rendering**: Alle wichtigen Inhalte sind serverseitig gerendert und ohne JavaScript zugänglich. **Beispiel für Health-Check:** ```bash curl -i http://127.0.0.1:4999/health ``` **Beispiel für Sitemap:** ```bash curl -i http://127.0.0.1:4999/sitemap.xml ``` **robots.txt Beispiel:** User-agent: * Disallow: /admin/ Disallow: /static/uploads/ Allow: / Sitemap: /sitemap.xml **Hinweis:** - Die SEO-Meta-Tags können pro Seite in den Templates überschrieben werden (`meta_description`). - Die Sitemap kann bei Bedarf um weitere Seiten ergänzt werden. ## Empfohlener Ablauf 1. sudo ./gitea.sh start 2. sudo ./nginx.sh apply 3. sudo ./gitea.sh status ## Erstinstallation (automatisiert) Für eine neue Maschine kann die Erstinstallation in einem Schritt ausgeführt werden: ```bash sudo ./setup-first-install.sh ``` Standardmäßig macht das Skript: 1. Startet den Stack über gitea.sh. 2. Wendet nginx.sh apply an. 3. Installiert den Hosts-Sync-systemd-Service. 4. Installiert den Stack-Autostart-systemd-Service. Optionen: - --skip-start - --skip-nginx - --skip-hosts-sync - --skip-autostart ## Quick Verify ```bash sudo ./gitea.sh status sudo systemctl status invario-hosts-sync --no-pager sudo systemctl status invario-stack-autostart --no-pager ```