Ontaric GmbH

Resourcecloud im eigenen Rechenzentrum

Installation, erste Schritte nach der Installation und Updates für Kunden, die Resourcecloud selbst betreiben.

Gilt für Version 5.3.0 · Stand 10.10.2026 · Entwurf

  1. Überblick
  2. Voraussetzungen
  3. Installation (Docker Compose hinter eigenem Proxy · einzelne VM mit automatischem HTTPS · Kubernetes)
  4. Ersteinrichtung
  5. Erste Schritte: Dateispeicher (S3) · Mail · Lizenz · KI · Microsoft 365 · Single Sign-On · Organisation
  6. Betrieb und Sicherung
  7. Update und Rückfall
  8. Fehlersuche
  9. Anhang: Variablen, Netzwerkverbindungen

Resourcecloud im eigenen Rechenzentrum

Installation, erste Schritte und Updates für Kunden, die Resourcecloud selbst betreiben. Gilt für Version 5.3.0 · Stand 10.10.2026 · Entwurf.

1 · Überblick

Resourcecloud wird als ein Container-Image ausgeliefert, das die Anwendung (Apache und PHP 8.5) enthält. Daran hängen eine MariaDB-Datenbank, ein Scheduler-Container und ein S3-kompatibler Objektspeicher für hochgeladene Dateien. Konfiguriert wird ausschließlich über Umgebungsvariablen; im Image wird nichts angepasst.

DienstAufgabe
rescloud-webApache und PHP. Legt beim Start das Datenbankschema an bzw. migriert es und liefert dann die Anwendung aus. Meldet sich unter /healthz.php.
rescloud-mysqlMariaDB 12.3 (mindestens 11.8, weil der KI-Index VECTOR-Spalten braucht).
rescloud-cronDasselbe Image, nur der Scheduler: Mailversand, Postfachabruf, Eskalationen, Statistiken, Lizenzmeldung. Ohne ihn werden keine Mails verschickt und nichts Geplantes läuft, die Anwendung sieht aber gesund aus.
ollama, reranker (optional)Lokale KI-Dienste für Dokumentensuche und Assistent. Nur nötig, wenn keine Daten an einen externen KI-Anbieter gehen sollen (Abschnitt 5.4).
Ein BetreiberSie betreiben, sichern und aktualisieren die Instanz selbst. Ontaric liefert Image, Compose-Datei, Skripte und Release-Notes.
Keine Daten bei OntaricIhre Daten liegen in Ihrer Datenbank und Ihrem S3-Speicher. Es gibt genau eine Verbindung nach außen, die zu Ontaric führt: die Lizenzmeldung (Abschnitt 5.3).
Eine Instanz je MandantJede Instanz hat eigene Datenbank, eigenen Speicher und ein eigenes Netz. Mehrere Instanzen (z. B. Test und Produktion) laufen nebeneinander.

2 · Voraussetzungen

2.1 Server

MinimumEmpfohlen
CPU / RAM2 vCPU / 4 GB4 vCPU / 8 GB; mit lokalen KI-Modellen zusätzlich 2–3 GB
Festplatte20 GB50 GB und mehr (Datenbank, Zwischenspeicher, Images)
BetriebssystemLinux, 64 Bit (Debian oder Ubuntu LTS; die Skripte für Weg B setzen eines von beiden voraus)
SoftwareDocker Engine 24 oder neuer mit dem Compose-Plugin (docker compose version), oder ein Kubernetes-Cluster ab 1.25

2.2 Was Sie vorab bereitstellen

WasDetails
Hostname und ZertifikatEin DNS-Name (z. B. rescloud.firma.de) und ein TLS-Zertifikat. Das Zertifikat wird am vorgeschalteten Proxy bzw. Load Balancer eingebunden (Abschnitt 3.1) oder vom mitgelieferten Traefik per Let's Encrypt bezogen (Abschnitt 3.2, braucht öffentlich erreichbare Ports 80 und 443).
Zugang zum ImageDas Image liegt in der Registry dockerreg.jannedy.de und ist nicht öffentlich. Ontaric gibt Ihnen einen eigenen Zugang (Benutzername und Token, nur lesend), mit dem Sie sich per docker login anmelden (Abschnitt 3.0). Auf Wunsch gibt es ein Image-Archiv zum Einspielen ohne Internet.
S3-SpeicherEin privater Bucket mit Zugangsschlüssel (Lesen, Schreiben, Löschen nur auf diesen Bucket). Hinweise in Abschnitt 5.1.
MailserverEin SMTP-Konto, über das die Anwendung senden darf (Abschnitt 5.2).
LizenzdatenKundenkennung und Token, die Ihnen Ontaric nach Vertragsschluss nennt (Abschnitt 5.3).
Je nach BedarfKI-Anbieter oder lokale Hardware (5.4) · Entra-ID-Administrator für Microsoft 365 (5.5) · Identitätsanbieter für Single Sign-On (5.6).

2.3 Netzwerk: wer muss wohin

Eingehend benötigen Sie nur HTTPS (443) zu Ihrem Proxy. Alle Verbindungen, die die Instanz selbst nach außen aufbaut, stehen in Anhang B. Wer eine strenge Firewall betreibt, gibt diese Ziele frei oder trägt einen Proxy ein (Abschnitt 5.7).

3 · Installation

Drei Wege, je nach Umgebung. Der erste ist der übliche im Rechenzentrum, der zweite für eine einzelne VM mit Internetzugang, der dritte für vorhandene Kubernetes-Cluster. Danach geht es für alle gleich mit Abschnitt 4 weiter.

3.0 Image beziehen

Ontaric nennt Ihnen Benutzername (customer-<ihr-name>) und Token. Der Zugang erlaubt nur das Herunterladen des Anwendungs-Images. Melden Sie sich einmal je Server an; Docker merkt sich die Anmeldung:

