Auf einem Host läuft das vollständige Produkt: das LMS, seine Hintergrundaufgaben, die Realtime- und kollaborativen Bearbeitungsdienste sowie alle optionalen Dienste hinter einem Profil. Das Design ist in Abschnitt 2 von docs/architecture/23-ops.md beschrieben.
Andere Ziele: Vercel und Cloudflare Workers betreiben nur den Web-Tier. Upgrades werden unter upgrade.md beschrieben, Sicherungen und die Wiederherstellungsübung unter backup-restore.md.
Voraussetzungen
- Docker Engine 27 oder höher mit Compose-Plugin 2.30 oder höher.
- 4 CPU-Kerne und 8 GB Speicher für den Standard-Stack; 8 Kerne und 16 GB mit
--profile full(allein ClamAV benötigt etwa 1,5 GB für Signaturen). - Einen DNS-Namen für den Web-Tier und einen zweiten für nicht vertrauenswürdige Inhalte. Es müssen verschiedene Hosts sein: SCORM-Pakete und hochgeladenes HTML laufen auf dem Content-Origin, damit sie niemals die Cookies des LMS lesen können.
- Für lokale Tests zeigen
lvh.meund*.localhostauf 127.0.0.1. Das verwendetdocker/.env.example. Der eigene Dienstproxydes Stacks stellt beide über HTTPS mit einer lokalen Zertifizierungsstelle bereit; es muss daher nichts Weiteres installiert werden (siehe „TLS“). - Die Ports 80 und 443 müssen auf dem Host frei sein (
QUIRE_PROXY_HTTP_PORTundQUIRE_PROXY_HTTPS_PORTändern sie).
Erster Start
QUIRE_APP_ORIGIN=https://learn.example.org \
QUIRE_CONTENT_ORIGIN=https://content.example-content.org \
QUIRE_SETUP_ADMIN_EMAIL=you@example.org \
docker/scripts/init-env.sh
docker compose -f docker/compose.yaml up -d --build
docker compose -f docker/compose.yaml logs initdocker/scripts/init-env.sh erstellt docker/.env aus docker/.env.example und generiert alle Secrets (Datenbankpasswörter, Signatur- und Master-Schlüssel sowie das Schlüsselpaar zum Starten von Inhalten) sowie den Signaturschlüssel für Audit-Prüfpunkte unter docker/secrets/audit-signing-key.pem. Compose hängt ihn als Secret in die Worker ein. Das Skript benötigt nur sh, awk und openssl und überschreibt keine vorhandene docker/.env. Kopieren Sie beide Dateien vom Host weg: Ohne QUIRE_MASTER_KEY kann eine wiederhergestellte Datenbank ihre gespeicherten Zugangsdaten nicht entschlüsseln. Um die Datei stattdessen manuell zu erstellen, führen Sie cp docker/.env.example docker/.env aus; die Datei erläutert, wie jedes Secret erzeugt wird.
Beide Origins müssen https verwenden: Der Content-Dienst lehnt in der Produktion einfaches HTTP ab, und sie dürfen keine gemeinsame registrierbare Domain haben. Der Dienst proxy beendet TLS für beide (siehe „TLS“); init-env.sh lehnt eine Origin mit http:// ab.
Der Stack startet in einer festgelegten Reihenfolge, wobei jeder Schritt auf den Abschluss des vorherigen wartet:
postgreswird gesund. Beim allerersten Start setzt sein Initialisierungsskript (docker/postgres/init/90-passwords.sh) die vier Rollenpasswörter.migratewendet jede Migration an und richtet die Job-Warteschlange sowohl in der Kontrolldatenbank als auch in jeder dedizierten Mandantendatenbank ein. Der Dienst prüft, dass sie alle übereinstimmen, und wird dann beendet (siehe docs/ops/upgrade.md). Migrationen werden bei jedem Start ausgeführt und sind idempotent; ein Upgrade besteht daher aus einem neuen Image und einem Neustart.init(apps/web/src/first-run.ts) registriert die Anwendungsdatenbank unterQUIRE_DATABASE_IDund erstellt bei gesetztemQUIRE_SETUP_ADMIN_EMAILdie erste Organisation und deren Administrator. Die Anmeldeadresse und ein generiertes Passwort werden einmalig indocker compose logs initausgegeben.web,content,worker,scheduler,collabundcentrifugostarten.proxystartet, sobaldwebundcontentgesund sind.
Öffnen Sie https://demo. gefolgt von Ihrer Anwendungsdomain (das init-Protokoll zeigt die genaue Anmeldeadresse an) und melden Sie sich an. Bei einer lokalen Installation müssen Sie zuerst der Zertifizierungsstelle des Proxys vertrauen (siehe „TLS“). Ändern Sie das generierte Passwort unter /account/security.
Ein Prozess, der ohne ein erforderliches Secret gestartet wird, verweigert den Start und nennt die fehlende Einstellung im Protokoll. Es startet nichts mit unvollständiger Konfiguration.
Dienste und Profile
| Dienst | Profil | Aufgabe |
|---|---|---|
| postgres | always | Datenbank (PostgreSQL 18 mit pgvector, erstellt aus docker/postgres.Dockerfile), mit WAL-Archivierung ab dem ersten Start |
| migrate, init | always | Einmalige Ausführung: Migrationen, dann Erststart |
| web | always | LMS auf QUIRE_HTTP_PORT (8080) |
| content | always | Origin für nicht vertrauenswürdige Inhalte auf QUIRE_CONTENT_PORT (8081) |
| worker | always | Hintergrundjobs: E-Mail, Berichte, Dateiverarbeitung und Webhooks |
| scheduler | always | Wiederkehrende Jobs: registriert die 64 Laufzeitzeitpläne und übergibt sie an den Worker; jeweils nur ein führender Prozess |
| collab | always | WebSocket für kollaboratives Bearbeiten auf QUIRE_COLLAB_HTTP_PORT (1234) |
| centrifugo | always | Realtime-Verteilung auf QUIRE_REALTIME_PORT (8000) |
| proxy | always | Caddy, TLS-Eingang auf den Ports 80 und 443 (siehe „TLS“) |
| valkey | cache |
Cache und Ratenbegrenzungen |
| clamav | scan |
Malware-Prüfung hochgeladener Dateien |
| gotenberg | preview |
Vorschauen von Office-Dateien als PDF und Darstellung von Zertifikaten |
| imgproxy | images |
Skalierte und konvertierte Bilder |
| transcoder | video |
Worker-Image mit ausschließlich LGPL-lizenziertem ffmpeg für Video-Varianten |
| seaweedfs | storage |
S3-kompatibler Objektspeicher auf diesem Host |
| otelcol | observability |
OpenTelemetry-Collector |
| mailpit | devmail |
Fängt für Tests alle ausgehenden E-Mails ab |
| backup | backup |
Einmalige Basissicherung; siehe backup-restore.md |
| backup-scheduler, backup-offsite | backup |
Basissicherung alle QUIRE_BACKUP_INTERVAL_HOURS und verschlüsselte externe Kopien mit wöchentlicher Verifizierungsübung |
| h5p | h5p |
Von Ihnen bereitgestelltes H5P-LTI-1.3-Tool-Image in QUIRE_H5P_IMAGE, auf QUIRE_H5P_PORT (8090); siehe „H5P-Anbieter verbinden“ |
--profile full startet alle optionalen Dienste außer backup und h5p. Starten Sie ein einzelnes Profil mit docker compose -f docker/compose.yaml --profile scan up -d. Auch ohne einen optionalen Dienst funktioniert Quire weiterhin und zeigt an, was fehlt: Ohne Scanner werden Uploads ungeprüft gespeichert und der Administrator wird informiert; ohne Gotenberg können Dateien heruntergeladen, aber nicht in der Vorschau angezeigt werden; ohne Transcoder wird ein Video als Originaldatei abgespielt.
Alle Images von Drittanbietern und die damit verbundenen Lizenzpflichten sind in docker/third-party-containers.yaml aufgeführt.
H5P-Anbieter verbinden
Quire bindet keine H5P-Laufzeitumgebung oder Sidecar-Komponente ein und liefert sie auch nicht mit (ADR 0019). Wenn Sie H5P verwenden, benötigen Sie ein eigenes gehostetes Abonnement oder betreiben eine selbst gehostete H5P-Instanz getrennt von Quire. Registrieren Sie den Anbieter als externes LTI-1.3-Tool und fügen Sie dessen Inhalte als Tool-Aktivitäten in Kurse ein. Quire tauscht Noten und Aktivitäts- beziehungsweise Bewertungsfortschritt über LTI Assignment and Grade Services (AGS) aus. Sendet der Anbieter auch xAPI-Anweisungen, konfigurieren Sie diese getrennt für den xAPI-Anweisungsspeicher von Quire; der Austausch von Noten und Fortschritt über AGS sendet keine xAPI-Anweisungen. Bei Moodle-Importen werden H5P-Aktivitäten als solche gemeldet, die eine LTI-Tool-Verbindung benötigen. Der Anbieter bleibt für seine H5P-Laufzeitumgebung, Inhaltserstellung, Inhaltsbibliothek und den Versuchsverlauf verantwortlich.
Um auf diesem Host eine eigene selbst gehostete Instanz zu betreiben, setzen Sie QUIRE_H5P_IMAGE auf deren Image und starten Sie das Profil h5p. Compose veröffentlicht sie auf QUIRE_H5P_PORT (8090) und speichert ihre Daten im Volume h5p-data; das Image und die damit verbundenen Pflichten bleiben in Ihrer Verantwortung.
Einstellungen
Jeder Prozess liest docker/.env. Die Vorlage docker/.env.example führt jede Einstellung mit ihrem Standardwert auf. Die Bereiche:
Adressen
| Einstellung | Bedeutung |
|---|---|
QUIRE_APP_ORIGIN |
Öffentliche Adresse des LMS, zum Beispiel https://learn.example.com |
QUIRE_CONTENT_ORIGIN |
Origin für Inhalte auf einem anderen Host |
QUIRE_PLATFORM_DOMAINS |
Kommagetrennte Domains, unter denen Organisationen liegen |
QUIRE_MARKETING_ORIGIN |
Optional. The marketing site, default https://quirelms.com. The only origin the waitlist form (POST /api/waitlist, POST /waitlist) accepts and redirects to. Comma separated; a www. variant is allowed only if listed |
QUIRE_DEPLOY_TARGET |
Hier compose. Weitere Anleitungen behandeln vercel und cloudflare |
QUIRE_TRUSTED_PROXY_CIDRS |
Proxys, deren X-Forwarded-For vertraut wird |
Secrets
| Einstellung | Bedeutung |
|---|---|
QUIRE_SECRET_KEY |
Signiert Sitzungen und Tokens. 64 hexadezimale Zeichen |
QUIRE_MASTER_KEY |
Umhüllt gespeicherte Zugangsdaten, etwa SSO- und Webhook-Secrets. 32 Byte, Base64. Web-Tier und Worker benötigen denselben Wert. Rotation: key-rotation.md |
QUIRE_MASTER_KEY_VERSION |
Versionsbezeichnung des Master-Schlüssels, ohne Angabe v1. Bei einer Rotation erhöhen |
QUIRE_MASTER_KEY_RETIRED |
Frühere Master-Schlüssel, die zum Lesen der von ihnen umhüllten Werte noch nötig sind, etwa v1=<base64>. Entfernen, wenn eine Rotation ohne ungelöste Werte abgeschlossen ist |
QUIRE_COLLAB_SIGNING_KEY |
Von Web-Tier und Collab gemeinsam zum Signieren von Bearbeitungs-Tokens verwendet |
QUIRE_BACKUP_SIGNING_KEY |
Signiert Kurssicherungen (optional) |
Bewahren Sie eine Kopie von QUIRE_MASTER_KEY getrennt von diesem Host auf. Ohne diesen Schlüssel kann eine wiederhergestellte Datenbank die enthaltenen Zugangsdaten nicht entschlüsseln.
Datenbank
| Einstellung | Bedeutung |
|---|---|
POSTGRES_PASSWORD |
Superuser-Passwort für Container und Sicherungen |
QUIRE_DB_APP_PASSWORD, QUIRE_DB_MIGRATOR_PASSWORD, QUIRE_DB_REPORT_PASSWORD, QUIRE_DB_AUDIT_PASSWORD |
Rollenpasswörter, die beim ersten Start gesetzt werden |
DATABASE_URL |
Anwendungsrolle. Für jede ihrer Abfragen gilt Row-Level-Security |
DATABASE_MIGRATOR_URL, QUIRE_MIGRATION_URL |
Migrationsrolle für migrate und init |
QUIRE_SUPERUSER_URL |
Wird nur beim Erststart verwendet |
QUIRE_REPORT_DATABASE_URL |
Schreibgeschützte Report-Rolle für Berichte und den Report-Builder |
QUIRE_AUDIT_DATABASE_URL |
Audit-Rolle für die Audit-Konsole und den SIEM-Export |
QUIRE_DATABASE_ID |
Beliebige UUID, während der gesamten Lebensdauer der Installation unverändert |
Rollenpasswörter werden nur gesetzt, wenn das Datenbank-Volume zum ersten Mal erstellt wird. Ändern Sie eines später mit ALTER ROLE und aktualisieren Sie anschließend die zugehörige URL.
QUIRE_REPORT_DATABASE_URL wird für die physische Datenbank verwendet, die durch DATABASE_URL konfiguriert ist. Legen Sie für jede weitere registrierte physische Datenbank ihre eigene Verbindungs-URL quire_report in den Umgebungen von Web-Tier und Worker fest. Tragen Sie anschließend im Feld Reporting environment variable der Datenbank den Variablennamen als env:NAME ein. Der Verweis muss auf dieselbe Datenbank wie ihre Anwendungsverbindung zeigen, idealerweise auf deren Lesereplikat. Jede Report-Oberfläche folgt dem Mandanten zur Report-Verbindung seiner eigenen Datenbank: der Report-Builder und gespeicherte Berichte, geplante Zustellungen, Report-Exporte, Analytics, das Audit-Protokoll, die REST-Auditressourcen und die Auditsuche des Assistenten. Keine davon verwendet jemals die Report-URL einer anderen Datenbank. Hat eine Datenbank keine Report-Verbindung, laufen gewöhnliche Berichte über ihre eigene Anwendungsverbindung; Analytics und alle Audit-Lesezugriffe werden dagegen abgelehnt und melden den Grund, da die Anwendungsrolle das Auditprotokoll nicht lesen kann.
Treiber
| Einstellung | In dieser Version | Hinweise |
|---|---|---|
QUIRE_STORAGE_DRIVER |
local (Standard), s3 oder azure |
local speichert Dateien im Volume files. s3 unterstützt AWS S3, R2, GCS-Interoperabilität und andere S3-kompatible Speicher mit fortsetzbaren Multipart-Uploads |
QUIRE_REALTIME_DRIVER |
inprocess (Standard), sse, centrifugo oder durable_objects |
inprocess eignet sich für einen Web-Container; bei mehreren verwenden Sie centrifugo oder sse |
QUIRE_CACHE_DRIVER |
memory (Standard), postgres oder valkey |
memory gilt pro Prozess. Verwenden Sie valkey oder postgres, damit Ratenbegrenzungen über Container hinweg gelten |
QUIRE_VIDEO_DRIVER |
ffmpeg (Standard) oder progressive_mp4 |
Oder ein gehosteter Anbieter, mit dessen Schlüsseln: Cloudflare Stream, Mux oder Bunny |
QUIRE_IMAGE_DRIVER |
noop (Standard), imgproxy oder cloudflare |
noop liefert jedes Bild in Originalgröße aus. imgproxy benötigt das Profil images und die unten aufgeführten Einstellungen; cloudflare verwendet Cloudflare Images |
QUIRE_MEETING_PROVIDER |
bbb, zoom, teams, meet, jitsi oder in_process |
Plattformstandard für Live-Sitzungen. Ohne Angabe melden Live-Sitzungen, dass sie nicht konfiguriert sind, bis eine Organisation unter Integrations, Live session provider ihr eigenes Konto verbindet. Das Konto der Organisation hat immer Vorrang vor diesem Wert. Die jeweiligen Einstellungen des Anbieters (BBB_URL und BBB_SECRET, die Variablen ZOOM_*, TEAMS_*, GOOGLE_MEET_* und JITSI_*) werden nur für den hier benannten Anbieter gelesen |
QUIRE_MEETING_REGIONS |
Kommagetrennte Liste aus eu, uk, us |
Regionen, in denen der Plattformstandard-Anbieter Besprechungen verarbeitet. Ohne Angabe wird, wie bisher, nicht geprüft, ob dies einer auf eine Region festgelegten Organisation entspricht. Das eigene Konto einer Organisation zeigt seine Regionen auf der entsprechenden Seite an |
Ein Treiberwert, der in dieser Version nicht enthalten ist, wird beim Start des Web-Tiers mit Angabe der Einstellung abgelehnt, statt stillschweigend durch den Standardwert ersetzt zu werden.
Bilder
Seiten fordern Bilder in vier festen Größen über /api/files/{id}/image/{size} an. Der Endpunkt prüft dieselben Zugriffsrechte wie für die Datei selbst und leitet dann zum Bilddienst weiter. Jede Organisation darf pro Stunde QUIRE_IMAGE_SPECS_PER_HOUR (Standardwert 2000) neue Kombinationen aus Bild und Größe anfordern. Größen, die bereits in dieser Stunde erstellt wurden, werden nicht mitgezählt. Verwenden Sie bei mehr als einem Web-Container valkey oder postgres für QUIRE_CACHE_DRIVER, damit das Limit containerübergreifend gilt.
| Einstellung | Treiber | Hinweise |
|---|---|---|
IMGPROXY_URL |
imgproxy |
Adresse, unter der Browser imgproxy erreichen, zum Beispiel https://images.example.org. Das Profil images veröffentlicht den Dienst auf QUIRE_IMAGES_PORT (8082) |
IMGPROXY_KEY, IMGPROXY_SALT |
imgproxy |
Hexadezimale Zeichenfolgen, dieselben Werte, mit denen imgproxy gestartet wird. Erzeugen Sie jeden Wert mit openssl rand -hex 32. Quire signiert jede Bildadresse damit, sodass imgproxy nichts rendert, was Quire nicht angefordert hat |
QUIRE_IMAGE_SOURCE_ORIGIN |
imgproxy mit lokalem Speicher |
Quelle, von der imgproxy Originale abruft. Compose setzt http://web:3000. Bei s3- oder azure-Speicher ruft imgproxy sie aus dem Bucket ab; diese Einstellung wird dann nicht verwendet |
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_IMAGES_TOKEN, CLOUDFLARE_IMAGES_ACCOUNT_HASH |
cloudflare |
API-Token mit Bearbeitungsrechten für Images und der Account-Hash aus Images, Developer resources. Aktivieren Sie flexible Varianten für das Konto |
CLOUDFLARE_IMAGES_SIGNING_KEY |
cloudflare |
Optional. Wenn gesetzt, sind Bilder privat und jede Adresse wird signiert und läuft ab. Ohne diesen Schlüssel sind Bilder öffentlich unter Adressen, die von QUIRE_SECRET_KEY abgeleitet sind und die niemand erraten kann |
Cloudflare Images bewahrt eine eigene Kopie jedes Originals auf, das es ausliefert. Beim Löschen einer Datei entfernt der Worker diese Kopie vor dem Original.
Warteschlange
Hintergrundjobs verwenden pg-boss in derselben Postgres-Datenbank. Es muss daher kein Warteschlangendienst betrieben oder konfiguriert werden. Jobs werden in derselben Transaktion wie die auslösende Änderung eingereiht. Ein Absturz kann deshalb keinen Job verlieren oder doppelt senden. Hier lautet der Standardwert für QUIRE_QUEUE_DRIVER pgboss; vercel und cloudflare verschieben nur einfache Benachrichtigungs- und Webhook-Zustellungen in die jeweilige Warteschlange der Plattform. Die Anleitungen für Vercel und Cloudflare beschreiben dies und erläutern, wie deren Web-Tiers Jobs einreihen.
Legen Sie eine der folgenden Einstellungen fest:
QUIRE_EMAIL_PROVIDER_CONFIG: Ein JSON-Objekt mit dem Namen eines HTTP-Anbieters und seinen Zugangsdaten, zum Beispiel{"provider":"postmark","token":"..."}. Unterstützt werden Postmark, Amazon SES, Mailgun, SendGrid und Resend.QUIRE_SMTP_URL:smtp://user:password@host:587. Nur für dieses Ziel; serverlose Ziele blockieren SMTP.
QUIRE_MAIL_FROM gibt den Absender an. Starten Sie für einen Test von Quire das Profil devmail, setzen Sie QUIRE_SMTP_URL=smtp://mailpit:1025 und lesen Sie die E-Mails unter http://localhost:8025.
Optionale Dienste
| Einstellung | Mit Profil |
|---|---|
CLAMAV_URL=tcp://clamav:3310 |
scan |
GOTENBERG_URL=http://gotenberg:3000 |
preview |
IMGPROXY_KEY, IMGPROXY_SALT |
images |
VALKEY_URL=redis://valkey:6379 |
cache |
QUIRE_OPENSEARCH_URL oder QUIRE_MEILISEARCH_URL |
Externe Suche; andernfalls Volltextsuche in Postgres |
QUIRE_BREACH_CHECK_PROVIDER=off, QUIRE_BREACH_CHECK_URL |
Prüfung auf kompromittierte Passwörter. Standardmäßig wird api.pwnedpasswords.com abgefragt (nur ein Hash-Präfix mit fünf Zeichen wird gesendet). Mit off wird die Prüfung deaktiviert; die URL verweist auf eine von Ihnen betriebene Range-API |
Beobachtbarkeit
OTEL_EXPORTER_OTLP_ENDPOINT bezeichnet den Collector, an den jeder Prozess Traces und Metriken sendet. Mit dem Profil observability lautet die Adresse http://otelcol:4318; in docker/otel-collector.yaml fügen Sie den Exporter für Ihr Backend hinzu. Wenn die Einstellung gesetzt ist, exportieren Web-Tier, Worker, Scheduler, Content- und Collab-Prozesse Spans über OTLP/HTTP (Webanfragen, Transaktionen in Mandantendatenbanken, Worker-Jobs und ausgehende Aufrufe) sowie jede Minute Metriken an denselben Endpunkt (OTEL_METRICS_EXPORTER=none deaktiviert sie). OTEL_TRACES_SAMPLER_ARG legt den Anteil der beibehaltenen Traces fest. Protokolle werden mit LOG_LEVEL an die Standardausgabe geschrieben; Compose rotiert sie. Traces enthalten keine personenbezogenen Daten.
Regionaler Egress (EU-Datenresidenz)
QUIRE_REGION=eu gibt an, dass der Stack Organisationen in der Europäischen Union bedient. Der Worker beschränkt dann alle ausgehenden Anfragen für eine auf die EU festgelegte Organisation auf eine Zulassungsliste (21-compliance.md, Abschnitt 8.1). Die Liste enthält die Hosts, die konfigurierte Dienste für die Region angeben (Speicherendpunkt, E-Mail-Anbieter, gehosteter Videoanbieter, eigene Speicherziele der Organisation, KI-Anbieter und E-Mail-Konto), die Hosts aller Dienste mit aktiver Ausnahmegenehmigung sowie die Hosts aus QUIRE_EGRESS_ALLOW_HOSTS. Anfragen an andere öffentliche Hosts werden vor dem Versand abgelehnt. Die Ablehnung wird als privacy/egress_refused im Audit-Protokoll der Organisation festgehalten und unter Compliance, Data residency aufgeführt.
| Einstellung | Werte | Auswirkung |
|---|---|---|
QUIRE_EGRESS_ALLOW_HOSTS |
Kommagetrennte Hostnamen oder *.example.org für alle Subdomains |
Zusätzliche Hosts, die eine EU-Organisation erreichen darf. Webhook-, xAPI- und SIEM-Endpunkte, Blog-Feeds und Hosts von Amazon SES gehören hierher, da sie von der Organisation selbst gewählt werden und von keinem Dienst angegeben sind. Loopback, private Adressen und Namen mit einem einzelnen Label wie web oder clamav gehören zu Ihrem eigenen Netzwerk und werden nie geprüft |
Organisationen im Vereinigten Königreich und in den USA sind nicht an eine Hostliste gebunden; für sie gelten weiterhin die Prüfungen der Dienstregion. Legen Sie die Liste beim Worker fest. Die Verwaltungsseite liest sie im Web-Tier aus, um die Zulassungsliste anzuzeigen. Tragen Sie sie deshalb in docker/.env ein, die von jedem Dienst gelesen wird.
Die Anwendungsprüfung liefert einen klaren Fehler und einen Audit-Eintrag, ist aber nicht die Garantie: Code kann fehlerhaft sein. Die Garantie ist das Netzwerk, und Compose erzwingt sie nicht für Sie. Betreiben Sie für einen regionalen Stack worker und web in einem Netzwerk mit internal: true, dessen einziger Weg nach außen über einen Egress-Proxy (zum Beispiel einen Squid- oder tinyproxy-Container) führt. Dieser sollte dieselben Hosts wie QUIRE_EGRESS_ALLOW_HOSTS sowie die Hosts der konfigurierten Dienste zulassen. Setzen Sie für diese Dienste HTTPS_PROXY. Die Residenzseite listet die exakten Hosts auf, die die Anwendung zulässt, sodass sich die beiden Listen vergleichen lassen.
Systemzustand
| Endpunkt | Bedeutung |
|---|---|
/healthz |
Liveness: Der Prozess antwortet. Compose verwendet dies für Zustandsprüfungen |
/readyz |
Readiness: Abhängigkeiten sind erreichbar; jeder optionale Dienst wird als konfiguriert oder nicht konfiguriert gemeldet. Richten Sie Ihren Load-Balancer darauf aus |
docker compose -f docker/compose.yaml ps zeigt den Zustand jedes Dienstes.
TLS
Der Dienst proxy (Caddy, Apache-2.0, docker/caddy/Caddyfile) gehört zum Standard-Stack. Er antwortet auf den Ports 80 und 443 und leitet Anfragen wie folgt weiter:
| Host oder Pfad | Ziel |
|---|---|
QUIRE_PROXY_CONTENT_HOST |
content |
QUIRE_PROXY_APP_HOST, alle Mandanten-Subdomains und benutzerdefinierten Domains |
web |
/_collab/ auf diesen Hosts |
collab (WebSocket, QUIRE_COLLAB_URL) |
/_realtime/connection/ auf diesen Hosts |
Client-WebSocket von centrifugo; dessen Server-API wird nie offengelegt |
/_images/ auf diesen Hosts |
imgproxy mit dem Profil images (IMGPROXY_URL) |
init-env.sh leitet QUIRE_PROXY_APP_HOST, QUIRE_PROXY_CONTENT_HOST, QUIRE_PROXY_HTTPS_PORT, QUIRE_COLLAB_URL und IMGPROXY_URL aus den beiden Origins ab, damit sie nicht auseinanderlaufen können. Ändern Sie sie gemeinsam, falls Sie eine Origin manuell ändern.
Zertifikate richten sich nach QUIRE_PROXY_TLS:
-
internal(Standard): Die eigene Zertifizierungsstelle von Caddy fürlocalhost,*.localhostundlvh.me. Vertrauen Sie einmalig ihrer Stammzertifizierungsstelle und rufen Sie dann Folgendes auf:docker compose -f docker/compose.yaml cp \ proxy:/data/caddy/pki/authorities/local/root.crt ./quire-local-ca.crtFügen Sie
quire-local-ca.crtdem Vertrauensspeicher des Systems oder Browsers hinzu. Beicurlübergeben Sie sie mit--cacert. -
Eine E-Mail-Adresse: automatische ACME-Zertifikate (Let’s Encrypt, danach ZeroSSL) für echte Hostnamen. DNS für beide Origins und jeden Mandantenhost muss auf diesen Host zeigen. Die Ports 80 und 443 müssen aus dem Internet erreichbar sein.
Zertifikate für Mandantenhosts werden bei deren erstem Aufruf nur dann ausgestellt, wenn web bestätigt, dass der Name zu dieser Installation gehört (/tls-allowed, über das Compose-Netzwerk angefragt). Ein Wildcard-Zertifikat und ein DNS-Anbieter-Plugin sind nicht erforderlich; eine fremde Person kann daher nicht allein dadurch, dass sie einen Namen auf den Host verweist, die Ausstellung von Zertifikaten veranlassen. Zertifikate und lokale Zertifizierungsstelle liegen im Volume caddy-data. Wenn Sie internal verwenden, sichern Sie es zusammen mit den übrigen Daten.
Der Web-Tier vertraut X-Forwarded-For nur vom Proxy: Dieser hat die feste Adresse QUIRE_PROXY_ADDRESS (Standard 172.29.64.10) im festen Subnetz QUIRE_COMPOSE_SUBNET, und QUIRE_TRUSTED_PROXY_CIDRS nennt diese Adresse. Falls sich das Subnetz mit einem Netzwerk auf dem Host überschneidet, ändern Sie beides und führen Sie docker compose down vor up aus.
Eigenen Reverse-Proxy verwenden
Wenn Sie stattdessen einen bereits vorhandenen Load-Balancer oder Proxy verwenden möchten, lassen Sie den Dienst proxy weg (docker compose up -d --scale proxy=0) und beenden Sie TLS vor web (8080), content (8081), collab (1234, WebSocket) und centrifugo (8000, WebSocket). Legen Sie die öffentlichen Adressen in QUIRE_APP_ORIGIN, QUIRE_CONTENT_ORIGIN und QUIRE_COLLAB_URL (wss://) sowie den Adressbereich Ihres Proxys in QUIRE_TRUSTED_PROXY_CIDRS fest.
Fehlerbehebung
initwird mit „QUIRE_DATABASE_ID is not a UUID“ beendet: Legen Sie den Wert mituuidgenfest.webstartet mit „did not start on compose“ wiederholt neu: Im Protokoll steht jede Einstellung, die der Dienst nicht verarbeiten kann, sowie die passende Alternative.- Ein Rollenpasswort, das nach dem ersten Start in
.envgeändert wird, hat keine Wirkung: Das Initialisierungsskript wird nur einmal ausgeführt. Verwenden SieALTER ROLE. - Uploads schlagen mit einem Scanfehler fehl, obwohl
CLAMAV_URLgesetzt ist: ClamAV lädt beim ersten Start seine Signaturen herunter; das dauert einige Minuten.