Eine digitale Plattform zur Stärkung demokratischer Mitbestimmung an Universitäten und Hochschulen.
- 1. Quick start / Installation Guide
- 2. Projektbeschreibung
- 3. Projektstruktur
- 4. Troubleshooting
- 5. Contributing und Licensing
Bevor Sie mit der Installation beginnen, stellen Sie sicher, dass folgende Tools installiert sind:
- Node.js >= 20
- pnpm >= 8
- Docker
- Kubernetes Cluster (z.B. minikube, kind oder ein Cloud-Cluster)
- kubectl (Kubernetes CLI)
- Skaffold (für Development-Workflows)
Installieren Sie den Ingress-Controller für Kubernetes:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yamlErstellen Sie die folgenden Kubernetes Secrets mit den entsprechenden Schlüsseln in core/uvc-infra/k8s/dev oder core/uvc-infra/k8s/prod:
schluessel: JWT-Verschlüsselungsschlüssel (String)
user: MongoDB Benutzernamepassword: MongoDB Passworturi: MongoDB Connection URI
brevo_key: Brevo (ehemals Sendinblue) API-Schlüssel für E-Mail-Versandmode: Umgebungsmodus (z.B. "development", "production")public_url: Öffentliche URL der Anwendungnetwork_key: Netzwerk-Schlüssel für interne Kommunikation
endpoint_url: S3-kompatibler Storage Endpoint URLaccess_key: S3 Access Keysecret_key: S3 Secret Keybucket_name: S3 Bucket Name
.dockerconfigjson: Das Image Pull Secret für das Private Docker Registry
Für Shibboleth-Login muss zusätzlich ein Secret mit dem Namen shibboleth-sp-credentials vorhanden sein (in dev und prod). Es enthält:
sp-signing-cert.pem: SP Signing Zertifikat (PEM)sp-signing-key.pem: SP Signing Private Key (PEM)dfn-aai.pem: Zertifikat zur Signaturprüfung der DFN-AAI Metadaten (PEM)
Wichtig: Diese Dateien sind in .gitignore und werden nicht committed.
Für die lokale Entwicklung können Sie das Development-Script verwenden:
./scripts/dev.shDieses Script:
- Baut das Basis-Docker-Image (
uvc-base) falls nötig - Startet Skaffold im Development-Modus
- Synchronisiert Code-Änderungen automatisch in die laufenden Container
Wichtig: Development-Images werden lokal gebaut und nicht zu einer Docker Registry gepusht (push: false in skaffold.yaml). Die Images werden nur im lokalen Docker-Daemon verfügbar gemacht und direkt im Kubernetes-Cluster verwendet. Dies bedeutet:
- Keine Registry-Credentials für Development erforderlich
- Schnellere Build-Zyklen (kein Push nötig)
- Images sind nur lokal verfügbar
- Für Production-Deployments müssen Images zu einer Registry gepusht werden (siehe Abschnitt 1.5)
Für Production-Deployments müssen Sie zunächst Ihre Docker Registry konfigurieren.
Das Repository verwendet Platzhalter für die Docker Registry-URLs, um keine privaten Informationen zu committen. Für Production-Deployments müssen Sie eine lokale Konfigurationsdatei erstellen:
- Kopieren Sie die Vorlage:
cp .registry.local.example .registry.local- Passen Sie die Werte in
.registry.localan:
export REGISTRY_URL="ihre-registry-url.com"
export REGISTRY_SECRET="ihr-registry-secret-name"
# Shibboleth dev (required for ./scripts/dev.sh)
export SHIB_DEV_ENTITY_ID="http://apps.univocal.local.de/shibboleth"
export SHIB_DEV_DISCOVERY_URL="https://wayf.aai.dfn.de/DFN-AAI-Test/wayf"
export SHIB_DEV_METADATA_URL="http://www.aai.dfn.de/metadata/dfn-aai-test-metadata.xml"
export SHIB_DEV_SUPPORT_CONTACT="support@univocal.local.de"
export SHIB_DEV_APACHE_SERVER_NAME="apps.univocal.local.de"
# Shibboleth prod (required for ./scripts/deploy.sh)
export SHIB_PROD_ENTITY_ID="https://apps.univocal.de/shibboleth"
export SHIB_PROD_DISCOVERY_URL="https://wayf.aai.dfn.de/DFN-AAI/wayf"
export SHIB_PROD_METADATA_URL="http://www.aai.dfn.de/metadata/dfn-aai-metadata.xml"
export SHIB_PROD_SUPPORT_CONTACT="support@education-interactive.de"
export SHIB_PROD_APACHE_SERVER_NAME="https://apps.univocal.de:443"Wichtig: Die Datei .registry.local ist in .gitignore und wird nicht ins Repository committed. Sie enthält Ihre privaten Registry-Informationen.
Für Production-Deployments verwenden Sie das Deployment-Script:
./scripts/deploy.sh <version_base> prodBeispiel:
./scripts/deploy.sh 2.0.0 prodDas Script:
- Lädt die Registry- und Shibboleth-Konfiguration aus
.registry.local - Ersetzt automatisch die Platzhalter in den Kubernetes-Manifesten
- Baut die Docker-Images mit Skaffold
- Deployed die Anwendung in den Production-Cluster
- Stellt die Original-Dateien nach dem Deployment wieder her
Hinweis: Stellen Sie sicher, dass alle erforderlichen Secrets (siehe Abschnitt 1.3) im Production-Namespace vorhanden sind, bevor Sie das Deployment ausführen.
Das Repository enthält eine Beispiel-Konfigurationsdatei für die lokale Konfiguration:
Vorlage für die Docker Registry-Konfiguration. Kopieren Sie diese Datei zu .registry.local und passen Sie die Werte an:
cp .registry.local.example .registry.localDie Datei enthält:
REGISTRY_URL: URL Ihrer Docker RegistryREGISTRY_SECRET: Name des Kubernetes Secrets für Registry-Authentifizierung
Wichtig: Die Datei .registry.local ist in .gitignore und wird nicht ins Repository committed.
Wichtig: Die Secret-Dateien in core/uvc-infra/k8s/dev/secrets/ und core/uvc-infra/k8s/prod/secrets/ sollten nicht mit echten Credentials committed werden. Diese Dateien dienen als Referenz für die Struktur der benötigten Secrets.
Für neue Installationen müssen Sie Ihre eigenen Secrets erstellen. Die folgenden Secrets werden benötigt:
- environment: Umgebungsvariablen (Brevo API Key, Public URL, etc.)
- jwt-encryption-key: JWT-Verschlüsselungsschlüssel
- mongodb-cluster: MongoDB-Verbindungsdaten
- nodemailer: E-Mail-Konfiguration (falls verwendet)
- s3-config: S3-kompatibler Storage-Konfiguration
- Registry Secret (nur prod): Docker Registry Pull Secret
- shibboleth-sp-credentials (dev + prod): Shibboleth SP Credentials (SP signing cert/key + DFN-AAI metadata signature cert)
Informationen zur Erstellung von Secrets:
Weitere Informationen zur Erstellung von Kubernetes Secrets mit YAML-Dateien finden Sie in der offiziellen Kubernetes-Dokumentation:
- Kubernetes Secrets - Offizielle Dokumentation
- Erstellen von Secrets mit kubectl
- Erstellen von Secrets mit YAML
Wichtig:
- Erstellen Sie für Ihre eigene Installation neue Secrets mit Ihren eigenen Werten
- Die Secret-Dateien im Repository dienen nur als Struktur-Referenz
- Lokale Secret-Dateien mit echten Werten sollten nicht ins Repository committed werden
univocal ist eine digitale Plattform zur Stärkung demokratischer Mitbestimmung an Universitäten und Hochschulen. Sie wurde aus der Praxis studentischer Gremienarbeit heraus entwickelt und verfolgt das Ziel, demokratische Prozesse, Organisation und Kommunikation von Fachschaften, Studierendenvertretungen und Hochschulgruppen zeitgemäß, sicher und nachhaltig zu unterstützen. Mit der Veröffentlichung des vollständigen Source Codes als Open-Source-Software (OSS) wird univocal nun einer breiten Öffentlichkeit zugänglich gemacht und kann von Hochschulen, Initiativen und Entwickler:innen weitergenutzt, angepasst und weiterentwickelt werden.
Studentische Vertretungen und Hochschulgremien übernehmen an Universitäten und Hochschulen eine zentrale Rolle für demokratische Teilhabe, Interessenvertretung und politische Bildung. Gleichzeitig stehen sie vor strukturellen Herausforderungen: häufig wechselnde Amtszeiten, begrenzte zeitliche Ressourcen, fehlende Kontinuität in der Dokumentation sowie uneinheitliche oder ungeeignete digitale Werkzeuge erschweren nachhaltige Gremienarbeit erheblich.
Zwar existieren zahlreiche digitale Tools für Projektmanagement, Kommunikation, Umfragen oder Abstimmungen, diese sind jedoch oft kostenpflichtig, datenschutzrechtlich problematisch oder nicht auf die Prozesse studentischer Selbstverwaltung ausgerichtet. Insbesondere fehlen Lösungen, die speziell auf die Bedürfnisse demokratischer Gremien an Hochschulen zugeschnitten sind und dabei rechtliche, organisatorische und technische Anforderungen gleichermaßen berücksichtigen.
Vor diesem Hintergrund entstand univocal als integrierte Plattform, die typische Arbeitsprozesse studentischer Gremienarbeit bündelt und gleichzeitig den Anspruch verfolgt, demokratische Mitbestimmung niedrigschwelliger, transparenter und wirksamer zu gestalten.
univocal ist als Web-Anwendung und App nutzbar und vereint mehrere zentrale Funktionen in einer gemeinsamen, intuitiven Oberfläche. Dazu gehören unter anderem:
- Digitale Wahlen und Abstimmungen, die demokratische Entscheidungsprozesse vereinfachen und dokumentieren
- Projekt- und Aufgabenmanagement, um Vorhaben in Fachschaften und Gremien strukturiert zu planen, umzusetzen und nachzuhalten
- Budget- und Ressourcenverwaltung, die Transparenz im Umgang mit finanziellen Mitteln schafft
- Kommunikations- und Informationsfunktionen, etwa zur internen Abstimmung oder zur Öffentlichkeitsarbeit
- Dokumentation und Wissenssicherung, um Erfahrungen, Beschlüsse und Materialien über Amtszeiten hinweg verfügbar zu halten
Durch diese Bündelung entsteht eine zentrale Arbeitsumgebung, die nicht nur organisatorische Abläufe unterstützt, sondern auch demokratische Prinzipien wie Transparenz, Beteiligung und Nachvollziehbarkeit digital abbildet.
Das Projekt verwendet pnpm Workspaces zur Verwaltung eines Monorepos. Dies ermöglicht:
- Zentrale Dependency-Verwaltung
- Geteilte Bibliotheken zwischen Services
- Effiziente Build-Prozesse
- Versionierung über Workspace-Protokolle
Die Workspace-Struktur ist in pnpm-workspace.yaml definiert und umfasst:
core/*- Microserviceslib/*- Gemeinsame Bibliothekentemplates/*- Projektvorlagen
Verfügbare Root-Scripts:
pnpm build:libs # Baut alle Bibliotheken
pnpm build:services # Baut alle Services
pnpm build:all # Baut alles
pnpm install:all # Installiert alle DependenciesDie Anwendung besteht aus mehreren Microservices, die als separate Docker-Container deployed werden:
- uvc-auth: Authentifizierung und Benutzerverwaltung
- uvc-calendar: Kalenderfunktionalität und Terminverwaltung
- uvc-chat: Chat- und Messaging-Funktionen
- uvc-event: Event-Management und Veranstaltungen
- uvc-knowledge: Wissensdatenbank und Wiki-Funktionalität
- uvc-profile: Öffentliche Schüler*innenvertretungsprofile
- uvc-project: Projektmanagement und Aufgabenverwaltung
- uvc-survey: Umfragen und Abstimmungen
- uvc-tenant: Gruppenverwaltung und -administration
- uvc-web: Frontend-Webanwendung (React + Vite)
- uvc-infra: Kubernetes-Infrastruktur-Konfigurationen
Jeder Service ist ein eigenständiges Node.js/Express-Projekt mit:
- TypeScript
- MongoDB (Mongoose)
- Migrations (migrate-mongo)
- Docker-Support
Gemeinsame Bibliotheken, die von den Services verwendet werden:
- uvc-common: Gemeinsame Utilities, Middleware, Fehlerbehandlung, Services (Brevo, Notifications, Upload, etc.)
- uvc-api: API-Route-Definitionen und Typen für alle Services
Diese Bibliotheken werden als Workspace-Dependencies referenziert und müssen vor dem Build der Services kompiliert werden.
Die mobile Anwendung befindet sich im mobile/ Verzeichnis und basiert auf:
- Expo (React Native)
- Expo Router für Navigation
- TypeScript
Problem: Skaffold kann die Docker-Images nicht bauen.
Lösung:
- Stellen Sie sicher, dass Docker läuft:
docker ps - Prüfen Sie, ob der Build-Kontext korrekt ist
- Für Production: Stellen Sie sicher, dass
.registry.localexistiert und korrekt konfiguriert ist
Problem: Pods bleiben im Status Pending oder CrashLoopBackOff.
Lösung:
- Prüfen Sie die Pod-Logs:
kubectl logs <pod-name> - Stellen Sie sicher, dass alle erforderlichen Secrets vorhanden sind:
kubectl get secrets - Prüfen Sie die Pod-Beschreibung:
kubectl describe pod <pod-name> - Für Production: Stellen Sie sicher, dass das Registry-Pull-Secret korrekt konfiguriert ist
Problem: Images können nicht aus der Registry gezogen werden.
Lösung:
- Prüfen Sie, ob das Registry-Secret existiert:
kubectl get secret <registry-secret-name> - Stellen Sie sicher, dass
.registry.localdie korrekteREGISTRY_SECRETVariable enthält - Erstellen Sie das Secret manuell, falls nötig:
kubectl create secret docker-registry <secret-name> \ --docker-server=<registry-url> \ --docker-username=<username> \ --docker-password=<password> \ --docker-email=<email>
Problem: Services können sich nicht mit MongoDB verbinden.
Lösung:
- Prüfen Sie, ob das MongoDB-Secret korrekt ist:
kubectl get secret mongodb-cluster -o yaml - Stellen Sie sicher, dass MongoDB erreichbar ist
- Prüfen Sie die Connection URI im Secret
Problem: Code-Änderungen werden nicht in die Container synchronisiert.
Lösung:
- Prüfen Sie die Skaffold-Logs:
skaffold dev --verbosity=debug - Stellen Sie sicher, dass die
sync-Konfiguration inskaffold.yamlkorrekt ist - Prüfen Sie, ob die Dateien in den
infer-Pfaden liegen
Problem: Ports sind bereits belegt.
Lösung:
- Prüfen Sie, welche Prozesse die Ports verwenden:
lsof -i :<port>(macOS/Linux) odernetstat -ano | findstr :<port>(Windows) - Ändern Sie die Port-Konfiguration in den Kubernetes-Services oder beenden Sie die konkurrierenden Prozesse
Falls Sie weitere Probleme haben:
- Prüfen Sie die Issues auf GitHub für bekannte Probleme
- Erstellen Sie ein neues Issue mit:
- Beschreibung des Problems
- Schritte zur Reproduktion
- Erwartetes vs. tatsächliches Verhalten
- Logs und Fehlermeldungen
- Umgebungsinformationen (OS, Kubernetes-Version, etc.)
Beiträge sind jederzeit willkommen! Bitte lesen Sie die Contributing Guidelines und den Code of Conduct bevor Sie einen Pull Request einreichen.
Wichtige Punkte:
- Kleine, fokussierte Pull Requests bevorzugt
- Tests und Linter müssen bestehen
- Dokumentation aktualisieren
- Für größere Änderungen bitte zuerst ein Issue öffnen
Bei Fragen, Anregungen oder Problemen können Sie uns erreichen:
- E-Mail: univocal@saukels.de
- GitHub Issues: Für Bug Reports und Feature Requests nutzen Sie bitte die GitHub Issues
Wenn Sie eine Sicherheitslücke gefunden haben, melden Sie diese bitte nicht öffentlich, sondern kontaktieren Sie uns direkt:
- Security E-Mail: univocal@saukels.de
- Betreff: Bitte verwenden Sie "[SECURITY]" im Betreff
Wir werden Sicherheitsprobleme schnellstmöglich bearbeiten und Sie über den Fortschritt informieren.
univocal ist unter der Apache License 2.0 lizenziert. Details finden Sie in der LICENSE.md.
Copyright 2026 Education Interactive