docker login dockerreg.jannedy.de -u customer-<ihr-name>      # Token als Passwort eingeben
docker pull dockerreg.jannedy.de/cptsolo/rescloud:5.3.0
docker pull mariadb:12.3

Verwenden Sie eine Versionsnummer (5.3.0), nicht latest: So wissen Sie, was läuft, und ein Update geschieht, wann Sie es entscheiden. Der Zugang kann ein Ablaufdatum haben; fragen Sie rechtzeitig vorher nach einem neuen Token. Ist er abgelaufen oder gesperrt, laufen bestehende Instanzen weiter, Updates lassen sich aber nicht mehr laden.

Ohne Internetzugang: Ontaric liefert das Image als Archiv. Einspielen mit docker load -i rescloud-5.3.0.tar. Mit einer eigenen Registry (Harbor, Artifactory o. ä.) setzen Sie RC_IMAGE und DB_IMAGE in der Umgebungsdatei auf die Adressen in Ihrer Registry. Die optionalen KI-Images (ollama/ollama, ghcr.io/ggml-org/llama.cpp) sind in der Compose-Datei fest eingetragen und müssen dort bei Bedarf ebenfalls angepasst werden.

3.1 Weg A: Docker Compose hinter Ihrem Proxy (Standard im Rechenzentrum)

Die Anwendung läuft per HTTP auf einem lokalen Port. Ihr Proxy oder Load Balancer terminiert TLS und leitet an diesen Port weiter.

  1. Docker installieren nach docs.docker.com/engine/install und prüfen: docker --version und docker compose version.
  2. Dateien bereitstellen. Von Ontaric erhalten Sie docker-compose.prod.yml und docker-compose.localtest.yml (der Name „localtest“ ist historisch; die Datei veröffentlicht den Webport). Mehr brauchen Sie nicht, die Anwendung steckt im Image.
    mkdir -p /opt/rescloud && cd /opt/rescloud
    # beide Dateien hierher kopieren
  3. Umgebungsdatei rescloud.env anlegen:
    cat > rescloud.env <<EOF
    RC_IMAGE=dockerreg.jannedy.de/cptsolo/rescloud:5.3.0
    DB_NAME=rescloud
    DB_USER=rescloud
    DB_PASSWORD=$(openssl rand -hex 16)
    DB_ROOT_PASSWORD=$(openssl rand -hex 16)
    # Adresse, unter der die Anwender die Anwendung aufrufen (https, ohne Schrägstrich am Ende)
    BASE_URL=https://rescloud.firma.de
    ACCESS_METHOD=https
    # Der Proxy spricht diesen Port auf dem Server an
    HTTP_PORT=8080
    # Von der Compose-Datei verlangt; bei eigenem Proxy ohne weitere Bedeutung
    TENANT=rescloud
    TENANT_HOST=rescloud.firma.de
    EOF
    chmod 600 rescloud.env
    Sichern Sie diese Datei. Sie enthält die einzigen Kopien der Datenbankpasswörter. BASE_URL und ACCESS_METHOD müssen exakt zu dem passen, was der Anwender im Browser sieht, sonst zeigen Links in Mails und manche Weiterleitungen ins Leere.
  4. Netzwerk anlegen (einmal je Server; die Compose-Datei erwartet es, auch wenn Sie keinen Traefik nutzen):
    docker network create rescloud-edge
  5. Starten:
    docker compose -f docker-compose.prod.yml -f docker-compose.localtest.yml \
      --env-file rescloud.env -p rescloud up -d \
      --scale ollama=0 --scale ollama-init=0
    Die beiden --scale-Angaben lassen die lokalen KI-Dienste weg (spart einen Download von rund 1 GB; siehe 5.4). Wiederholen Sie die Angaben bei jedem späteren up.
  6. Warten, bis die Instanz gesund ist. Der erste Start legt das Schema an und dauert etwa eine Minute.
    docker compose -p rescloud ps
    curl -s http://localhost:8080/healthz.php      # {"status":"ok"}
    Jeder andere Status nennt die fehlgeschlagene Prüfung (siehe Abschnitt 8).
  7. Proxy einrichten: Weiterleitung von https://rescloud.firma.de an http://<server>:8080. Der Proxy muss den Host-Header und X-Forwarded-Proto: https weitergeben. Für den Gesundheitstest des Proxys eignet sich /healthz.php.

3.2 Weg B: Einzelne VM mit automatischem HTTPS

Für eine frische Debian- oder Ubuntu-VM mit Internetzugang. Die Skripte installieren Docker, starten Traefik, das Zertifikate bei Let's Encrypt bezieht und erneuert, und richten die Instanz dahinter ein.

  1. DNS: A-Record auf die Server-IP, Ports 80 und 443 von außen erreichbar. Ohne auflösbaren Namen und offenen Port 80 wird kein Zertifikat ausgestellt.
  2. Dateien kopieren (Ordner deploy/ und docker-compose.prod.yml, Struktur beibehalten):
    /opt/rescloud-src/
    ├── docker-compose.prod.yml
    ├── docker-compose.localtest.yml
    └── deploy/
  3. Server vorbereiten (installiert Docker, begrenzt Container-Logs, legt das Netz an, startet Traefik; mehrfach ausführbar):
    cd /opt/rescloud-src/deploy
    sudo bash bootstrap-server.sh --acme-email [email protected] --staging
    --staging nutzt die Test-CA von Let's Encrypt: Browser warnen, aber ein DNS-Fehler kann das Limit der echten CA nicht aufbrauchen. Mit --firewall wird der Server zusätzlich auf SSH, HTTP und HTTPS eingeschränkt.
  4. Instanz anlegen (schreibt /opt/rescloud/customers/main.env mit zufälligen Passwörtern, startet und wartet auf „gesund“):
    ./new-customer.sh main rescloud.firma.de --no-ai --start
    Ohne --admin-email, --admin-name und --company erscheint der Einrichtungsassistent (Abschnitt 4). Mit allen dreien richtet sich die Instanz selbst ein und zeigt das Administratorpasswort einmalig an. --no-ai lässt die lokalen KI-Dienste weg.
  5. Echte Zertifikate, sobald die Seite lädt:
    sudo bash bootstrap-server.sh --acme-email [email protected]
    docker compose -p traefik up -d --force-recreate

