---
title: "Instaliranje Quirea pomoću Docker Composea"
description: "Instalirajte Quire na vlastitoj infrastrukturi pomoću Docker Composea."
image: "https://docs.quirelms.com/og.png"
---

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

# Instaliranje Quirea pomoću Docker Composea

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

Ovo je potpuni proizvod na jednom hostu: LMS, njegovi pozadinski zadaci, usluge za realtime i zajedničko uređivanje te sve opcionalne usluge dostupne kroz profile. Dizajn je opisan u odjeljku 2 dokumenta `docs/architecture/23-ops.md`.

Ostale platforme: [Vercel](/bs/ops/vercel/) i [Cloudflare Workers](/bs/ops/cloudflare/) pokreću samo web sloj. Nadogradnje su opisane u [upgrade.md](/bs/ops/upgrade/), a sigurnosne kopije i proba oporavka u [backup-restore.md](/bs/ops/backup-restore/).

## Šta vam je potrebno <!--quire:what-you-need-->

- Docker Engine 27 ili noviji uz Compose dodatak verzije 2.30 ili noviji.
- 4 CPU jezgre i 8 GB memorije za podrazumijevani stack; 8 jezgri i 16 GB uz `--profile full` (sam ClamAV zauzima oko 1,5 GB za potpise).
- DNS naziv za web sloj i drugi za nepouzdani sadržaj. Moraju biti različiti hostovi: SCORM paketi i otpremljeni HTML izvršavaju se na izvoru sadržaja da nikada ne bi mogli čitati LMS kolačiće.
- Za lokalno testiranje `lvh.me` i `*.localhost` vode na 127.0.0.1, što koristi `docker/.env.example`. Vlastita usluga `proxy` u stacku poslužuje oba putem https-a s lokalnim certifikacijskim tijelom, pa se ništa drugo ne instalira (pogledajte „TLS“).
- Portovi 80 i 443 moraju biti slobodni na hostu (`QUIRE_PROXY_HTTP_PORT` i `QUIRE_PROXY_HTTPS_PORT` mijenjaju ih).

## Prvo pokretanje <!--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` pravi `docker/.env` iz `docker/.env.example` i generiše sve tajne (lozinke baze, ključeve za potpisivanje i glavni ključ, par ključeva za pokretanje sadržaja), kao i ključ za potpis kontrolne tačke revizije u `docker/secrets/audit-signing-key.pem`, koji Compose montira u workere kao tajnu. Potrebni su samo `sh`, `awk` i `openssl`; skripta odbija prepisati postojeći `docker/.env`. Kopirajte obje datoteke izvan hosta: bez `QUIRE_MASTER_KEY` vraćena baza ne može dešifrovati sačuvane pristupne podatke. Ako datoteku želite popuniti ručno, pokrenite `cp docker/.env.example docker/.env`; datoteka objašnjava kako generisati svaku tajnu.

Oba izvora moraju koristiti `https`: usluga content odbija obični http u produkciji, a ne smiju dijeliti registrovanu domenu. Usluga `proxy` završava TLS za oba izvora (pogledajte „TLS“); `init-env.sh` odbija izvor `http://`.

Stack se pokreće zadanim redoslijedom, pri čemu svaki korak čeka prethodni:

1. `postgres` postaje zdrav. Pri prvom pokretanju njegova inicijalizacijska skripta (`docker/postgres/init/90-passwords.sh`) postavlja četiri lozinke uloga.
2. `migrate` primjenjuje sve migracije i priprema red zadataka u kontrolnoj bazi i svakoj namjenskoj bazi klijenta, provjerava njihovu usklađenost i zatim završava (docs/ops/upgrade.md). Migracije se pokreću pri svakom pokretanju i idempotentne su, pa nadogradnja znači novi image i ponovno pokretanje.
3. `init` (`apps/web/src/first-run.ts`) bilježi bazu aplikacije pod `QUIRE_DATABASE_ID` i, ako je postavljeno `QUIRE_SETUP_ADMIN_EMAIL`, kreira prvu organizaciju i njenog administratora. Adresa za prijavu i generisana lozinka ispisuju se samo jednom u `docker compose logs init`.
4. Pokreću se `web`, `content`, `worker`, `scheduler`, `collab` i `centrifugo`.
5. `proxy` se pokreće kada `web` i `content` postanu zdravi.

