Il s’agit du produit complet sur un seul hôte : le LMS, ses tâches en arrière-plan, les services temps réel et de modification collaborative, et tous les services facultatifs activés par un profil. La conception est décrite à la section 2 de docs/architecture/23-ops.md.
Autres cibles : Vercel et Cloudflare Workers n’exécutent que la couche Web. Les mises à niveau sont décrites dans upgrade.md, et les sauvegardes et l’exercice de restauration dans backup-restore.md.
Prérequis
- Docker Engine 27 ou version ultérieure avec le module Compose 2.30 ou version ultérieure.
- 4 cœurs de processeur et 8 Go de mémoire pour la pile par défaut; 8 cœurs et 16 Go avec
--profile full(ClamAV utilise à lui seul environ 1,5 Go de signatures). - Un nom DNS pour la couche Web et un autre pour le contenu non fiable. Il doit s’agir d’hôtes différents : les modules SCORM et le HTML téléversé sont exécutés sur l’origine du contenu et ne peuvent ainsi jamais lire les témoins du LMS.
- Pour un essai local,
lvh.meet*.localhostse résolvent en 127.0.0.1, comme l’utilisedocker/.env.example. Le serviceproxyde la pile sert les deux en HTTPS avec une autorité de certification locale; aucun autre élément n’est donc installé (consultez « TLS »). - Les ports 80 et 443 doivent être libres sur l’hôte (
QUIRE_PROXY_HTTP_PORTetQUIRE_PROXY_HTTPS_PORTpermettent de les déplacer).
Premier démarrage
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 crée docker/.env à partir de docker/.env.example et génère tous les secrets (mots de passe de base de données, clés de signature et principale, paire de clés de lancement du contenu), ainsi que la clé de signature du point de contrôle d’audit à docker/secrets/audit-signing-key.pem, que Compose monte dans les processus de travail en tant que secret. Seuls sh, awk et openssl sont nécessaires, et le script refuse d’écraser un fichier docker/.env existant. Copiez les deux fichiers à l’extérieur de l’hôte : sans QUIRE_MASTER_KEY, une base restaurée ne peut pas déchiffrer les justificatifs qu’elle contient. Pour remplir le fichier à la main, exécutez plutôt cp docker/.env.example docker/.env; le fichier indique comment générer chaque secret.
Les deux origines doivent utiliser https : en production, le service de contenu refuse le HTTP non chiffré, et les origines ne doivent pas partager le même domaine enregistrable. Le service proxy termine TLS pour les deux (consultez « TLS »); init-env.sh refuse une origine http://.
La pile démarre dans un ordre fixe; chaque étape attend que la précédente soit terminée :
postgresdevient sain. Lors du tout premier démarrage, son script d’initialisation (docker/postgres/init/90-passwords.sh) définit les mots de passe des quatre rôles.migrateapplique toutes les migrations et initialise la file de tâches dans la base de contrôle et dans chaque base de locataire dédiée; il vérifie qu’elles concordent toutes, puis se termine (docs/ops/upgrade.md). Les migrations sont exécutées à chaque démarrage et sont idempotentes; une mise à niveau consiste donc à utiliser une nouvelle image et à redémarrer.init(apps/web/src/first-run.ts) inscrit la base de données de l’application sousQUIRE_DATABASE_IDet, siQUIRE_SETUP_ADMIN_EMAILest défini, crée la première organisation et son administrateur. L’adresse de connexion et un mot de passe généré sont affichés une seule fois dansdocker compose logs init.web,content,worker,scheduler,collabetcentrifugodémarrent.proxydémarre lorsquewebetcontentsont sains.
Ouvrez https://demo. suivi du domaine de votre application (le journal init affiche l’adresse de connexion exacte), puis ouvrez une session. Sur une installation locale, faites d’abord confiance à l’autorité de certification du mandataire (consultez « TLS »). Changez le mot de passe généré à /account/security.
Un processus lancé sans un secret obligatoire refuse de démarrer et nomme le paramètre manquant dans son journal. Aucun composant ne démarre avec une configuration incomplète.
Services et profils
| Service | Profil | Fonction |
|---|---|---|
| postgres | toujours | Base de données (PostgreSQL 18 avec pgvector, compilé à partir de docker/postgres.Dockerfile), avec archivage du WAL dès le premier démarrage |
| migrate, init | toujours | Exécution ponctuelle : migrations, puis premier démarrage |
| web | toujours | LMS, sur QUIRE_HTTP_PORT (8080) |
| content | toujours | Origine du contenu non fiable, sur QUIRE_CONTENT_PORT (8081) |
| worker | toujours | Tâches en arrière-plan : courriels, rapports, traitement des fichiers et webhooks |
| scheduler | toujours | Tâches récurrentes : inscrit les 64 planifications d’exécution et les transmet au processus de travail; un seul responsable à la fois |
| collab | toujours | WebSocket de modification collaborative, sur QUIRE_COLLAB_HTTP_PORT (1234) |
| centrifugo | toujours | Diffusion temps réel, sur QUIRE_REALTIME_PORT (8000) |
| proxy | toujours | Caddy, point d’entrée TLS sur les ports 80 et 443 (consultez « TLS ») |
| valkey | cache |
Cache et limites de débit |
| clamav | scan |
Analyse des fichiers téléversés à la recherche de logiciels malveillants |
| gotenberg | preview |
Aperçus PDF de documents Office et rendu des certificats |
| imgproxy | images |
Redimensionnement et conversion d’images |
| transcoder | video |
Image du processus de travail avec ffmpeg sous licence LGPL uniquement, pour créer les rendus vidéo |
| seaweedfs | storage |
Stockage d’objets compatible S3 sur cet hôte |
| otelcol | observability |
Collecteur OpenTelemetry |
| mailpit | devmail |
Capture tous les courriels sortants pour permettre d’essayer Quire |
| backup | backup |
Sauvegarde de base ponctuelle; consultez backup-restore.md |
| backup-scheduler, backup-offsite | backup |
Sauvegarde de base toutes les QUIRE_BACKUP_INTERVAL_HOURS et copies chiffrées hors hôte avec exercice de vérification hebdomadaire |
| h5p | h5p |
Image de l’outil H5P LTI 1.3 que vous fournissez dans QUIRE_H5P_IMAGE, sur QUIRE_H5P_PORT (8090); consultez « Connecter un fournisseur H5P » |
--profile full démarre tous les services facultatifs, sauf backup et h5p. Pour en démarrer un, exécutez docker compose -f docker/compose.yaml --profile scan up -d. Quire fonctionne aussi sans service facultatif et indique ce qui manque : sans analyseur, les fichiers sont enregistrés sans être analysés et l’administrateur en est informé; sans Gotenberg, les fichiers peuvent être téléchargés, mais pas prévisualisés; sans transcodeur, la vidéo est lue dans son fichier original.
Les images de tiers et leurs obligations de licence sont répertoriées dans docker/third-party-containers.yaml.
Connecter un fournisseur H5P
Quire n’intègre ni ne distribue de moteur ou de service auxiliaire H5P (ADR 0019). Pour utiliser H5P, procurez-vous votre propre abonnement hébergé ou exploitez une instance H5P autohébergée séparément de Quire. Enregistrez ce fournisseur comme outil externe LTI 1.3 et ajoutez son contenu aux cours sous forme d’activités d’outil. Quire échange les notes et la progression des activités et de leur correction par l’intermédiaire des LTI Assignment and Grade Services (AGS). Si le fournisseur envoie aussi des énoncés xAPI, configurez-les séparément pour le magasin d’énoncés xAPI de Quire; l’échange des notes et de la progression AGS n’envoie pas d’énoncés xAPI. Les importations Moodle signalent que les activités H5P nécessitent une connexion à un outil LTI. Le fournisseur reste responsable de son moteur H5P, de la création du contenu, de sa banque de contenu et de l’historique des tentatives.
Pour exploiter votre propre instance autohébergée sur cet hôte, définissez QUIRE_H5P_IMAGE sur son image et démarrez le profil h5p. Compose la publie sur QUIRE_H5P_PORT (8090) et conserve ses données dans le volume h5p-data; l’image et les obligations qui s’y rattachent restent sous votre responsabilité.
Paramètres
Chaque processus lit docker/.env. Le modèle docker/.env.example répertorie chaque paramètre et sa valeur par défaut. Voici les groupes :
Adresses
| Paramètre | Signification |
|---|---|
QUIRE_APP_ORIGIN |
Adresse publique du LMS, par exemple https://learn.example.com |
QUIRE_CONTENT_ORIGIN |
Origine du contenu, sur un autre hôte |
QUIRE_PLATFORM_DOMAINS |
Domaines des organisations, séparés par des virgules |
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 |
compose ici. Consultez les autres guides pour vercel et cloudflare |
QUIRE_TRUSTED_PROXY_CIDRS |
Mandataires dont l’en-tête X-Forwarded-For est considéré comme fiable |
Secrets
| Paramètre | Signification |
|---|---|
QUIRE_SECRET_KEY |
Signe les sessions et les jetons. 64 caractères hexadécimaux |
QUIRE_MASTER_KEY |
Enveloppe les justificatifs conservés, comme les secrets SSO et de webhook. 32 octets, en base64. La couche Web et le processus de travail doivent partager la même valeur. Rotation : key-rotation.md |
QUIRE_MASTER_KEY_VERSION |
Étiquette de version de la clé principale, v1 si elle n’est pas définie. Incrémentez-la lors d’une rotation |
QUIRE_MASTER_KEY_RETIRED |
Anciennes clés principales encore nécessaires pour lire les valeurs qu’elles ont scellées, sous la forme v1=<base64>. Retirez-les une fois la rotation terminée sans élément non résolu |
QUIRE_COLLAB_SIGNING_KEY |
Partagée entre web et collab pour signer les jetons de modification |
QUIRE_BACKUP_SIGNING_KEY |
Signe les sauvegardes de cours (facultative) |
Gardez une copie de QUIRE_MASTER_KEY ailleurs que sur cet hôte. Une base restaurée sans cette clé ne peut pas déchiffrer les justificatifs qu’elle contient.
Base de données
| Paramètre | Signification |
|---|---|
POSTGRES_PASSWORD |
Superutilisateur utilisé par le conteneur et les sauvegardes |
QUIRE_DB_APP_PASSWORD, QUIRE_DB_MIGRATOR_PASSWORD, QUIRE_DB_REPORT_PASSWORD, QUIRE_DB_AUDIT_PASSWORD |
Mots de passe des rôles, définis au premier démarrage |
DATABASE_URL |
Rôle d’application. La sécurité au niveau des lignes s’applique à chacune de ses requêtes |
DATABASE_MIGRATOR_URL, QUIRE_MIGRATION_URL |
Rôle de migration utilisé par migrate et init |
QUIRE_SUPERUSER_URL |
Utilisé uniquement lors du premier démarrage |
QUIRE_REPORT_DATABASE_URL |
Rôle de rapport en lecture seule, pour les rapports et leur générateur |
QUIRE_AUDIT_DATABASE_URL |
Rôle d’audit, pour la console d’audit et l’exportation SIEM |
QUIRE_DATABASE_ID |
N’importe quel UUID, fixe pendant toute la durée de l’installation |
Les mots de passe des rôles ne sont appliqués que lors de la création initiale du volume de la base de données. Pour en modifier un par la suite, utilisez ALTER ROLE, puis mettez à jour l’URL correspondante.
QUIRE_REPORT_DATABASE_URL s’utilise pour la base physique configurée dans DATABASE_URL. Pour toute autre base physique enregistrée, définissez sa propre URL de connexion quire_report dans les environnements Web et de travail, puis saisissez le nom de la variable dans le champ Variable d’environnement de rapports de cette base, sous la forme env:NAME. La référence doit désigner la même base que la connexion de l’application, idéalement sa réplique en lecture seule. Chaque interface de rapport suit le locataire jusqu’à la connexion de rapport de sa propre base : générateur et rapports enregistrés, livraisons planifiées, exportations de rapports, analyses, journal d’audit, ressources d’audit REST et recherche d’audit de l’assistant. Aucune ne réutilise l’URL de rapport d’une autre base. Si une base n’a aucune connexion de rapport, les rapports ordinaires utilisent sa propre connexion d’application; les analyses et toute lecture d’audit sont refusées et l’indiquent, car le rôle d’application ne peut pas lire la piste d’audit.
Pilotes
| Paramètre | Valeurs dans cette version | Notes |
|---|---|---|
QUIRE_STORAGE_DRIVER |
local (par défaut), s3 ou azure |
local conserve les fichiers dans le volume files. s3 prend en charge AWS S3, R2, l’interopérabilité GCS et d’autres stockages compatibles S3, avec des téléversements multiparties reprenables |
QUIRE_REALTIME_DRIVER |
inprocess (par défaut), sse, centrifugo ou durable_objects |
inprocess convient à un seul conteneur Web; utilisez centrifugo ou sse s’il y en a plusieurs |
QUIRE_CACHE_DRIVER |
memory (par défaut), postgres ou valkey |
memory est propre à chaque processus; utilisez valkey ou postgres pour que les limites de débit soient appliquées entre les conteneurs |
QUIRE_VIDEO_DRIVER |
ffmpeg (par défaut) ou progressive_mp4 |
Ou un fournisseur hébergé : Cloudflare Stream, Mux ou Bunny, au moyen de leurs clés |
QUIRE_IMAGE_DRIVER |
noop (par défaut), imgproxy ou cloudflare |
noop sert chaque image dans sa taille originale. imgproxy exige le profil images et les paramètres ci-dessous; cloudflare utilise Cloudflare Images |
QUIRE_MEETING_PROVIDER |
bbb, zoom, teams, meet, jitsi ou in_process |
Fournisseur de la plateforme par défaut pour les séances en direct. S’il n’est pas défini, les séances en direct sont signalées comme non configurées jusqu’à ce qu’une organisation connecte son compte sous Intégrations, Fournisseur de séances en direct. Le compte propre à une organisation a toujours priorité. Les paramètres propres à chaque fournisseur (BBB_URL et BBB_SECRET, les variables ZOOM_*, TEAMS_*, GOOGLE_MEET_* et JITSI_*) sont lus uniquement pour le fournisseur indiqué ici |
QUIRE_MEETING_REGIONS |
Liste de valeurs eu, uk, us séparées par des virgules |
Régions où le fournisseur par défaut de la plateforme traite les réunions. Si ce paramètre n’est pas défini, la région n’est pas vérifiée par rapport aux organisations rattachées à une région, comme auparavant. Le compte propre à une organisation indique ses régions sur sa page |
Si la couche Web démarre avec une valeur de pilote absente de cette version, elle refuse cette valeur en nommant le paramètre au lieu de la remplacer silencieusement par la valeur par défaut.
Images
Les pages demandent les images en quatre tailles fixes par /api/files/{id}/image/{size}, qui vérifie les mêmes droits d’accès que le fichier, puis redirige vers le service d’images. Chaque organisation peut demander jusqu’à QUIRE_IMAGE_SPECS_PER_HOUR (2000 par défaut) nouvelles combinaisons d’image et de taille par heure; les tailles déjà produites durant l’heure ne comptent pas. Si vous avez plus d’un conteneur Web, utilisez valkey ou postgres pour QUIRE_CACHE_DRIVER afin que la limite soit commune aux conteneurs.
| Paramètre | Pilote | Notes |
|---|---|---|
IMGPROXY_URL |
imgproxy |
Adresse à laquelle les navigateurs accèdent à imgproxy, par exemple https://images.example.org. Le profil images le publie sur QUIRE_IMAGES_PORT (8082) |
IMGPROXY_KEY, IMGPROXY_SALT |
imgproxy |
Chaînes hexadécimales, identiques aux valeurs utilisées pour démarrer imgproxy. Générez-les avec openssl rand -hex 32. Quire signe chaque adresse d’image avec ces valeurs; imgproxy ne rend donc que ce que Quire lui demande |
QUIRE_IMAGE_SOURCE_ORIGIN |
imgproxy avec stockage local |
Emplacement où imgproxy récupère les originaux. Compose définit http://web:3000. Avec le stockage s3 ou azure, imgproxy récupère les images dans le compartiment; ce paramètre n’est alors pas utilisé |
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_IMAGES_TOKEN, CLOUDFLARE_IMAGES_ACCOUNT_HASH |
cloudflare |
Jeton d’API doté du droit de modifier Images et valeur de hachage du compte indiquée sous Images, Ressources pour développeurs. Activez les variantes flexibles pour le compte |
CLOUDFLARE_IMAGES_SIGNING_KEY |
cloudflare |
Facultative. Lorsqu’elle est définie, les images sont privées et chaque adresse est signée et expire. Sans cette clé, les images sont publiques, à des adresses dérivées de QUIRE_SECRET_KEY que personne ne peut deviner |
Cloudflare Images conserve sa propre copie de chaque original servi. Lorsqu’un fichier est supprimé, le processus de travail supprime cette copie avant l’original.
File d’attente
Les tâches en arrière-plan utilisent pg-boss dans la même base PostgreSQL; aucun service de file d’attente n’est donc à exécuter ou à configurer. Les tâches sont ajoutées dans la même transaction que la modification qui les a déclenchées; une panne ne peut donc ni en perdre une ni l’envoyer deux fois. Ici, QUIRE_QUEUE_DRIVER vaut pgboss, sa valeur par défaut; vercel et cloudflare déplacent uniquement les livraisons légères de notifications et de webhooks dans la file propre à la plateforme. Les guides Vercel et Cloudflare décrivent ces files et la manière dont leurs couches Web y ajoutent les tâches.
Courriel
Définissez l’un des paramètres suivants :
QUIRE_EMAIL_PROVIDER_CONFIG: objet JSON indiquant un fournisseur HTTP et ses justificatifs, comme{"provider":"postmark","token":"..."}. Postmark, Amazon SES, Mailgun, SendGrid et Resend sont pris en charge.QUIRE_SMTP_URL:smtp://user:password@host:587. Cette cible seulement; les cibles sans serveur bloquent SMTP.
QUIRE_MAIL_FROM indique l’expéditeur. Pour essayer Quire, démarrez le profil devmail, définissez QUIRE_SMTP_URL=smtp://mailpit:1025 et consultez les courriels à http://localhost:8025.
Services facultatifs
| Paramètre | Profil requis |
|---|---|
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 ou QUIRE_MEILISEARCH_URL |
Recherche externe; recherche en texte intégral PostgreSQL sinon |
QUIRE_BREACH_CHECK_PROVIDER=off, QUIRE_BREACH_CHECK_URL |
Vérification des mots de passe compromis. Activée par défaut auprès de api.pwnedpasswords.com (seul le préfixe de cinq caractères du hachage est envoyé); off la désactive et l’URL désigne une API de plage que vous hébergez |
Observabilité
OTEL_EXPORTER_OTLP_ENDPOINT indique le collecteur auquel chaque processus envoie les traces et les métriques; avec le profil observability, il vaut http://otelcol:4318, et docker/otel-collector.yaml permet d’ajouter l’exportateur de votre système. Lorsque ce paramètre est défini, les processus Web, worker, scheduler, content et collab exportent leurs traces par OTLP/HTTP (requêtes Web, transactions de base de données de locataire, tâches et appels sortants), ainsi que leurs métriques à cette même adresse chaque minute (OTEL_METRICS_EXPORTER=none les désactive). OTEL_TRACES_SAMPLER_ARG définit la proportion de traces conservées. Les journaux sont envoyés sur la sortie standard au niveau LOG_LEVEL et Compose les fait tourner. Les traces ne contiennent jamais de données personnelles.
Trafic sortant régional (résidence des données de l’UE)
QUIRE_REGION=eu indique que la pile dessert des organisations de l’Union européenne. Le processus de travail limite alors à une liste d’autorisation chaque requête sortante faite pour une organisation rattachée à l’UE (21-compliance.md, section 8.1). Cette liste comprend les hôtes déclarés pour la région par les services configurés (point de terminaison de stockage, fournisseur de courriel, fournisseur vidéo hébergé, cibles de stockage propres à l’organisation, fournisseurs d’IA et compte de courriel), les hôtes de tout service visé par une dérogation active et ceux inscrits dans QUIRE_EGRESS_ALLOW_HOSTS. Toute requête à un autre hôte public est refusée avant l’envoi; le refus est inscrit à la piste d’audit de l’organisation comme privacy/egress_refused, et apparaît sous Conformité, Résidence des données.
| Paramètre | Valeurs | Effet |
|---|---|---|
QUIRE_EGRESS_ALLOW_HOSTS |
Liste de noms d’hôte séparés par des virgules ou *.example.org pour tous les sous-domaines |
Hôtes supplémentaires qu’une organisation de l’UE peut joindre. Les points de terminaison webhook, xAPI et SIEM, les fils de blogue et les hôtes Amazon SES doivent y figurer, car ils sont choisis par l’organisation et aucun service ne les déclare. La boucle locale, les adresses privées et les noms à une seule étiquette comme web ou clamav appartiennent à votre réseau et ne sont jamais vérifiés |
Les organisations du Royaume-Uni et des États-Unis ne sont pas assujetties à une liste d’hôtes; les vérifications de région de service restent en vigueur. Définissez la liste sur le processus de travail; la page d’administration la lit sur la couche Web pour afficher la liste d’autorisation. Inscrivez-la donc dans docker/.env, lu par chaque service.
La vérification de l’application fournit une erreur claire et une entrée d’audit, mais ce n’est pas la garantie : le code peut être erroné. La garantie relève du réseau. Compose ne l’applique pas à votre place. Pour une pile régionale, placez les services worker et web sur un réseau internal: true dont la seule sortie passe par un mandataire de trafic sortant (par exemple Squid ou un conteneur tinyproxy) qui autorise les mêmes hôtes que QUIRE_EGRESS_ALLOW_HOSTS, ainsi que ceux des services configurés; définissez HTTPS_PROXY pour ces services. La page de résidence répertorie les hôtes effectivement autorisés par l’application afin que vous puissiez comparer les deux listes.
État de santé
| Point de terminaison | Signification |
|---|---|
/healthz |
Vitalité : le processus répond. Les vérifications de santé Compose l’utilisent |
/readyz |
Préparation : les dépendances sont accessibles et chaque service facultatif est indiqué comme configuré ou non. Dirigez-y votre répartiteur de charge |
docker compose -f docker/compose.yaml ps affiche l’état de santé de chaque service.
TLS
Le service proxy (Caddy, Apache-2.0, docker/caddy/Caddyfile) fait partie de la pile par défaut. Il répond sur les ports 80 et 443 et dirige le trafic ainsi :
| Hôte ou chemin | Destination |
|---|---|
QUIRE_PROXY_CONTENT_HOST |
content |
QUIRE_PROXY_APP_HOST, chaque sous-domaine de locataire et domaine personnalisé |
web |
/_collab/ sur ces hôtes |
collab (WebSocket, QUIRE_COLLAB_URL) |
/_realtime/connection/ sur ces hôtes |
WebSocket client de centrifugo; son API serveur n’est jamais exposée |
/_images/ sur ces hôtes |
imgproxy, avec le profil images (IMGPROXY_URL) |
init-env.sh déduit QUIRE_PROXY_APP_HOST, QUIRE_PROXY_CONTENT_HOST, QUIRE_PROXY_HTTPS_PORT, QUIRE_COLLAB_URL et IMGPROXY_URL des deux origines, afin qu’ils ne divergent pas. Modifiez-les ensemble si vous changez une origine à la main.
Les certificats dépendent de QUIRE_PROXY_TLS :
-
internal(valeur par défaut) : autorité de certification propre à Caddy, pourlocalhost,*.localhostetlvh.me. Faites confiance une fois à sa racine, puis récupérez-la ainsi :docker compose -f docker/compose.yaml cp \ proxy:/data/caddy/pki/authorities/local/root.crt ./quire-local-ca.crtAjoutez
quire-local-ca.crtau magasin de certificats de confiance du système ou du navigateur.curlla prend en charge avec--cacert. -
Une adresse de courriel : certificats ACME automatiques (Let’s Encrypt, puis ZeroSSL) pour les vrais noms d’hôte. Le DNS des deux origines et de chaque hôte de locataire doit pointer ici, et les ports 80 et 443 doivent être accessibles depuis Internet.
Les certificats des hôtes de locataire sont demandés à la première visite et uniquement lorsque web confirme que le nom appartient à cette installation (/tls-allowed, demandé sur le réseau Compose). Aucun certificat générique ni module d’extension de fournisseur DNS n’est nécessaire; un tiers ne peut pas provoquer une demande de certificat en faisant pointer un nom vers l’hôte. Les certificats et l’autorité locale se trouvent dans le volume caddy-data; sauvegardez-le avec le reste si vous utilisez internal.
web ne fait confiance qu’au mandataire pour X-Forwarded-For : l’adresse du mandataire est fixe (QUIRE_PROXY_ADDRESS, 172.29.64.10 par défaut) sur un sous-réseau fixe (QUIRE_COMPOSE_SUBNET), et QUIRE_TRUSTED_PROXY_CIDRS indique cette adresse. Si le sous-réseau chevauche un réseau de l’hôte, modifiez les deux et exécutez docker compose down avant up.
Derrière votre propre mandataire inverse
Pour utiliser plutôt un répartiteur de charge ou un mandataire que vous exploitez déjà, omettez proxy (docker compose up -d --scale proxy=0) et terminez TLS devant web (8080), content (8081), collab (1234, WebSocket) et centrifugo (8000, WebSocket). Définissez les adresses publiques dans QUIRE_APP_ORIGIN, QUIRE_CONTENT_ORIGIN et QUIRE_COLLAB_URL (wss://), ainsi que la plage d’adresses de votre mandataire dans QUIRE_TRUSTED_PROXY_CIDRS.
Dépannage
initse termine avec « QUIRE_DATABASE_ID is not a UUID » : définissez-le à l’aide deuuidgen.webredémarre avec « did not start on compose » : le journal répertorie chaque paramètre non pris en charge et la valeur à utiliser à sa place.- Modifier un mot de passe de rôle dans
.envaprès le premier démarrage ne change rien : le script d’initialisation ne s’exécute qu’une fois. UtilisezALTER ROLE. - Les téléversements échouent pendant l’analyse alors que
CLAMAV_URLest défini : ClamAV télécharge ses signatures au premier démarrage, ce qui prend quelques minutes.