---
title: "Installeer Quire met Docker Compose"
description: "Installeer Quire op jou eie infrastruktuur met Docker Compose."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/af/llms.txt
> Use this file to discover all available pages before exploring further.

# Installeer Quire met Docker Compose

<span id="installing-quire-with-docker-compose"></span>

Dit is die volledige produk op een gasheer: die LMS, sy agtergrondwerk, die intydse en samewerkende redigeerdienste en elke opsionele diens agter ’n profiel. Die ontwerp is afdeling 2 van `docs/architecture/23-ops.md`.

Ander teikens: [Vercel](/af/ops/vercel/) en [Cloudflare Workers](/af/ops/cloudflare/) loop net die webvlak. Opgraderings staan in [upgrade.md](/af/ops/upgrade/), en rugsteun en die hersteloefening in [backup-restore.md](/af/ops/backup-restore/).

## Wat jy nodig het <!--quire:what-you-need-->

- Docker Engine 27 of later met Compose-inprop 2.30 of later.
- 4 CPU-kerne en 8 GB geheue vir die verstekstapel; 8 kerne en 16 GB met `--profile full` (ClamAV alleen hou ongeveer 1.5 GB handtekeninge).
- ’n DNS-naam vir die webvlak en ’n tweede vir onbetroubare inhoud. Hulle moet verskillende gashere wees: SCORM-pakkette en opgelaaide HTML loop op die inhoudsoorsprong sodat hulle nooit die LMS-koekies kan lees nie.
- Vir ’n plaaslike toets los `lvh.me` en `*.localhost` op na 127.0.0.1, soos `docker/.env.example` gebruik. Die stapel se eie `proxy`-diens bedien albei oor https met ’n plaaslike sertifikaatowerheid, dus word niks anders geïnstalleer nie (sien “TLS”).
- Poorte 80 en 443 moet op die gasheer beskikbaar wees (`QUIRE_PROXY_HTTP_PORT` en `QUIRE_PROXY_HTTPS_PORT` verskuif hulle).

## Eerste aanvang <!--quire:first-run-->

```sh
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 init
```

`docker/scripts/init-env.sh` skryf `docker/.env` vanaf `docker/.env.example` met elke geheim gegenereer (databasiswagwoorde, ondertekenings- en hoofsleutels, inhoudbekendstellingsleutelpaar) en die ouditkontrolepunt se ondertekeningsleutel in `docker/secrets/audit-signing-key.pem`; Compose monteer dit in werkers as ’n geheim. Dit benodig net `sh`, `awk` en `openssl`, en weier om ’n bestaande `docker/.env` te oorskryf. Kopieer albei lêers van die gasheer af: sonder `QUIRE_MASTER_KEY` kan ’n herstelde databasis nie sy gestoorde aanmeldbewyse ontsyfer nie. Om die lêer eerder met die hand in te vul, voer `cp docker/.env.example docker/.env` uit; die lêer verduidelik hoe om elke geheim te genereer.

Albei oorspronge moet `https` wees: die inhouddiens weier gewone http in produksie, en hulle mag nie ’n registreerbare domein deel nie. Die `proxy`-diens beëindig TLS vir albei (sien “TLS”); `init-env.sh` weier ’n `http://`-oorsprong.

Die stapel begin in ’n vaste volgorde, en elke stap wag vir die vorige:

1. `postgres` word gesond. By die heel eerste aanvang stel sy inisialisasieskrip (`docker/postgres/init/90-passwords.sh`) die vier rolwagwoorde.
2. `migrate` pas elke migrasie toe en begin die taak-tou in die beheerdatabasis en elke toegewyde tenant-databasis, kontroleer dat almal ooreenstem en sluit dan af (docs/ops/upgrade.md). Migrasies loop met elke aanvang en is idempotent, dus is ’n opgradering ’n nuwe beeld en ’n herbegin.
3. `init` (`apps/web/src/first-run.ts`) teken die toepassingdatabasis onder `QUIRE_DATABASE_ID` aan en skep, wanneer `QUIRE_SETUP_ADMIN_EMAIL` gestel is, die eerste organisasie en administrateur. Die aanmeldadres en gegenereerde wagwoord word een keer in `docker compose logs init` vertoon.
4. `web`, `content`, `worker`, `scheduler`, `collab` en `centrifugo` begin.
5. `proxy` begin wanneer `web` en `content` gesond is.