Otvorite `https://demo.` iza kojeg slijedi domena aplikacije (dnevnik `init` prikazuje tačnu adresu za prijavu) i prijavite se. Na lokalnoj instalaciji prvo vjerujte certifikacijskom tijelu proxyja (pogledajte „TLS“). Promijenite generisanu lozinku na `/account/security`.

Proces pokrenut bez obavezne tajne odbija pokretanje i navodi nedostajuću postavku u dnevniku. Ništa se ne pokreće s nepotpunom konfiguracijom.

## Usluge i profili <!--quire:services-and-profiles-->

| Usluga | Profil | Namjena |
| --- | --- | --- |
| postgres | uvijek | Baza podataka (PostgreSQL 18 s pgvectorom, izgrađen iz `docker/postgres.Dockerfile`), uz arhiviranje WAL-a od prvog pokretanja |
| migrate, init | uvijek | Jednokratne radnje: migracije, pa prvo pokretanje |
| web | uvijek | LMS na `QUIRE_HTTP_PORT` (8080) |
| content | uvijek | Izvor nepouzdanog sadržaja na `QUIRE_CONTENT_PORT` (8081) |
| worker | uvijek | Pozadinski zadaci: e-pošta, izvještaji, obrada datoteka i webhookovi |
| scheduler | uvijek | Ponavljajući zadaci: registruje 64 rasporeda tokom rada i predaje ih workeru; istovremeno je aktivan jedan vođa |
| collab | uvijek | WebSocket za zajedničko uređivanje na `QUIRE_COLLAB_HTTP_PORT` (1234) |
| centrifugo | uvijek | Širenje realtime događaja na `QUIRE_REALTIME_PORT` (8000) |
| proxy | uvijek | Caddy, TLS ulaz na portovima 80 i 443 (pogledajte „TLS“) |
| valkey | `cache` | Keš i ograničenja učestalosti |
| clamav | `scan` | Skeniranje otpremanja u potrazi za zlonamjernim softverom |
| gotenberg | `preview` | Pregledi Office dokumenata u PDF-u i izrada certifikata |
| imgproxy | `images` | Promjena veličine i konverzija slika |
| transcoder | `video` | Worker image s ffmpegom samo pod LGPL licencom za video varijante |
| seaweedfs | `storage` | S3-kompatibilno spremište objekata na ovom hostu |
| otelcol | `observability` | OpenTelemetry kolektor |
| mailpit | `devmail` | Hvata svu odlaznu poštu radi isprobavanja Quirea |
| backup | `backup` | Jednokratna osnovna kopija; pogledajte backup-restore.md |
| backup-scheduler, backup-offsite | `backup` | Osnovna kopija svakih `QUIRE_BACKUP_INTERVAL_HOURS` i šifrovane kopije izvan hosta sa sedmičnom provjerom |
| h5p | `h5p` | Slika H5P LTI 1.3 alata koju obezbjeđujete preko `QUIRE_H5P_IMAGE`, na `QUIRE_H5P_PORT` (8090); pogledajte „Povezivanje H5P pružatelja“ |

`--profile full` pokreće sve opcionalne usluge osim `backup` i `h5p`. Pokrenite uslugu ovako: `docker compose -f docker/compose.yaml --profile scan up -d`. Quire radi i bez opcionalne usluge te navodi šta nedostaje: bez skenera otpremanja se čuvaju neskenirana i administrator dobija obavještenje; bez Gotenberga datoteke se nude za preuzimanje umjesto pregleda; bez transcoder-a video se reproducira kao izvorna datoteka.

Sve slike trećih strana i njihove licencne obaveze navedene su u `docker/third-party-containers.yaml`.

### Povezivanje H5P pružatelja <!--quire:connecting-an-h5p-provider-->