3.3 Weg C: Kubernetes

Das Manifest rescloud-k8s.yaml legt Namespace rescloud, Datenbank (StatefulSet), Web- und Scheduler-Deployment, Volumes, Services und Ingress an. Alle Stellen, die Sie anpassen müssen, sind mit # <-- CHANGE: markiert.

ObjektEinstellung
Secret rescloud-dbDB_PASSWORD, DB_ROOT_PASSWORD: lange Zufallswerte
ConfigMap rescloud-configrc_baseurl (öffentliche URL), rc_mailsender
Deploymentsimage: dockerreg.jannedy.de/cptsolo/rescloud:5.3.0 (bei Web und Cron gleich, ggf. aus Ihrer Registry); dazu imagePullSecrets ergänzen (das Manifest enthält keinen):
kubectl -n rescloud create secret docker-registry regcred --docker-server=dockerreg.jannedy.de --docker-username=customer-<ihr-name> --docker-password=<token>
IngressHostname, TLS-Host, Ingress-Klasse, Zertifikatsaussteller
kubectl apply -f rescloud-k8s.yaml
kubectl -n rescloud get pods -w
kubectl -n rescloud logs deploy/rescloud-web -f

4 · Ersteinrichtung

Auf einer leeren Datenbank öffnet die Anwendung den Einrichtungsassistenten unter /basic_setup. Er läuft genau einmal: sobald ein Team und ein Benutzer existieren, führt dieselbe Adresse zur normalen Anmeldung.

  1. Benutzer: Vor- und Nachname, Passwort (zweimal), E-Mail-Adresse. Diese Person wird erster Administrator und Teamleitung. Den Anmeldenamen bildet die Anwendung selbst: erster Buchstabe des Vornamens plus Nachname in Kleinbuchstaben (Anna Schmidt → aschmidt). Ein Bild lassen Sie vorerst weg, damit vor der Speicheranbindung keine Datei geschrieben wird.
  2. Firma: Name, Kürzel (höchstens sechs Buchstaben), Adresse, Land. Daraus entsteht die Startorganisation mit Bereich, Abteilung und Team sowie eine Willkommensaufgabe. Alles lässt sich später in der Organisationsverwaltung umbenennen.
  3. Fertigstellen. Das eingebaute Admin-Konto wird aus Sicherheitsgründen deaktiviert; ab jetzt gilt der soeben angelegte Benutzer.

Anmelden: Feld „E-Mail“ nimmt den Anmeldenamen (aschmidt), nicht die Adresse. Sie landen bei „Meine Aufgaben“ mit der Willkommensaufgabe. Alle Einstellungen dieses Kapitels finden Sie unten im Menü unter Admin.

Automatisierte Einrichtung: Über die Variablen rc_seed_admin_* und rc_seed_company_* kann ein Deployment den ersten Administrator vorgeben; der Assistent erscheint dann nicht. Bei handgeschriebenen Umgebungsdateien muss jedes $ im Passwort-Hash zu $$ verdoppelt werden, sonst kommt der Hash gekürzt an. new-customer.sh übernimmt das.

5 · Erste Schritte nach der Installation

Reihenfolge: zuerst der Dateispeicher, bevor jemand etwas hochlädt; Mail und Lizenz direkt danach; KI, Microsoft 365 und Single Sign-On in der Reihenfolge, in der Ihr Projekt sie braucht. Alle Schritte brauchen die Rolle RC Admin.

5.1 Dateispeicher (S3)

Ohne Anbindung landen Anhänge, eingebettete Bilder und Avatare auf der lokalen Platte des Web-Containers, und ein Container-Neustart oder eine Umplanung kann sie verlieren. Bereiten Sie vorab bei Ihrem Speicheranbieter vor: einen privaten Bucket (nie öffentlich, Downloads laufen über kurzlebige signierte Links), einen Zugangsschlüssel mit Lese-, Schreib- und Löschrecht nur auf diesen Bucket, Endpunkt und Region und optional ein Präfix, damit mehrere Instanzen einen Bucket teilen können.

AnbieterEndpunktRegionPfad-Stil
Amazon S3leer lassenRegion des Buckets, z. B. eu-central-1aus
Eigener Speicher (MinIO, Ceph RGW u. a.)z. B. https://s3.firma.deRegion des Servers (üblich: us-east-1)an
Hetzner Object Storagehttps://fsn1.your-objectstorage.comfsn1, nbg1 oder hel1an

Die Region muss zum Endpunkt passen, sie geht in die Signatur ein; eine falsche wird abgelehnt, bevor der Bucket überhaupt geprüft wird.

  1. Admin → Globale Einstellungen → Datenverwaltung, Karte Externer Speicher: Externen S3-Speicher verwenden einschalten.
  2. Endpunkt, Bucket, Region, Access Key und Secret Key eintragen; Pfad-Stil wie in der Tabelle.
  3. Verbindung testen. Der Test schreibt, liest und löscht ein Probeobjekt und meldet das Ergebnis. Fehlt der Bucket, bietet der Test an, ihn anzulegen.
  4. Speicher-Einstellungen speichern. Das Secret wird in der Datenbank abgelegt und nie wieder angezeigt; bei späterem Speichern leer lassen, um es zu behalten.