Maak `https://demo.` gevolg deur jou toepassingdomein oop (die `init`-log druk die presiese aanmeldadres) en meld aan. Op ’n plaaslike installasie moet jy eers die proxy se sertifikaatowerheid vertrou (sien “TLS”). Verander die gegenereerde wagwoord by `/account/security`.

’n Proses wat sonder ’n vereiste geheim begin, weier om te begin en noem die ontbrekende instelling in sy log. Niks begin half gekonfigureer nie.

## Dienste en profiele <!--quire:services-and-profiles-->

| Diens | Profiel | Wat dit doen |
| --- | --- | --- |
| postgres | altyd | Die databasis (PostgreSQL 18 met pgvector, gebou vanaf `docker/postgres.Dockerfile`), met WAL geargiveer vanaf eerste aanvang |
| migrate, init | altyd | Eenmalig: migrasies, dan eerste aanvang |
| web | altyd | Die LMS op `QUIRE_HTTP_PORT` (8080) |
| content | altyd | Die onbetroubare-inhoud-oorsprong op `QUIRE_CONTENT_PORT` (8081) |
| worker | altyd | Agtergrondtake: e-pos, verslae, lêerverwerking, webhooks |
| scheduler | altyd | Herhalende take: registreer die 64 looptydskedules en gee hulle aan die werker; een leier op ’n slag |
| collab | altyd | Samewerkende-redigering-websocket op `QUIRE_COLLAB_HTTP_PORT` (1234) |
| centrifugo | altyd | Intydse verspreiding op `QUIRE_REALTIME_PORT` (8000) |
| proxy | altyd | Caddy, die TLS-voordeur op poorte 80 en 443 (sien “TLS”) |
| valkey | `cache` | Kas en tempo-limiete |
| clamav | `scan` | Wanware-skandering van oplaaie |
| gotenberg | `preview` | Office-na-PDF-voorskoue en sertifikaatweergawe |
| imgproxy | `images` | Beeldverandering in grootte en formaat |
| transcoder | `video` | Die werkerbeeld met net LGPL ffmpeg vir video-weergawes |
| seaweedfs | `storage` | S3-versoenbare objekberging op hierdie gasheer |
| otelcol | `observability` | ’n OpenTelemetry-versamelaar |
| mailpit | `devmail` | Vang alle uitgaande e-pos vir toetsing van Quire op |
| backup | `backup` | Eenmalige basisrugsteun; sien backup-restore.md |
| backup-scheduler, backup-offsite | `backup` | ’n Basisrugsteun elke `QUIRE_BACKUP_INTERVAL_HOURS` uur en geënkripteerde kopieë buite die gasheer met ’n weeklikse verifikasie-oefening |
| h5p | `h5p` | Die H5P LTI 1.3-nutsdingbeeld wat jy verskaf in `QUIRE_H5P_IMAGE`, op `QUIRE_H5P_PORT` (8090); sien “Koppel ’n H5P-verskaffer” |

`--profile full` begin elke opsionele diens behalwe `backup` en `h5p`. Begin een met `docker compose -f docker/compose.yaml --profile scan up -d`. Sonder ’n opsionele diens werk Quire steeds en verduidelik wat ontbreek: sonder skandeerder word oplaaie ongeskandeer gestoor en die administrateur ingelig; sonder Gotenberg bied lêers aflaai in plaas van voorskou; sonder transkodeerder speel video as oorspronklike lêer.

Elke derdepartybeeld en sy lisensieverpligtinge word in `docker/third-party-containers.yaml` gelys.

### Koppel ’n H5P-verskaffer <!--quire:connecting-an-h5p-provider-->

Quire sluit nie ’n H5P-looptyd of sywaartse diens in nie (ADR 0019). As jy H5P gebruik, verskaf jou eie gehuisveste intekening of bedryf jou eie selfgehuisveste H5P-instansie apart van Quire. Registreer die verskaffer as ’n LTI 1.3-eksterne nutsding en voeg sy inhoud as nutsdingaktiwiteite by kursusse. Quire ruil punte en aktiwiteit-/nasienvordering uit deur LTI Assignment and Grade Services (AGS). As die verskaffer ook xAPI-stellings stuur, stel dit apart vir Quire se xAPI-stellingstoor op; AGS-uitruil stuur nie xAPI-stellings nie. Moodle-invoere meld dat H5P-aktiwiteite ’n LTI-nutsdingverbinding nodig het. Die verskaffer bly verantwoordelik vir sy H5P-looptyd, opstel, inhoudbank en pogingsgeskiedenis.