Quire ne ugrađuje niti isporučuje H5P runtime ili prateći servis (ADR 0019). Ako koristite H5P, obezbijedite vlastitu hostovanu pretplatu ili zasebno upravljajte vlastitom H5P instalacijom. Registrujte pružatelja kao vanjski LTI 1.3 alat i dodajte njegov sadržaj u kurseve kao aktivnosti-alate. Quire razmjenjuje ocjene i napredak aktivnosti/ocjenjivanja preko LTI Assignment and Grade Services (AGS). Ako pružatelj šalje i xAPI izjave, zasebno ga podesite za Quireovo spremište xAPI izjava; AGS razmjena ocjena i napretka ne šalje xAPI izjave. Moodle uvozi prijavljuju H5P aktivnosti kao one kojima je potrebna veza s LTI alatom. Pružatelj ostaje odgovoran za H5P runtime, izradu sadržaja, banku sadržaja i historiju pokušaja.

Da biste na ovom hostu pokrenuli vlastitu instalaciju, postavite `QUIRE_H5P_IMAGE` na njenu sliku i pokrenite profil `h5p`. Compose je objavljuje na `QUIRE_H5P_PORT` (8090), a podatke čuva u volumenu `h5p-data`; slika i pripadajuće obaveze ostaju vaša odgovornost.

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

Svaki proces čita `docker/.env`. Predložak `docker/.env.example` navodi svaku postavku i njenu podrazumijevanu vrijednost. Grupe su:

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

| Postavka | Značenje |
| --- | --- |
| `QUIRE_APP_ORIGIN` | Javna adresa LMS-a, npr. `https://learn.example.com` |
| `QUIRE_CONTENT_ORIGIN` | Izvor sadržaja na drugom hostu |
| `QUIRE_PLATFORM_DOMAINS` | Domene organizacija, razdvojene zarezima |
| `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` | Ovdje `compose`. Za `vercel` i `cloudflare` pogledajte druge vodiče |
| `QUIRE_TRUSTED_PROXY_CIDRS` | Proxyji čijem `X-Forwarded-For` zaglavlju se vjeruje |

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

| Postavka | Značenje |
| --- | --- |
| `QUIRE_SECRET_KEY` | Potpisuje sesije i tokene. 64 heksadecimalna znaka |
| `QUIRE_MASTER_KEY` | Omotava sačuvane pristupne podatke poput SSO i webhook tajni. 32 bajta, base64. Web sloj i worker moraju imati istu vrijednost. Rotacija: [key-rotation.md](/bs/ops/key-rotation/) |
| `QUIRE_MASTER_KEY_VERSION` | Oznaka verzije glavnog ključa, podrazumijevano `v1`. Povećajte je pri rotaciji |
| `QUIRE_MASTER_KEY_RETIRED` | Raniji ključevi potrebni za čitanje onoga što su zapečatili, u obliku `v1=<base64>`. Uklonite ih nakon završetka rotacije bez neriješenih vrijednosti |
| `QUIRE_COLLAB_SIGNING_KEY` | Dijele ga web i collab radi potpisivanja tokena za uređivanje |
| `QUIRE_BACKUP_SIGNING_KEY` | Potpisuje rezervne kopije kurseva (opcionalno) |

Sačuvajte kopiju `QUIRE_MASTER_KEY` izvan ovog hosta. Vraćena baza bez njega ne može dešifrovati pristupne podatke.

### Baza podataka <!--quire:database-->

| Postavka | Značenje |
| --- | --- |
| `POSTGRES_PASSWORD` | Superuser koji koriste kontejner i sigurnosne kopije |
| `QUIRE_DB_APP_PASSWORD`, `QUIRE_DB_MIGRATOR_PASSWORD`, `QUIRE_DB_REPORT_PASSWORD`, `QUIRE_DB_AUDIT_PASSWORD` | Lozinke uloga, postavljaju se pri prvom pokretanju |
| `DATABASE_URL` | Uloga aplikacije. Svaki njen upit podliježe row-level securityju |
| `DATABASE_MIGRATOR_URL`, `QUIRE_MIGRATION_URL` | Uloga migratora za `migrate` i `init` |
| `QUIRE_SUPERUSER_URL` | Koristi se samo pri prvom pokretanju |
| `QUIRE_REPORT_DATABASE_URL` | Uloga izvještavanja samo za čitanje, za izvještaje i alat za izradu izvještaja |
| `QUIRE_AUDIT_DATABASE_URL` | Uloga revizije za konzolu i SIEM izvoz |
| `QUIRE_DATABASE_ID` | Bilo koji UUID, nepromjenjiv tokom životnog vijeka instalacije |