Prüfen Sie Ende-zu-Ende: Datei an die Willkommensaufgabe hängen und im Bucket nachsehen. Waren schon Dateien hochgeladen, bietet die Karte Lokale Dateien nach S3 kopieren an. Eine unvollständige Konfiguration fällt still auf lokalen Speicher zurück; verlassen Sie sich daher auf den bestandenen Test.

Keine Internetverbindung? Sie benötigen nur einen S3-Endpunkt, den die Instanz im Netz erreicht, nicht notwendig einen öffentlichen.

Der Bucket nimmt außerdem den Prüfschlüssel des Änderungsprotokolls und dessen tägliche Ankerkopien auf, unter audit/ (unterhalb Ihres Präfixes). Richten Sie für dieses Präfix keine Ablauf- oder Lifecycle-Regel ein, und nehmen Sie es in Ihre Bucket-Sicherung oder Replikation auf.

Direkt danach: Audit-Schlüssel herunterladen

Resourcecloud führt ein Änderungsprotokoll darüber, wer was geändert hat. Es lässt sich nicht bearbeiten, und eine Prüfkette mit einem geheimen Schlüssel macht jede spätere Änderung erkennbar. Resourcecloud legt diesen Schlüssel selbst an und hält ihn im soeben angebundenen Bucket – Sie brauchen aber eine eigene Kopie. Ohne sie lässt sich das Protokoll nach einer Wiederherstellung, einem Wechsel des Buckets oder einem ersetzten Schlüssel nicht mehr prüfen. Als RC Admin sind Sie für diese Kopie verantwortlich.

  1. Admin → Änderungsprotokoll öffnen. Ein gelber Hinweis lautet Audit-Schlüssel herunterladen und sicher aufbewahren.
  2. Schlüssel herunterladen und die Datei dort ablegen, wo Sie wichtige Geheimnisse aufbewahren (Passwortmanager, Tresor), nicht nur auf dem Server und nicht im Datenbank-Backup.
  3. „Ich habe ihn gesichert“ anklicken. Der Hinweis verschwindet, und die Seite zeigt, wer die Kopie bestätigt hat. Nur ein RC Admin kann bestätigen; die Rolle Auditor darf ebenfalls herunterladen.

Erledigen Sie das jetzt, solange noch nichts davon abhängt. Setzen Sie RC_AUDIT_KEY selbst in der Umgebungsdatei, erscheint kein Hinweis; bewahren Sie dann diesen Wert bei Ihren übrigen Geheimnissen auf. Mehr in der Anleitung Änderungsprotokoll (docs/auditlog/index.html, auch als PDF).

5.2 Mailserver

Globale Einstellungen → Externe Dienste → Mailserver-Konfiguration: SMTP-Server und Port (587 mit STARTTLS oder 465 mit implizitem TLS), Benutzer und Passwort, Authentifizierung und TLS je nach Server, Absenderadresse (viele Server verlangen die des Kontos oder der Domäne), Markenname. Speichern und Testmail senden.

Der Scheduler leert die Mail-Warteschlange; die Testmail kann daher bis zu fünf Minuten brauchen. Bleibt das Feld leer, fällt die Instanz auf einen Standard-Server zurück, über den im eigenen Rechenzentrum nichts zugestellt wird.

5.3 Lizenz

Ihre Instanz meldet Ontaric die Anzahl der Plätze (aktive Benutzer), damit nach dem Monatsmaximum abgerechnet werden kann. Die Meldung geht von Ihrem Server nach außen, sodass kein Zugriff in Ihr Netz nötig ist.

Nach Vertragsschluss nennt Ihnen Ontaric drei Zeilen. In die Umgebungsdatei eintragen:

rc_license_customer=<Kundenkennung>
rc_license_token=<Token>
rc_license_report_url=https://licensing.resourcecloud.io/api/report

Umgebungsvariablen werden beim Erzeugen des Containers fixiert; ein Neustart liest die alten Werte erneut. Daher erneut „hochfahren“, nicht neu starten:

docker compose -f docker-compose.prod.yml -f docker-compose.localtest.yml \
  --env-file rescloud.env -p rescloud up -d --scale ollama=0 --scale ollama-init=0

Die Ausgabe muss Recreated nennen; bei Running hat Compose keine Änderung bemerkt. Prüfung: docker exec rescloud-rescloud-cron-1 printenv | grep rc_license zeigt drei Zeilen. Die Meldung läuft alle 15 Minuten.

Was übertragen wird. Mit Token: die Kundenkennung und die Platzzahl des laufenden und des Vormonats. Ohne Token meldet sich die Instanz alle 15 Minuten anonym mit Basis-URL, Hostname, Platzzahl und Schemaversion, damit nicht lizenzierte Installationen sichtbar werden. Inhalte, Personendaten und Kundendaten werden in keinem Fall übertragen. Möchten Sie die Meldung nicht zulassen, sprechen Sie das vorab mit Ontaric ab.

5.4 KI-Anbindung (optional)

Zwei Funktionen nutzen KI: die semantische Suche und Aufwandsschätzung (Einbettungen) sowie der Chat-Assistent. Ohne Einrichtung arbeitet eine schlagwortbasierte Suche. Der Assistent bekommt bewusst keine namentlichen Leistungsranglisten einzelner Personen, unabhängig vom gewählten Anbieter.

BetriebsartWas die Instanz verlässtAufwand
Vollständig lokal
(ollama und Reranker im selben Compose-Projekt, Chat über ein eigenes Modell, z. B. vLLM, Ollama oder einen internen OpenAI-kompatiblen Dienst)
Nichts. Mit AI_LOCAL_ONLY=1 darf kein KI-Aufruf die Instanz verlassen; eine Funktion, die noch nach außen zeigt, wird nicht eingeschaltet.Eigene Hardware; Einbettungen laufen auf CPU, für den Chat braucht es ein Modell auf eigener GPU
Lokale Einbettungen, externer ChatFragen und die dazu ausgewählten Textstellen gehen an den Chat-AnbieterMittel
Extern (OpenAI, Gemini, Anthropic für den Chat)Texte für Einbettungen und ChatGering