Om jou eie selfgehuisveste instansie op hierdie gasheer te loop, stel `QUIRE_H5P_IMAGE` op sy beeld en begin die `h5p`-profiel. Compose publiseer dit op `QUIRE_H5P_PORT` (8090) en hou sy data in die `h5p-data`-volume; die beeld en gepaardgaande verpligtinge bly joune.

## Instellings <!--quire:settings-->

Elke proses lees `docker/.env`. Die sjabloon, `docker/.env.example`, lys elke instelling met sy verstekwaarde. Groepe:

### Adresse <!--quire:addresses-->

| Instelling | Betekenis |
| --- | --- |
| `QUIRE_APP_ORIGIN` | Die LMS se openbare adres, soos `https://learn.example.com` |
| `QUIRE_CONTENT_ORIGIN` | Die inhoudsoorsprong, ’n ander gasheer |
| `QUIRE_PLATFORM_DOMAINS` | Domeine waaronder organisasies woon, deur kommas geskei |
| `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`. Sien ander gidse vir `vercel` en `cloudflare` |
| `QUIRE_TRUSTED_PROXY_CIDRS` | Instaanbedieners wie se `X-Forwarded-For` vertrou word |

### Geheime <!--quire:secrets-->

| Instelling | Betekenis |
| --- | --- |
| `QUIRE_SECRET_KEY` | Onderteken sessies en tekens. 64 heksadesimale karakters |
| `QUIRE_MASTER_KEY` | Draai gestoorde aanmeldbewyse soos SSO- en webhookgeheime toe. 32 grepe, base64. Webvlak en werker benodig dieselfde waarde. Rotasie: [key-rotation.md](/af/ops/key-rotation/) |
| `QUIRE_MASTER_KEY_VERSION` | Weergawebemerking van hoofsleutel, `v1` as ongestel. Verhoog wanneer jy roteer |
| `QUIRE_MASTER_KEY_RETIRED` | Vroeëre hoofsleutels wat nog nodig is om hul verseëlde waardes te lees, as `v1=<base64>`. Verwyder nadat rotasie sonder onopgeloste waardes eindig |
| `QUIRE_COLLAB_SIGNING_KEY` | Gedeel deur web en collab om redigeertekens te onderteken |
| `QUIRE_BACKUP_SIGNING_KEY` | Onderteken kursusrugsteun (opsioneel) |

Hou ’n kopie van `QUIRE_MASTER_KEY` elders as op hierdie gasheer. ’n Databasis wat daarsonder herstel word, kan die aanmeldbewyse daarin nie ontsyfer nie.

### Databasis <!--quire:database-->

| Instelling | Betekenis |
| --- | --- |
| `POSTGRES_PASSWORD` | Die supergebruiker, gebruik deur houer en rugsteun |
| `QUIRE_DB_APP_PASSWORD`, `QUIRE_DB_MIGRATOR_PASSWORD`, `QUIRE_DB_REPORT_PASSWORD`, `QUIRE_DB_AUDIT_PASSWORD` | Rolwagwoorde, ingestel by eerste aanvang |
| `DATABASE_URL` | Die toepassingrol. Ryvlak-sekuriteit geld vir elke navraag wat dit maak |
| `DATABASE_MIGRATOR_URL`, `QUIRE_MIGRATION_URL` | Migreerderrol vir `migrate` en `init` |
| `QUIRE_SUPERUSER_URL` | Slegs deur eerste aanvang gebruik |
| `QUIRE_REPORT_DATABASE_URL` | Leesalleen-verslagrol vir verslae en verslagbouer |
| `QUIRE_AUDIT_DATABASE_URL` | Ouditrol vir ouditkonsole en SIEM-uitvoer |
| `QUIRE_DATABASE_ID` | Enige UUID, vas vir die leeftyd van installasie |

