Bestehende Kunden können nur noch zusätzliche Module buchen. Bereits enthaltene Module werden auf der Preisseite deaktiviert. Gültige Herabstufungen werden separat angeboten. Herabstufungen behalten Instanz und Daten, erstellen keine neue Rechnung und aktualisieren den Modulumfang. Bestehende Schul-URLs werden automatisch vorausgefüllt. Serverseitige Validierung verhindert manipulierte Buchungsanfragen. Geänderte Dateien: main.py, preise.html, schnell_buchung.html. Validiert mit Python-Syntaxprüfung, Jinja-Template-Parsing und git diff --check. Der direkte Laufzeittest war wegen fehlendem Flask im System-Interpreter nicht möglich.
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