Lozinke uloga primjenjuju se samo kada se volumen baze prvi put kreira. Kasniju promjenu izvršite naredbom `ALTER ROLE`, pa ažurirajte odgovarajući URL.

`QUIRE_REPORT_DATABASE_URL` koristi se za fizičku bazu podešenu putem `DATABASE_URL`. Za svaku drugu registrovanu fizičku bazu u okruženje weba i workera postavite vlastiti `quire_report` URL, a naziv varijable unesite u polje **Reporting environment variable** te baze kao `env:NAME`. Referenca mora voditi do iste baze kao veza aplikacije, idealno do njene replike za čitanje. Svaka funkcija izvještavanja prati klijenta do vlastite veze njegove baze: alat za izradu i sačuvani izvještaji, zakazane isporuke, izvoz izvještaja, analitika, revizorski dnevnik, REST resursi revizije i pretraga revizije asistenta. Nijedna ne koristi URL izvještavanja druge baze. Kada baza nema vezu izvještavanja, obični izvještaji se izvršavaju preko vlastite veze aplikacije, a analitika i svako čitanje revizije se odbijaju uz objašnjenje jer uloga aplikacije ne može čitati revizorski trag.

### Upravljački programi <!--quire:drivers-->

| Postavka | U ovoj verziji | Napomene |
| --- | --- | --- |
| `QUIRE_STORAGE_DRIVER` | `local` (podrazumijevano), `s3` ili `azure` | `local` čuva datoteke u volumenu `files`. `s3` obuhvata AWS S3, interoperabilnost s R2 i GCS-om te druga S3-kompatibilna spremišta uz nastavljivo višedijelno otpremanje |
| `QUIRE_REALTIME_DRIVER` | `inprocess` (podrazumijevano), `sse`, `centrifugo` ili `durable_objects` | `inprocess` odgovara jednom web kontejneru; za više njih koristite `centrifugo` ili `sse` |
| `QUIRE_CACHE_DRIVER` | `memory` (podrazumijevano), `postgres` ili `valkey` | `memory` važi za pojedinačni proces; koristite `valkey` ili `postgres` kako bi ograničenja učestalosti važila među kontejnerima |
| `QUIRE_VIDEO_DRIVER` | `ffmpeg` (podrazumijevano) ili `progressive_mp4` | Ili hostovani pružatelj: Cloudflare Stream, Mux ili Bunny, uz njihove ključeve |
| `QUIRE_IMAGE_DRIVER` | `noop` (podrazumijevano), `imgproxy` ili `cloudflare` | `noop` poslužuje sve slike u izvornoj veličini. `imgproxy` zahtijeva profil `images` i postavke u nastavku; `cloudflare` koristi Cloudflare Images |
| `QUIRE_MEETING_PROVIDER` | `bbb`, `zoom`, `teams`, `meet`, `jitsi` ili `in_process` | Podrazumijevani pružatelj platforme za sesije uživo. Ako nije postavljen, sesije uživo prijavljuju da nisu konfigurisane dok organizacija ne poveže vlastiti račun u Integrations, Live session provider. Vlastiti račun organizacije uvijek ima prednost nad ovom vrijednošću. Postavke pojedinačnog pružatelja (`BBB_URL` i `BBB_SECRET`, varijable `ZOOM_*`, `TEAMS_*`, `GOOGLE_MEET_*` i `JITSI_*`) čitaju se samo za ovdje navedenog pružatelja |
| `QUIRE_MEETING_REGIONS` | Lista `eu`, `uk`, `us` razdvojena zarezima | Regije u kojima podrazumijevani pružatelj platforme obrađuje sastanke. Ako nije postavljeno, ne provjerava se prema organizaciji vezanoj za određenu regiju, kao ni ranije. Vlastiti račun organizacije navodi svoje regije na vlastitoj stranici |

Vrijednost upravljačkog programa koji nije uključen u ovu verziju web sloj odbija pri pokretanju, uz navođenje postavke, umjesto da je tiho zamijeni podrazumijevanom vrijednošću.

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