Rolwagwoorde word net toegepas wanneer die databasisvolume die eerste keer geskep word. Om een later te verander, gebruik `ALTER ROLE` en werk dan die ooreenstemmende URL by.

`QUIRE_REPORT_DATABASE_URL` word gebruik vir die fisiese databasis wat deur `DATABASE_URL` gekonfigureer word. Vir enige ander geregistreerde fisiese databasis, stel sy eie `quire_report`-verbinding-URL in die web- en werkeromgewings en plaas dan die veranderlikenaam in daardie databasis se veld **Verslagdoeningsomgewingsveranderlike** as `env:NAME`. Die verwysing moet na dieselfde databasis as sy toepassingverbinding wys, verkieslik die leesreplika. Elke verslagoppervlak volg die tenant na sy eie databasis se verslagverbinding: verslagbouer en gestoorde verslae, geskeduleerde aflewerings, verslaguitvoere, analise, ouditlog, REST-ouditbronne en assistent se ouditsoektog. Geen van hulle leen ooit ’n ander databasis se verslag-URL nie. Wanneer ’n databasis geen verslagverbinding het nie, loop gewone verslae op daardie databasis se eie toepassingverbinding; analise en elke ouditlesing weier en verduidelik waarom, want die toepassingrol kan nie die ouditspoor lees nie.

### Aandrywers <!--quire:drivers-->

| Instelling | Hierdie vrystelling | Aantekeninge |
| --- | --- | --- |
| `QUIRE_STORAGE_DRIVER` | `local` (verstek), `s3` of `azure` | `local` hou lêers in `files`-volume. `s3` dek AWS S3, R2, GCS-interoperabiliteit en ander S3-versoenbare winkels, met hervatbare meervoudige-deel-oplaaie |
| `QUIRE_REALTIME_DRIVER` | `inprocess` (verstek), `sse`, `centrifugo` of `durable_objects` | `inprocess` pas by een webhouer; gebruik `centrifugo` of `sse` wanneer daar verskeie is |
| `QUIRE_CACHE_DRIVER` | `memory` (verstek), `postgres` of `valkey` | `memory` is per proses; gebruik `valkey` of `postgres` sodat tempolimiete oor houers geld |
| `QUIRE_VIDEO_DRIVER` | `ffmpeg` (verstek) of `progressive_mp4` | Of ’n gehuisveste verskaffer: Cloudflare Stream, Mux of Bunny met hul sleutels |
| `QUIRE_IMAGE_DRIVER` | `noop` (verstek), `imgproxy` of `cloudflare` | `noop` bedien elke prent op oorspronklike grootte. `imgproxy` benodig `images`-profiel en instellings hieronder; `cloudflare` gebruik Cloudflare Images |
| `QUIRE_MEETING_PROVIDER` | `bbb`, `zoom`, `teams`, `meet`, `jitsi` of `in_process` | Die platform se verstek vir regstreekse sessies. As ongestel, sê regstreekse sessies dat hulle nie gekonfigureer is nie totdat ’n organisasie sy eie rekening onder Integrasies, Regstreekse sessieverskaffer koppel. ’n Organisasie se eie rekening wen altyd bo hierdie waarde. Elke verskaffer se instellings (`BBB_URL` en `BBB_SECRET`, die `ZOOM_*`, `TEAMS_*`, `GOOGLE_MEET_*` en `JITSI_*`-veranderlikes) word slegs gelees vir die verskaffer wat hier benoem is |
| `QUIRE_MEETING_REGIONS` | ’n Kommalys van `eu`, `uk`, `us` | Waar die platform se verstekverskaffer vergaderings verwerk. As ongestel, word dit soos voorheen nie nagegaan teen ’n organisasie wat aan ’n streek gepen is nie. ’n Organisasie se eie rekening verklaar sy streke op sy bladsy |

’n Aandrywerwaarde wat hierdie vrystelling nie insluit nie, word geweier wanneer die webvlak begin, met die instelling benoem, eerder as om stilweg deur die verstek vervang te word.

### Beelde <!--quire:images-->

