256 lines
8.3 KiB
Markdown
256 lines
8.3 KiB
Markdown
# 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 `<meta name="description">`, 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
|
|
``` |