Lokale Dienste starten

In der Umgebungsdatei (new-customer.sh schreibt sie von selbst, wenn Sie --no-ai weglassen):

OLLAMA_EMBED_MODEL=embeddinggemma
AI_EMBED_BASE_URL=http://ollama:11434/v1
COMPOSE_PROFILES=reranker
AI_RERANK_BASE_URL=http://reranker:8080/v1
# optional: nichts darf die Instanz verlassen
AI_LOCAL_ONLY=1

Dann up -d ohne die --scale-Angaben. Beim ersten Start trägt die Instanz diese Adressen in Externe Dienste → Konfiguration des KI-Dienstes ein, und zwar nur in leere Felder und nur einmal; was ein Administrator später ändert, bleibt. Modelle: embeddinggemma (etwa 1,1 GB RAM beim Einbetten) oder bge-m3 (etwa 1,7 GB, etwas besser); nomic-embed-text taugt für deutsche Inhalte nicht. Ollama lädt das Modell beim ersten Start (0,3 bis 1,7 GB), der Reranker rund 440 MB von Hugging Face. Ohne Internetzugang müssen die Modelldateien vorher in die Volumes kopiert werden; fragen Sie dazu bei Ontaric nach.

Chat-Endpunkt eintragen

Globale Einstellungen → Externe Dienste → Konfiguration des KI-Dienstes: API-Schlüssel, Basis-URL, Chat-Modell; die Schalter für Schätzung/Suche und Chat-Assistent einschalten und speichern. Jeder OpenAI-kompatible Endpunkt funktioniert. Anthropic bietet keine Einbettungen an; kombinieren Sie sie mit einem lokalen Dienst oder einem anderen Anbieter. Das Feld „Proxy“ derselben Karte nutzen Sie, wenn die KI-Aufrufe über einen Proxy gehen müssen.

5.5 Microsoft 365: Kalender und Teams

Stand: Die Anbindung an Microsoft Graph wurde gegen die dokumentierte Schnittstelle entwickelt und mit einem simulierten Graph-Dienst getestet, aber noch nicht gegen einen echten Microsoft-365-Tenant. Probieren Sie sie in einem Testtenant aus, bevor Sie sie für alle einschalten.

Die Verbindung wird einmal vom Administrator für die ganze Instanz hergestellt. Niemand verbindet sein eigenes Microsoft-Konto, und Resourcecloud fragt nie nach einem Microsoft-Passwort. Dazu gibt es einen Teil ohne jede Einrichtung: Jeder Anwender kann in seinem Profil unter Kalender-Abo einen privaten Link erzeugen und in Outlook, Google Kalender oder Apple Kalender abonnieren.

Benötigte Rechte: Entra-Rolle zum Registrieren von Anwendungen und für die Administratorzustimmung (Anwendungsadministrator plus Globaler Administrator oder Administrator für privilegierte Rollen), Exchange-Online-Administrator für die Zugriffsrichtlinie, RC Admin in Resourcecloud. Die Instanz muss login.microsoftonline.com und graph.microsoft.com per HTTPS erreichen.

  1. App in Entra ID registrieren. Entra Admin Center → App-Registrierungen → Neue Registrierung, ein Mandant, keine Umleitungs-URI. Unter API-Berechtigungen → Microsoft Graph → Anwendungsberechtigungen hinzufügen und die Administratorzustimmung erteilen:
    Berechtigungwofür
    Calendars.ReadWriteTermine anlegen, verschieben, absagen; Antworten lesen; Frei/Gebucht
    OnlineMeetings.ReadWrite.AllTeams-Besprechungen
    OnlineMeetingArtifact.Read.AllTeams-Anwesenheitsbericht
    Unter Zertifikate & Geheimnisse einen Clientschlüssel erzeugen und den Wert sofort kopieren; Verzeichnis-ID (Tenant) und Anwendungs-ID (Client) von der Übersichtsseite notieren.
  2. App auf die richtigen Postfächer beschränken. Calendars.ReadWrite als Anwendungsberechtigung erreicht ohne Einschränkung jedes Postfach des Tenants. Tun Sie das, bevor Sie etwas einschalten. In der Exchange-Online-PowerShell:
    New-ApplicationAccessPolicy -AppId <Client-ID> `
      -PolicyScopeGroupId [email protected] `
      -AccessRight RestrictAccess -Description "Resourcecloud Kalender"
    Test-ApplicationAccessPolicy -AppId <Client-ID> -Identity [email protected]
    Die Gruppe ist eine E-Mail-aktivierte Sicherheitsgruppe mit den Resourcecloud-Anwendern. Die Richtlinie kann bis zu einer Stunde brauchen. Für Teams-Besprechungen gilt zusätzlich die Teams-Anwendungszugriffsrichtlinie (New-CsApplicationAccessPolicy, Grant-CsApplicationAccessPolicy) für die Organisatoren.
  3. In Resourcecloud eintragen. Globale Einstellungen → Externe Dienste → Videokonferenz: Tenant-ID, Client-ID, Clientschlüssel (Felder von Microsoft Teams). Optional eine Organisator-UPN als Ersatz für Organisatoren ohne Postfach.
  4. Schalter, aufeinander aufbauend:
    SchalterWirkungBedenken
    1 · Besprechungen in Outlook-Kalender schreibenBesprechungen werden Outlook-Termine mit Teams-Link; Exchange verschickt die Einladungen; Antworten kommen zurück.Beim Einschalten erhalten die Teilnehmer der Besprechungen der nächsten 90 Tage eine Einladung. Wählen Sie einen ruhigen Zeitpunkt oder kündigen Sie es an.
    2 · Abwesenheiten als „Abwesend“ (setzt 1 voraus)Genehmigter Urlaub und Krankheitstage erscheinen als ganztägiges „Abwesend“. Nur Daten, kein Grund, keine Art. Jeder kann im Profil widersprechen.Sichtbar für alle, die den Kalender oder Frei/Gebucht der Person sehen.
    3 · Belegte Zeit senkt die Kapazität (setzt 1 voraus, optional)Für Personen, die zugestimmt haben, werden die belegten Minuten je Arbeitstag gelesen und von der Kapazität abgezogen.Mit dem Betriebsrat abstimmen. Nur mit Einwilligung je Person, nur Zahlen, nie Inhalte.