Bladsye vra beelde in vier vaste groottes deur `/api/files/{id}/image/{size}`, wat dieselfde toegang as die lêer kontroleer en dan na die beeldediens herlei. Elke organisasie kan `QUIRE_IMAGE_SPECS_PER_HOUR` (verstek 2000) nuwe beeld-en-grootte-pare per uur versoek; groottes wat reeds daardie uur vervaardig is, tel nie. Gebruik `valkey` of `postgres` vir `QUIRE_CACHE_DRIVER` met meer as een webhouer sodat die limiet oor hulle geld.

| Instelling | Aandrywer | Aantekeninge |
| --- | --- | --- |
| `IMGPROXY_URL` | `imgproxy` | Adres waar blaaiers imgproxy bereik, byvoorbeeld `https://images.example.org`. `images`-profiel publiseer dit op `QUIRE_IMAGES_PORT` (8082) |
| `IMGPROXY_KEY`, `IMGPROXY_SALT` | `imgproxy` | Heksadesimale stringe, dieselfde waardes waarmee imgproxy begin. Genereer elk met `openssl rand -hex 32`. Quire onderteken elke beeldadres daarmee, dus lewer imgproxy niks wat Quire nie versoek het nie |
| `QUIRE_IMAGE_SOURCE_ORIGIN` | `imgproxy` met plaaslike berging | Waar imgproxy oorspronklikes ophaal. Compose stel `http://web:3000`. Met `s3`- of `azure`-berging haal imgproxy uit die emmer en dit word nie gebruik nie |
| `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_IMAGES_TOKEN`, `CLOUDFLARE_IMAGES_ACCOUNT_HASH` | `cloudflare` | API-teken met Images-wysigtoestemming en rekeninghash vanaf Images, Developer resources. Skakel buigsame variante vir die rekening aan |
| `CLOUDFLARE_IMAGES_SIGNING_KEY` | `cloudflare` | Opsioneel. Wanneer gestel, is beelde privaat en elke adres word onderteken en verval. Daarsonder is beelde publiek by adresse afgelei van `QUIRE_SECRET_KEY` wat niemand kan raai nie |

Cloudflare Images hou sy eie kopie van elke oorspronklike wat dit bedien. Wanneer ’n lêer geskrap word, skrap die werker daardie kopie voor die oorspronklike.

### Tou <!--quire:queue-->

Agtergrondtake gebruik pg-boss in dieselfde Postgres-databasis, dus is daar geen toudiens om te loop of op te stel nie. Take word in dieselfde transaksie geplaas as die verandering wat hulle veroorsaak het, dus kan ’n ineenstorting nie een verloor of dubbel stuur nie. `QUIRE_QUEUE_DRIVER` is hier `pgboss`, sy verstek; `vercel` en `cloudflare` skuif net ligte kennisgewings- en webhook-aflewerings na platform se eie tou, soos in die Vercel- en Cloudflare-gidse beskryf word, insluitend hoe hul webvlakke hulle in die tou plaas.

### E-pos <!--quire:email-->

Stel een van die volgende:

- `QUIRE_EMAIL_PROVIDER_CONFIG`: ’n JSON-objek wat ’n HTTP-verskaffer en aanmeldbewyse benoem, soos `{"provider":"postmark","token":"..."}`. Postmark, Amazon SES, Mailgun, SendGrid en Resend word ondersteun.
- `QUIRE_SMTP_URL`: `smtp://user:password@host:587`. Net hierdie teiken; bedienerlose teikens blokkeer SMTP.

`QUIRE_MAIL_FROM` is die sender. Om Quire te probeer, begin die `devmail`-profiel, stel `QUIRE_SMTP_URL=smtp://mailpit:1025` en lees e-pos by `http://localhost:8025`.

### Opsionele dienste <!--quire:optional-services-->

| Instelling | Met profiel |
| --- | --- |
| `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` of `QUIRE_MEILISEARCH_URL` | Eksterne soektog; anders volle teks in Postgres |
| `QUIRE_BREACH_CHECK_PROVIDER=off`, `QUIRE_BREACH_CHECK_URL` | Wagwoordlek-kontrole. By verstek aan teen `api.pwnedpasswords.com` (net ’n vyfkarakter-hashvoorvoegsel word gestuur); `off` skakel dit af, die URL wys na ’n reeks-API wat jy huisves |

### Waarneembaarheid <!--quire:observability-->