Stranice traže slike u četiri fiksne veličine putem `/api/files/{id}/image/{size}`; ta putanja provjerava isti pristup kao i samoj datoteci, a zatim preusmjerava na uslugu za slike. Svaka organizacija može u jednom satu zatražiti do `QUIRE_IMAGE_SPECS_PER_HOUR` (podrazumijevano 2000) novih kombinacija slike i veličine; veličine već generisane tog sata ne broje se ponovo. Uz više web kontejnera postavite `valkey` ili `postgres` za `QUIRE_CACHE_DRIVER` da bi ograničenje važilo u svima.

| Postavka | Upravljački program | Napomene |
| --- | --- | --- |
| `IMGPROXY_URL` | `imgproxy` | Adresa imgproxyja dostupna preglednicima, npr. `https://images.example.org`. Profil `images` objavljuje ga na `QUIRE_IMAGES_PORT` (8082) |
| `IMGPROXY_KEY`, `IMGPROXY_SALT` | `imgproxy` | Heksadecimalni nizovi, iste vrijednosti s kojima se imgproxy pokreće. Generišite svaki pomoću `openssl rand -hex 32`. Quire njima potpisuje svaku adresu slike, pa imgproxy obrađuje samo slike koje je Quire zatražio |
| `QUIRE_IMAGE_SOURCE_ORIGIN` | `imgproxy` uz lokalno spremište | Odredište s kojeg imgproxy preuzima izvornike. Compose postavlja `http://web:3000`. Uz `s3` ili `azure` spremište imgproxy ih preuzima iz kante, pa se ova postavka ne koristi |
| `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_IMAGES_TOKEN`, `CLOUDFLARE_IMAGES_ACCOUNT_HASH` | `cloudflare` | API token s dozvolom za uređivanje Imagesa i hash računa iz Images, Developer resources. Uključite fleksibilne varijante računa |
| `CLOUDFLARE_IMAGES_SIGNING_KEY` | `cloudflare` | Opcionalno. Kada je postavljen, slike su privatne, a svaka adresa je potpisana i ističe. Bez njega slike su javne na adresama izvedenim iz `QUIRE_SECRET_KEY` koje niko ne može pogoditi |

Cloudflare Images čuva vlastitu kopiju svakog izvornika koji poslužuje. Kada se datoteka izbriše, worker prvo briše tu kopiju.

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

Pozadinski zadaci koriste pg-boss u istoj Postgres bazi, pa nema zasebne usluge reda za pokretanje ni podešavanje. Zadaci se stavljaju u red u istoj transakciji kao promjena koja ih je izazvala, tako da ih pad sistema ne može izgubiti ili poslati dvaput. Ovdje je `QUIRE_QUEUE_DRIVER` podrazumijevani `pgboss`; `vercel` i `cloudflare` prebacuju samo lake isporuke obavještenja i webhookova u redove same platforme. Vodiči za Vercel i Cloudflare opisuju te redove i način na koji ih njihovi web slojevi pune.

### E-pošta <!--quire:email-->

Postavite jednu od sljedećih vrijednosti:

- `QUIRE_EMAIL_PROVIDER_CONFIG`: JSON objekt s nazivom HTTP pružatelja i njegovim pristupnim podacima, npr. `{"provider":"postmark","token":"..."}`. Podržani su Postmark, Amazon SES, Mailgun, SendGrid i Resend.
- `QUIRE_SMTP_URL`: `smtp://user:password@host:587`. Samo ova platforma podržava SMTP; bezserverske platforme ga blokiraju.

`QUIRE_MAIL_FROM` je pošiljalac. Za isprobavanje Quirea pokrenite profil `devmail`, postavite `QUIRE_SMTP_URL=smtp://mailpit:1025` i čitajte poštu na `http://localhost:8025`.

### Opcionalne usluge <!--quire:optional-services-->

