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
- Start/Stop/Restart/Status für Gitea + Website-Stack
- nginx.sh
- Nginx-Konfiguration anwenden/deaktivieren
- Website/provision_instance.sh
- Instanz-Provisioning für Inventarsystem (release-basiert, Multiinstancing-aware)
- Website/launch.sh
- Start der Website (kanonisches Startskript)
- Website/launch_dev.sh
- Kompatibilitäts-Wrapper auf launch.sh
- Website/stop.sh
- Stoppt den Website-Stack (docker compose down)
- Website/start_docker_build.sh
- Build/Start-Helfer für Website-Container
- Website/sync_dev_hosts.sh
- Synchronisiert dynamische Subdomains in /etc/hosts
Setup-Skripte (optional, aktiv)
- setup-first-install.sh
- Führt Erstinstallation in einem Ablauf aus (Start, Nginx, Hosts-Sync-Service, Autostart-Service)
- setup-hosts-sync.sh
- Installiert den systemd-Service für automatische Hosts-Synchronisierung
- 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
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
Befehle:
- sudo ./nginx.sh apply
- sudo ./nginx.sh disable
- sudo ./nginx.sh deactivate
Nginx-Templates:
- nginx/gitea.http.conf.template
- nginx/gitea.https.conf.template
- nginx/website.http.conf.template
- nginx/website.https.conf.template
Inventarsystem Instanzen
Admin-Oberfläche:
- Route: /admin/instances
- Menu: Schul-Instanzen
Provisioning-Flow:
- Admin wählt Nutzer, Schule, Version und optional Subdomain.
- Backend ruft Website/provision_instance.sh auf.
- Provisioning installiert release-basiert aus GitHub-Releases.
- Wenn verfügbar, wird docker-compose-multitenant.yml bevorzugt genutzt.
- 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
- Kompatibel (alt): 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.pyimWebsite/-Verzeichnis vorhanden ist; falls nicht, bricht das Skript mit einer erklärenden Fehlermeldung ab. - Nach
docker compose up -dwartet das Skript bis zu 60 Sekunden (Intervall 2s) auf einen erfolgreichen HTTP-Request (/) auf127.0.0.1:4999. - Schlägt der Health-Check fehl, sammelt das Skript automatisch folgende Diagnosedaten und gibt Hinweise aus:
docker compose psdocker 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):
# 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:
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
<meta name="description">, OpenGraph- und Twitter-Tags sowie einen Canonical-Link. Die Startseite und wichtige Unterseiten haben eine eigenemeta_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:
curl -i http://127.0.0.1:4999/health
Beispiel für Sitemap:
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
- sudo ./gitea.sh start
- sudo ./nginx.sh apply
- sudo ./gitea.sh status
Erstinstallation (automatisiert)
Für eine neue Maschine kann die Erstinstallation in einem Schritt ausgeführt werden:
sudo ./setup-first-install.sh
Standardmäßig macht das Skript:
- Startet den Stack über gitea.sh.
- Wendet nginx.sh apply an.
- Installiert den Hosts-Sync-systemd-Service.
- Installiert den Stack-Autostart-systemd-Service.
Optionen:
- --skip-start
- --skip-nginx
- --skip-hosts-sync
- --skip-autostart
Quick Verify
sudo ./gitea.sh status
sudo systemctl status invario-hosts-sync --no-pager
sudo systemctl status invario-stack-autostart --no-pager