`OTEL_EXPORTER_OTLP_ENDPOINT` benoem die versamelaar waarheen elke proses nasporingsdata en maatstawwe stuur; met `observability`-profiel is dit `http://otelcol:4318`, en `docker/otel-collector.yaml` is waar jy uitvoerder vir jou agterkant byvoeg. Webvlak-, werker-, skeduleerder-, inhoud- en collab-prosesse voer afdelings oor OTLP/HTTP uit (webversoeke, tenant-databasistransaksies, werktake en uitgaande oproepe) wanneer dit gestel is, en maatstawwe elke minuut na dieselfde eindpunt (`OTEL_METRICS_EXPORTER=none` skakel hulle af). `OTEL_TRACES_SAMPLER_ARG` stel die deel van nasporings wat behou word. Logboeke gaan na standaardafvoer by `LOG_LEVEL`, en Compose roteer hulle. Nasporings bevat nooit persoonlike data nie.

### Streeksuitgaande verkeer (EU-dataverblyf) <!--quire:regional-egress-eu-data-residency-->

`QUIRE_REGION=eu` sê die stapel bedien Europese Unie-organisasies. Die werker beperk dan elke uitgaande versoek namens ’n organisasie wat aan die EU gepen is tot ’n toelaatlys (21-compliance.md afdeling 8.1). Die toelaatlys bestaan uit gashere wat gekonfigureerde dienste vir die streek verklaar (bergingseindpunt, e-posverskaffer, gehuisveste videoverskaffer, organisasie se eie bergingsteikens, KI-verskaffers en e-posrekening), gashere van enige diens onder ’n geldige afwyking en gashere wat jy in `QUIRE_EGRESS_ALLOW_HOSTS` lys. ’n Versoek aan enige ander openbare gasheer word geweier voordat dit gestuur word; die weiering word in die organisasie se ouditspoor aangeteken as `privacy/egress_refused` en onder Nakoming, Dataverblyf gelys.

| Instelling | Waardes | Gevolg |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | Kommalys gasheername of `*.example.org` vir elke subdomein | Ekstra gashere wat ’n EU-organisasie mag bereik. Webhook-, xAPI- en SIEM-eindpunte, blogvoere en Amazon SES-gashere hoort hier omdat dit organisasies se eie keuses is en geen diens hulle verklaar nie. Teruglus-, private adresse en enkelvlakname soos `web` of `clamav` is jou eie netwerk en word nooit nagegaan nie |

VK- en VSA-organisasies word nie tot ’n gasheerlys beperk nie; hulle behou diensstreekkontroles. Stel die lys op die werker; die administrasiebladsy lees dit op webvlak om die toelaatlys te wys, dus plaas dit in `docker/.env`, wat elke diens lees.

Toepassingkontrole gee ’n duidelike fout en ouditinskrywing, maar dit is nie die waarborg nie: kode kan verkeerd wees. Die waarborg is die netwerk. Compose dwing dit nie vir jou af nie. Plaas die `worker`- en `web`-dienste vir ’n streekstapel op ’n `internal: true`-netwerk waarvan die enigste uitgaande roete ’n egress-instaanbediener is (soos Squid of ’n klein tinyproxy-houer) wat dieselfde gashere as `QUIRE_EGRESS_ALLOW_HOSTS` plus jou gekonfigureerde diensgashere toelaat, en stel `HTTPS_PROXY` vir daardie dienste. Die verblyfbladsy lys presies die gashere wat die toepassing toelaat, sodat die twee lyste vergelyk kan word.

## Gesondheid <!--quire:health-->

| Eindpunt | Betekenis |
| --- | --- |
| `/healthz` | Lewendigheid: proses antwoord. Compose-gesondheidsondersoeke gebruik dit |
| `/readyz` | Gereedheid: afhanklikhede bereikbaar, en elke opsionele diens aangemeld as gekonfigureer of nie. Wys jou lasbalanseerder hierheen |

`docker compose -f docker/compose.yaml ps` wys die gesondheid van elke diens.

## TLS <!--quire:tls-->

Die `proxy`-diens (Caddy, Apache-2.0, `docker/caddy/Caddyfile`) is deel van die verstekstapel. Dit antwoord op poorte 80 en 443 en roeteer:

| Gasheer of pad | Gaan na |
| --- | --- |
| `QUIRE_PROXY_CONTENT_HOST` | `content` |
| `QUIRE_PROXY_APP_HOST`, elke tenant-subdomein en pasgemaakte domein | `web` |
| `/_collab/` op daardie gashere | `collab` (websocket, `QUIRE_COLLAB_URL`) |
| `/_realtime/connection/` op daardie gashere | `centrifugo`-kliëntwebsocket; sy bediener-API word nooit blootgestel nie |
| `/_images/` op daardie gashere | `imgproxy`, met `images`-profiel (`IMGPROXY_URL`) |

`init-env.sh` lei `QUIRE_PROXY_APP_HOST`, `QUIRE_PROXY_CONTENT_HOST`, `QUIRE_PROXY_HTTPS_PORT`, `QUIRE_COLLAB_URL` en `IMGPROXY_URL` uit die twee oorspronge af, dus kan hulle nie uit pas raak nie. Wysig hulle saam as jy ’n oorsprong met die hand verander.

Sertifikate volg `QUIRE_PROXY_TLS`:

- `internal` (verstek): Caddy se eie sertifikaatowerheid vir `localhost`, `*.localhost` en `lvh.me`. Vertrou sy wortel een keer en blaai dan:

  ```sh
  docker compose -f docker/compose.yaml cp \
    proxy:/data/caddy/pki/authorities/local/root.crt ./quire-local-ca.crt
  ```

  Voeg `quire-local-ca.crt` by die stelsel- of blaaiervertrouewinkel. `curl` gebruik dit met `--cacert`.
- ’n E-posadres: outomatiese ACME-sertifikate (Let's Encrypt, dan ZeroSSL) vir regte gasheername. DNS vir albei oorspronge en elke tenant-gasheer moet hierheen wys; poorte 80 en 443 moet vanaf die internet bereikbaar wees.

Tenant-gashere kry sertifikate op aanvraag by eerste besoek, en net wanneer web bevestig dat die naam aan hierdie installasie behoort (`/tls-allowed`, aangevra oor die Compose-netwerk). Geen jokertekensertifikaat of DNS-verskafferinprop is nodig nie, en ’n vreemdeling wat ’n naam na die gasheer laat wys, kan nie sertifikate daarvoor laat aanvra nie. Sertifikate en plaaslike owerheid woon in `caddy-data`-volume; rugsteun dit saam met die res as jy `internal` gebruik.

Web vertrou `X-Forwarded-For` net vanaf die instaanbediener: die instaanbediener het ’n vaste adres (`QUIRE_PROXY_ADDRESS`, verstek `172.29.64.10`) op ’n vaste subnet (`QUIRE_COMPOSE_SUBNET`), en `QUIRE_TRUSTED_PROXY_CIDRS` benoem daardie adres. As die subnet met ’n netwerk op die gasheer bots, verander albei en voer `docker compose down` uit voordat jy `up` uitvoer.

## Agter jou eie omgekeerde instaanbediener <!--quire:behind-your-own-reverse-proxy-->

Om eerder ’n bestaande lasbalanseerder of instaanbediener te gebruik, laat `proxy` weg (`docker compose up -d --scale proxy=0`) en beëindig TLS voor `web` (8080), `content` (8081), `collab` (1234, websocket) en `centrifugo` (8000, websocket). Stel openbare adresse in `QUIRE_APP_ORIGIN`, `QUIRE_CONTENT_ORIGIN` en `QUIRE_COLLAB_URL` (`wss://`), en jou instaanbediener se adresreeks in `QUIRE_TRUSTED_PROXY_CIDRS`.

## Probleemoplossing <!--quire:troubleshooting-->

- `init` sluit af met “QUIRE_DATABASE_ID is not a UUID”: stel dit met `uuidgen`.
- `web` herbegin met “did not start on compose”: die log lys elke instelling wat dit nie kan eerbiedig nie en wat eerder gebruik moet word.
- Om ’n rolwagwoord in `.env` ná eerste aanvang te verander, doen niks: die inisialisasieskrip loop net een keer. Gebruik `ALTER ROLE`.
- Oplaaie misluk met ’n skandeerfout terwyl `CLAMAV_URL` gestel is: ClamAV laai sy handtekeninge by eerste aanvang af, wat ’n paar minute duur.

Source: https://docs.quirelms.com/af/ops/install/index.mdx