| Postavka | 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` ili `QUIRE_MEILISEARCH_URL` | Vanjska pretraga; inače se koristi puni tekstualni indeks Postgresa |
| `QUIRE_BREACH_CHECK_PROVIDER=off`, `QUIRE_BREACH_CHECK_URL` | Provjera je li lozinka kompromitovana. Podrazumijevano uključena prema `api.pwnedpasswords.com` (šalje se samo prefiks od pet znakova hasha); `off` je isključuje, a URL pokazuje na API raspona koji sami hostujete |

### Praćenje <!--quire:observability-->

`OTEL_EXPORTER_OTLP_ENDPOINT` navodi kolektor kojem svi procesi šalju tragove i metrike; uz profil `observability` to je `http://otelcol:4318`, a u `docker/otel-collector.yaml` dodajete izvoz za svoju pozadinsku uslugu. Kada je postavljen, web sloj, worker, scheduler, content i collab izvoze raspona putem OTLP/HTTP-a (web zahtjevi, transakcije baze klijenta, poslovi workera i odlazni pozivi) te svake minute šalju metrike na istu krajnju tačku (`OTEL_METRICS_EXPORTER=none` ih isključuje). `OTEL_TRACES_SAMPLER_ARG` određuje udio tragova koji se čuvaju. Dnevnici se šalju na standardni izlaz na nivou `LOG_LEVEL`, a Compose ih rotira. Tragovi nikad ne sadrže lične podatke.

### Regionalni odlazni promet (rezidentnost podataka u EU) <!--quire:regional-egress-eu-data-residency-->

`QUIRE_REGION=eu` označava da stack poslužuje organizacije iz Evropske unije. Worker tada svaki odlazni zahtjev organizacije vezane za EU ograničava listom dozvoljenih hostova (odjeljak 8.1 dokumenta 21-compliance.md). Lista obuhvata hostove koje konfigurisane usluge prijavljuju za regiju (krajnja tačka spremišta, pružatelj e-pošte, hostovani pružatelj videa, ciljevi spremišta organizacije, AI pružatelji i račun e-pošte), hostove usluga pod aktivnim izuzećem i hostove navedene u `QUIRE_EGRESS_ALLOW_HOSTS`. Zahtjev drugom javnom hostu odbija se prije slanja, bilježi se u revizorskom tragu organizacije kao `privacy/egress_refused` i prikazuje u Compliance, Data residency.

| Postavka | Vrijednosti | Efekat |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | Lista naziva hostova razdvojenih zarezima ili `*.example.org` za sve poddomene | Dodatni hostovi koje organizacija iz EU smije doseći. Webhook, xAPI i SIEM krajnje tačke, RSS sadržaji blogova i Amazon SES hostovi pripadaju ovdje jer su izbor organizacije i nijedna ih usluga ne prijavljuje. Loopback, privatne adrese i jednorječna imena poput `web` ili `clamav` pripadaju vašoj mreži i nikada se ne provjeravaju |

Organizacije iz Ujedinjenog Kraljevstva i SAD-a ne ograničavaju se listom hostova; za njih i dalje vrijede regionalne provjere usluga. Postavite listu na workeru; administratorska stranica je čita na web sloju radi prikaza, pa je dodajte u `docker/.env` koji čitaju sve usluge.

Provjera aplikacije daje jasnu grešku i revizorski zapis, ali nije sigurnosno jamstvo: kod može biti pogrešan. Jamstvo je mreža, a Compose ga ne provodi umjesto vas. Za regionalni stack postavite usluge `worker` i `web` na mrežu `internal: true` kojoj je jedina vanjska ruta proxy za izlazni promet (npr. Squid ili tinyproxy kontejner). Dozvolite mu iste hostove kao u `QUIRE_EGRESS_ALLOW_HOSTS` i hostove konfigurisane usluge te postavite `HTTPS_PROXY` za te usluge. Stranica rezidentnosti navodi tačne hostove koje aplikacija dopušta, pa možete uporediti liste.

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

| Krajnja tačka | Značenje |
| --- | --- |
| `/healthz` | Aktivnost: proces odgovara. Compose provjere zdravlja koriste ovo |
| `/readyz` | Spremnost: zavisnosti su dostupne, a svaka opcionalna usluga prijavljena je kao konfigurisana ili ne. Ovdje usmjerite balansator opterećenja |

`docker compose -f docker/compose.yaml ps` prikazuje zdravlje svake usluge.

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

Usluga `proxy` (Caddy, Apache-2.0, `docker/caddy/Caddyfile`) dio je podrazumijevanog stacka. Odgovara na portovima 80 i 443 te usmjerava:

| Host ili putanja | Odredište |
| --- | --- |
| `QUIRE_PROXY_CONTENT_HOST` | `content` |
| `QUIRE_PROXY_APP_HOST`, svaka poddomena klijenta i prilagođena domena | `web` |
| `/_collab/` na tim hostovima | `collab` (websocket, `QUIRE_COLLAB_URL`) |
| `/_realtime/connection/` na tim hostovima | Klijentski websocket `centrifugo`; njegov serverski API nikada se ne izlaže |
| `/_images/` na tim hostovima | `imgproxy` uz profil `images` (`IMGPROXY_URL`) |

`init-env.sh` izvodi `QUIRE_PROXY_APP_HOST`, `QUIRE_PROXY_CONTENT_HOST`, `QUIRE_PROXY_HTTPS_PORT`, `QUIRE_COLLAB_URL` i `IMGPROXY_URL` iz dva izvora, pa se vrijednosti ne mogu razići. Ako ručno promijenite izvor, promijenite ih zajedno.

Certifikati zavise od `QUIRE_PROXY_TLS`:

- `internal` (podrazumijevano): vlastito Caddy certifikacijsko tijelo za `localhost`, `*.localhost` i `lvh.me`. Jednom vjerujte njegovom korijenu, pa ga preuzmite:

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

  Dodajte `quire-local-ca.crt` u sistemsko ili preglednikovo spremište povjerenja. `curl` ga koristi putem `--cacert`.
- E-adresa: automatski ACME certifikati (Let's Encrypt, zatim ZeroSSL) za stvarne nazive hostova. DNS oba izvora i svakog hosta klijenta mora pokazivati ovamo, a portovi 80 i 443 moraju biti dostupni s interneta.

Certifikati za hostove klijenata izdaju se po potrebi, pri prvoj posjeti, i samo kada web potvrdi da ime pripada ovoj instalaciji (`/tls-allowed`, preko Compose mreže). Wildcard certifikat ni dodatak za DNS pružatelja nisu potrebni, a nepoznata osoba koja usmjeri ime na host ne može izazvati zahtjev za certifikatom. Certifikati i lokalno tijelo nalaze se u volumenu `caddy-data`; uključite ga u sigurnosnu kopiju ako koristite `internal`.

Web vjeruje zaglavlju `X-Forwarded-For` samo od proxyja: proxy ima fiksnu adresu (`QUIRE_PROXY_ADDRESS`, podrazumijevano `172.29.64.10`) u fiksnoj podmreži (`QUIRE_COMPOSE_SUBNET`), a `QUIRE_TRUSTED_PROXY_CIDRS` navodi tu adresu. Ako je podmreža u sukobu s hostovom mrežom, promijenite oboje i pokrenite `docker compose down` prije komande `up`.

## Iza vlastitog obrnutog proxyja <!--quire:behind-your-own-reverse-proxy-->

Da biste umjesto toga koristili postojeći balansator ili proxy, izostavite `proxy` (`docker compose up -d --scale proxy=0`) i završite TLS ispred `web` (8080), `content` (8081), `collab` (1234, websocket) i `centrifugo` (8000, websocket). Postavite javne adrese u `QUIRE_APP_ORIGIN`, `QUIRE_CONTENT_ORIGIN` i `QUIRE_COLLAB_URL` (`wss://`), a raspon adresa proxyja u `QUIRE_TRUSTED_PROXY_CIDRS`.

## Rješavanje problema <!--quire:troubleshooting-->

- `init` završava porukom „QUIRE_DATABASE_ID is not a UUID“: postavite ga pomoću `uuidgen`.
- `web` se ponovo pokreće uz poruku „did not start on compose“: dnevnik navodi postavke koje ne može ispoštovati i čime ih zamijeniti.
- Promjena lozinke uloge u `.env` nakon prvog pokretanja nema efekta: skripta za inicijalizaciju izvršava se samo jednom. Koristite `ALTER ROLE`.
- Otpremanja ne prolaze skeniranje dok je postavljen `CLAMAV_URL`: ClamAV pri prvom pokretanju preuzima potpise, što traje nekoliko minuta.

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