Zuordnung der Personen: über die Entra-Objekt-ID, wenn das Konto per SCIM angelegt wurde, sonst über die E-Mail-Adresse im Profil. Gäste ohne Konto werden nicht als Teilnehmer eingetragen, sie behalten die Einladung mit ihrem persönlichen Link. Vollständige Beschreibung mit Fehlersuche: Kalender-Anbindung (Calendar Integration Guide).

5.6 Single Sign-On und Benutzeranlage (optional)

Anmeldung über Ihren Identitätsanbieter (OpenID Connect für Entra ID, Keycloak, Okta u. a.; SAML 2.0 für ADFS, Shibboleth u. a.) und automatisches Anlegen, Ändern und Deaktivieren von Konten samt Teamzuordnung per SCIM 2.0. Die Passwortanmeldung bleibt daneben bestehen, eine falsche Einstellung sperrt also niemanden aus.

  1. Globale Einstellungen → Externe Dienste → Single Sign-On (OpenID Connect) öffnen und die dort angezeigte Umleitungs-URI kopieren (https://rescloud.firma.de/oidc_callback.php).
  2. Beim Identitätsanbieter Resourcecloud als Web-Anwendung (vertraulicher Client) mit genau dieser URI registrieren; Client-ID, Client-Secret und Issuer-URL notieren.
  3. Issuer, Client-ID und Secret eintragen, Anspruchszuordnung prüfen, Single Sign-On einschalten und speichern. Die Anwendung fragt den Anbieter vorab und speichert nicht, wenn er nicht antwortet.
  4. Im privaten Fenster testen, während Sie im normalen Fenster als RC Admin angemeldet bleiben.

Voraussetzungen: https-Adresse für Resourcecloud, ausgehendes HTTPS vom Server (nicht vom Browser) zum Anbieter, mindestens ein RC Admin mit Passwort als Rückweg. Bei SAML signiert der Anbieter mit SHA-256 (SHA-1 wird abgelehnt). Ausführlich, mit Entra, Keycloak, ADFS und SCIM: Single Sign-On und Provisioning (SSO Guide).

5.7 Organisation, Benutzer und Proxy

Checkliste vor der Einladung der ersten Kollegen

6 · Betrieb und Sicherung

6.1 Was gesichert wird

WasWoHinweis
DatenbankVolume rescloud-dbAls Dump sichern (unten). Ein Kopieren des Dateisystems bei laufender Datenbank ist keine Sicherung.
Hochgeladene DateienS3-BucketVersionierung oder Replikation des Speichers nutzen. Das Volume rescloud-userdata hält nur Zwischenspeicher und alles, was vor der Speicheranbindung geschrieben wurde.
Audit-SchlüsselDatei, die Sie heruntergeladen haben (5.1); zusätzlich im Bucket unter audit/Bei den Geheimnissen ablegen, getrennt vom Server. Datenbank und Bucket gemeinsam sichern.
Umgebungsdateirescloud.env bzw. /opt/rescloud/customers/*.envEinzige Kopie der Datenbankpasswörter, getrennt vom Server ablegen.
Zertifikate (nur Weg B)Volume traefik-letsencrypt
SitzungenVolume rescloud-sessionsNicht sichern. Verlust kostet jeden eine Anmeldung.
# Datenbank sichern (täglich, per Cron; mariadb-dump, nicht mysqldump: MariaDB 12 kennt den alten Namen nicht mehr)
docker exec rescloud-rescloud-mysql-1 sh -c \
  'mariadb-dump -uroot -p"$MARIADB_ROOT_PASSWORD" --single-transaction --routines "$MARIADB_DATABASE"' \
  | gzip > rescloud-$(date +%F).sql.gz

6.2 Zurückspielen

docker compose -p rescloud stop rescloud-web rescloud-cron
gunzip -c rescloud-2026-10-10.sql.gz | docker exec -i rescloud-rescloud-mysql-1 sh -c \
  'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE"'
docker compose -p rescloud start rescloud-web rescloud-cron

Wiederherstellung gehört in einen Test vor dem Ernstfall: auf einem zweiten Server, mit der Umgebungsdatei, dem Dump und dem Bucket. Spielen Sie Datenbank und Bucket zusammen zurück: Dann liegt auch der Prüfschlüssel des Änderungsprotokolls wieder bereit. Kommt die Datenbank in einen neuen, leeren Bucket, fügt ein RC Admin den heruntergeladenen Schlüssel unter Änderungsprotokoll → Aufbewahrung und Datenschutz → Älteren Schlüssel hinzufügen ein. Der Web-Container meldet sich erst gesund, wenn das Schema zur Version des Images passt.

6.3 Überwachen

7 · Update

Ein Update tauscht das Image aus. Beim Start migriert der Web-Container das Datenbankschema und meldet sich erst dann gesund. Ontaric liefert zu jeder Version Release-Notes; lesen Sie sie vor dem Update, vor allem Hinweise zu neuen Umgebungsvariablen, geänderter Compose-Datei oder neuen Mindestversionen von MariaDB.

7.1 Vor dem Update

  1. Release-Notes lesen. Gibt es eine neue Compose-Datei oder neue Skripte, ersetzen Sie die Kopien auf dem Server vorher (die Anwendung ist im Image, die Compose-Datei nicht). Neue Volumes, Variablen oder Proxy-Labels wirken erst damit.
  2. Datenbank sichern (Abschnitt 6.1) und prüfen, dass die Datei nicht leer ist. Der Dump ist Ihr Weg zurück, falls eine Migration nicht rückgängig zu machen ist.
  3. Aktuellen Stand notieren:
    docker inspect --format '{{index .RepoDigests 0}}' dockerreg.jannedy.de/cptsolo/rescloud:5.3.0
    docker compose -p rescloud exec rescloud-web head -6 /var/www/html/htdocs/CHANGELOG
    Der Digest (sha256:…) bleibt unveränderlich und führt Sie zum exakt gleichen Image zurück, auch wenn jemand ein Tag später überschreibt.
  4. Zeitpunkt wählen. Je nach Weg gibt es eine kurze Unterbrechung (Weg A) oder keine (Weg B, Abschnitt 7.2).
  5. Erst die Testinstanz, dann die Produktion, wenn Sie beides betreiben.

7.2 Update durchführen

Weg A: Docker Compose hinter eigenem Proxy

Neue Versionsnummer in RC_IMAGE der Umgebungsdatei eintragen (z. B. dockerreg.jannedy.de/cptsolo/rescloud:5.4.0), dann:

cd /opt/rescloud
docker compose -f docker-compose.prod.yml -f docker-compose.localtest.yml --env-file rescloud.env -p rescloud pull rescloud-web
docker compose -f docker-compose.prod.yml -f docker-compose.localtest.yml \
  --env-file rescloud.env -p rescloud up -d --scale ollama=0 --scale ollama-init=0
curl -s http://localhost:8080/healthz.php

Compose ersetzt Web- und Cron-Container. Während der Web-Container migriert und startet, ist die Anwendung kurz nicht erreichbar (gemessen: etwa 16 Sekunden bei einer kleinen Datenbank, bei größeren Datenbanken und Migrationen länger). Bis /healthz.php wieder ok meldet, antwortet sie mit 503. Angemeldete Anwender bleiben angemeldet, die Sitzungen liegen im eigenen Volume. Mit der KI: ohne die --scale-Angaben, wie bei der Installation.

Weg B: Einzelne VM mit Traefik (ohne Unterbrechung)

cd /opt/rescloud-src/deploy
./upgrade_tennants.sh --check     # zeigt, was sich ändern würde
./upgrade_tennants.sh main        # Update
# oder ein bestimmtes Image
./rollout.sh main dockerreg.jannedy.de/cptsolo/rescloud:5.4.0

Die Skripte upgrade_tennants.sh ziehen standardmäßig vom Docker Hub; für diese Registry setzen Sie vorher export RC_UPGRADE_IMAGE=dockerreg.jannedy.de/cptsolo/rescloud:5.4.0.

rollout.sh startet eine zweite Replik mit dem neuen Image, wartet, bis ihre Migration fertig ist und sie gesund meldet, nimmt dann die alte aus der Rotation und beendet sie. Wird die neue nie gesund, entfernt das Skript sie und lässt die alte weiterlaufen; es ändert dabei nichts am Kunden. Jedes Update wird in /opt/rescloud/deployments.log mit Digest festgehalten.

Weg C: Kubernetes

kubectl -n rescloud set image deploy/rescloud-web  web=dockerreg.jannedy.de/cptsolo/rescloud:<neue-version>
kubectl -n rescloud set image deploy/rescloud-cron cron=dockerreg.jannedy.de/cptsolo/rescloud:<neue-version>
kubectl -n rescloud rollout status deploy/rescloud-web

Der neue Web-Pod migriert das Schema, bevor er Ready meldet. Web und Cron immer auf dieselbe Version setzen.

7.3 Nach dem Update prüfen

7.4 Rückfall

Die meisten Migrationen fügen nur Spalten oder Indizes hinzu; das alte Image läuft damit weiter. Das gilt nicht immer, die Release-Notes nennen Ausnahmen.

7.5 Datenbank-Update (MariaDB)

Die Version der Datenbank wird unabhängig vom Anwendungs-Image geführt (DB_IMAGE, Standard mariadb:12.3). Verlangt ein Release eine neuere Version, steht das in den Release-Notes; das Rollout-Skript weigert sich außerdem, ein Image zu starten, das eine neuere Datenbank braucht. Ändern Sie die Versionsnummer nicht einfach in der Umgebungsdatei: MariaDB unterstützt den direkten Sprung nur über eine Hauptversion, und 12.3 auf einem 10.11-Datenverzeichnis wird entweder abgelehnt oder schreibt es unumkehrbar um. Nutzen Sie das mitgelieferte Skript:

./upgrade_mariadb.sh main --check     # zeigt, was passieren würde
./upgrade_mariadb.sh main             # Dump, Tausch, Rückspielen, Prüfung

Es stoppt die Anwendung, sichert per Dump und als Archiv des Volumes, startet die neue Datenbank auf einem leeren Verzeichnis, spielt den Dump ein, vergleicht die Tabellenzahl und lässt erst dann die Anwendung wieder zu. Schlägt das fehl, geht es selbstständig zurück. Beide Sicherungen liegen unter /opt/rescloud/backups/<instanz>/.

8 · Fehlersuche

SymptomUrsache und Abhilfe
/healthz.php → 503 db_unreachableDatenbank noch nicht oben oder falsche DB_*-Werte. Ein nach dem ersten Start geändertes Passwort kennt die Datenbank nicht: entweder in MariaDB ändern oder das Volume neu anlegen (zerstört die Daten).
503 schema_outdated / schema_missingMigration läuft noch oder ist fehlgeschlagen; Log des Web-Containers lesen. Beim ersten Start meist nach einer Minute vorbei.
503 drainingDie Replik wird gerade bei einem Rollout ersetzt. Kein Fehler.
Web-Container beendet sich sofortEine Pflichtvariable fehlt; das Log nennt sie (DB_PASSWORD, TENANT …).
Weiterleitungen und Links in Mails zeigen auf eine falsche AdresseBASE_URL und ACCESS_METHOD müssen zur Adresse im Browser passen (http/https, Host, Port). Beim Proxy zusätzlich X-Forwarded-Proto setzen.
Keine MailsDer Reihe nach: läuft rescloud-cron? SMTP-Einstellungen und Testmail, Log des Cron-Containers, Spam-Ordner.
Datei-Upload scheitert oder Dateien verschwindenS3-Test in den Einstellungen wiederholen; Region zum Endpunkt, Pfad-Stil, Berechtigungen des Schlüssels prüfen.
Lizenz erscheint als „nicht lizenziert“ / „keine Meldung“Drei rc_license_*-Zeilen im Cron-Container? (printenv). Container neu erzeugt statt neu gestartet? Ausgehendes HTTPS zu licensing.resourcecloud.io frei?
Assistent oder Suche antworten nichtKI-Schalter eingeschaltet? Basis-URL vom Server aus erreichbar (docker exec … curl)? Bei AI_LOCAL_ONLY=1 wird eine Funktion mit externem Ziel nicht eingeschaltet.
Image lässt sich nicht laden: denied / unauthorizeddocker login dockerreg.jannedy.de mit einem neuen Token wiederholen; das alte ist abgelaufen oder gesperrt, dann bei Ontaric melden. Die Rollout-Skripte brechen dann bewusst ab, statt ein altes Image weiterzubetreiben.
Einrichtungsassistent erscheint nichtDie Datenbank enthält schon eine Firma und einen Benutzer (oder die Instanz wurde über rc_seed_* eingerichtet). Normal anmelden.
Port 8080 belegt (Weg A)HTTP_PORT und Proxy-Ziel ändern, up -d erneut.

9 · Anhang

A · Wichtige Variablen der Umgebungsdatei

VariableBedeutung
RC_IMAGEAnwendungs-Image, z. B. dockerreg.jannedy.de/cptsolo/rescloud:5.3.0; immer eine Versionsnummer oder einen Digest eintragen. (Ohne Angabe verwendet die Compose-Datei den Docker Hub, auf den Sie keinen Zugriff haben.)
DB_IMAGEDatenbank-Image (Standard mariadb:12.3)
DB_NAME, DB_USER, DB_PASSWORD, DB_ROOT_PASSWORDDatenbankzugang; Pflicht
BASE_URL, ACCESS_METHODÖffentliche Adresse und Protokoll (https)
HTTP_PORTVeröffentlichter Port bei Weg A
TENANT, TENANT_HOSTInstanzname und Hostname für die Weiterleitung durch Traefik; Pflicht, bei eigenem Proxy ohne Bedeutung
SESSION_TIMEOUTInaktivitätsgrenze in Sekunden (Standard 30000)
MAIL_SENDER, ADMIN_MAILSStandard-Absender, Adressen für Administrator-Benachrichtigungen
rc_license_customer, rc_license_token, rc_license_report_urlLizenzmeldung (5.3); Schreibweise in Kleinbuchstaben beibehalten
RC_CRON_INTERVAL, RC_CRON_PING_URL, RC_CRON_JOB_TIMEOUTTakt (Standard 300 s), Totmannschalter, Zeitgrenze je Job (900 s)
OLLAMA_EMBED_MODEL, AI_EMBED_BASE_URL, COMPOSE_PROFILES, AI_RERANK_BASE_URL, AI_LOCAL_ONLYLokale KI (5.4)
rc_seed_admin_*Vorgegebener erster Administrator (Abschnitt 4)

Eine Änderung der Umgebungsdatei wirkt erst, wenn der Container neu erzeugt wird (up -d), nicht durch restart.

B · Netzwerkverbindungen der Instanz

VonNachZweckNotwendig?
Browser der AnwenderIhr Proxy, 443Zugriff auf die Anwendungja
ProxyServer, Port HTTP_PORTWeiterleitung (Weg A)ja
Cron-Containerlicensing.resourcecloud.io, 443Lizenzmeldung: Kennung, Platzzahllaut Vertrag
Web / CronIhr S3-EndpunktDateienja (empfohlen)
Web / CronIhr SMTP-Server, 587/465Mailversandja
CronIhr IMAP-ServerPostfachabruf für Eingangs-E-Mail, falls genutztnein
Web / Cronlogin.microsoftonline.com, graph.microsoft.comMicrosoft 365 (5.5)nur bei Nutzung
WebIhr IdentitätsanbieterSingle Sign-On (5.6)nur bei Nutzung
Web / CronKI-Anbieter oder interner ModellserverKI (5.4)nur bei Nutzung
Server (Docker)Docker-Registry bzw. Ihre RegistryImages beim Updatebeim Update
Reranker (einmalig)huggingface.coModelldatei, etwa 440 MB, danach nichtsnur bei lokaler KI, entfällt bei vorab kopierten Modellen
Ollama (einmalig)ollama.comEinbettungsmodell, danach nichtsnur bei lokaler KI, entfällt bei vorab kopierten Modellen
Traefik (nur Weg B)Let's EncryptZertifikatenur Weg B

Die Datenbank und der Scheduler sind nur im privaten Netz der Instanz erreichbar und werden nicht veröffentlicht.

C · Weiterführende Anleitungen