---
title: "Docker Compose менен Quire'ди орнотуу"
description: "Quire'ди өз инфраструктураңызга Docker Compose менен орнотуңуз."
image: "https://docs.quirelms.com/og.png"
---

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

# Docker Compose менен Quire'ди орнотуу

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

Бул бир хосттоги толук продукт: LMS, анын фон жумуштары, реалдуу убакыт
жана кызматташып тексти өзгөртүү кызматтары, жана профильдин артындагы
ар коопсуз кызмат. Дизайн `docs/architecture/23-ops.md` 2-бөлүмүндө.

Башка максаттар: [Vercel](/ky/ops/vercel/) жана [Cloudflare Workers](/ky/ops/cloudflare/)
веб катмарын гана иштетет. Жаңылоолор [upgrade.md](/ky/ops/upgrade/) документинде,
ал эми камдык көчүрмөлөр жана калыбына келтирүү машыгуусу
[backup-restore.md](/ky/ops/backup-restore/) документинде.

## Эмне керек <!--quire:what-you-need-->

- Docker Engine 27 же андан жогорусу жана Compose плагини 2.30 же
  андан жогорусу.
- Демилгелик топтом үчүн 4 CPU ядросу жана 8 ГБ эс тутум; `--profile full`
  менен 8 ядро жана 16 ГБ (ClamAV өзү жалпысынан 1.5 ГБга жакын
  сигнатураны кармайт).
- Веб катмары үчүн DNS аты жана ишенбөө контенти үчүн экинчиси. Алар
  айырмаланган хосттор болушу керек: SCORM пакеттери жана жүктөлгөн HTML
  контент башталышында иштетилет, ошондуктан алар эч качан LMS'тин
  cookie'лерин окуй албайт.
- Жергиликтүү сыноо үчүн `lvh.me` жана `*.localhost` 127.0.0.1'ге чечилет,
  мына ушуну `docker/.env.example` колдонот. Топтун өзүнүн `proxy`
  кызматы экөөнүн да жергиликтүү сертификат башкармалыгы менен https
  аркылуу тейлейт, ошондуктан башка эч нерсе орнотулбайт ("TLS" карагыла).
- Хосттоги 80 жана 443 порттору бош болушу керек
  (`QUIRE_PROXY_HTTP_PORT` жана `QUIRE_PROXY_HTTPS_PORT` аларды жылдырат).

## Биринчи иштетүү <!--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` `docker/.env`'ти `docker/.env.example`'тен
бардык сырлар түзүлгөн абалда жазат (маалымат базасынын паролдору, кол
коюу жана негизги килттер, контент ачуу килиттер жупу) жана аудит
чек абалынын кол коюу килитин `docker/secrets/audit-signing-key.pem`
ишинде, аны Compose жумушчуларга сыр катары туташтырат. Ага гана `sh`,
`awk` жана `openssl` керек, жана ал бар болгон `docker/.env`'ти
үстүнөн жазуудан баш тартат. Эки файлды тең хосттон тышкары көчүрүңүз:
`QUIRE_MASTER_KEY`'сиз калыбына келтирилген маалымат базасы сакталган
купуялык маалыматтарын шифрлөөдөн чыгара албайт. Файлды кол менен
толтуруу үчүн, `cp docker/.env.example docker/.env`; файл ар бир сырдын
кантип түзүлөрүн айтат.

Эки башталыш да `https` болушу керек: контент кызматы өндүрүштө жөнөкөй
http'ни четке кагат жана алар бирдей катталуучу доменди бөлүшпөшү керек.
`proxy` кызматы экөө үчүн TLS'ни аяктайт ("TLS" карагыла); `init-env.sh`
`http://` башталышын четке кагат.

Топтом так тартипте башталат, ар бир кадам мурункусун күтөт:

1. `postgres` саламат болот. Биринчи иштетүүдө анын башталыш скрипти
   (`docker/postgres/init/90-passwords.sh`) төрт роль паролун коюп,
   чыгат.
2. `migrate` ар бир миграцияны колдонуп, башкы маалымат базасында жана
   ар бир айырмаланган tenant маалымат базасында жумуш кезегин түзөт,
   алардын баары макул экенин текшерет, андан кийин чыгат
   (docs/ops/upgrade.md).
   Миграциялар ар бир иштетүүдө иштетилет жана бирдейликке ээ,
   ошондуктан жаңылоо — бул жаңы сүрөт жана кайра иштетүү.
3. `init` (`apps/web/src/first-run.ts`) колдонмо маалымат базасын
   `QUIRE_DATABASE_ID` астында каттайт жана, `QUIRE_SETUP_ADMIN_EMAIL`
   орнотулган болсо, биринчи уюмду жана анын администраторун түзөт.
   Кирүү дареги жана түзүлгөн пароль бир жолу, `docker compose logs init`
   ичинде басылып чыгат.
4. `web`, `content`, `worker`, `scheduler`, `collab` жана `centrifugo`
   башталат.
5. `proxy` `web` жана `content` саламат болгондо башталат.

`https://demo.` дегенди, андан кийин колдонмо домениңизди жазып ачыңыз
(`init` журналы так кирүү дарегин басып чыгарат), жана кириңиз. Жергиликтүү
орнотууда, алгач проксинин сертификат башкармалыгына ишендириңиз ("TLS"
карагыла). Түзүлгөн паролду `/account/security` жеринен өзгөртүңүз.

Милдеттүү сыры жок иштетилген процесс башталыштан баш тартат жана журналында
жетпей турган жөндөөнү атайт. Эч нерсе жарым конфигурацияланган абалда
башталбайт.

## Кызматтар жана профилдер <!--quire:services-and-profiles-->

| Service | Profile | What it does |
| --- | --- | --- |
| postgres | always | Маалымат базасы (`docker/postgres.Dockerfile`'ден курулган pgvector менен PostgreSQL 18), биринчи күйгүзүүдөн бери WAL архивденет |
| migrate, init | always | Бир жолу: миграциялар, андан кийин биринчи иштетүү |
| web | always | LMS, `QUIRE_HTTP_PORT` (8080) үстүндө |
| content | always | Ишенбөө контентинин башталышы, `QUIRE_CONTENT_PORT` (8081) үстүндө |
| worker | always | Фон жумуштары: почта, отчёттор, файл иштетүү, вебхуктар |
| scheduler | always | Кайталануучу жумуштар: 64 убакыт ички жумушун каттап, аларды жумушчуга өткөрөт; бир учурда бир жетекчи |
| collab | always | Кызматташып тексти өзгөртүү websocket'и, `QUIRE_COLLAB_HTTP_PORT` (1234) үстүндө |
| centrifugo | always | Реалдуу убакыт fan-out, `QUIRE_REALTIME_PORT` (8000) үстүндө |
| proxy | always | Caddy, 80 жана 443 портторундагы TLS алдыңкы эшиги ("TLS" карагыла) |
| valkey | `cache` | Кэш жана ылам чектөөлөр |
| clamav | `scan` | Жүктөөлөрдү зыяндуу программаларга текшерүү |
| gotenberg | `preview` | Office'тен PDF алдын ала көрүнүштөрү, сертификат рендерлөө |
| imgproxy | `images` | Көлчөмдөлгөн жана которулган сүрөттөр |
| transcoder | `video` | LGPL гана ffmpeg бар жумушчу сүрөтү, видео которуулар үчүн |
| seaweedfs | `storage` | Бул хостто S3 ылайыктуу объекттик сактоо |
| otelcol | `observability` | OpenTelemetry коллектору |
| mailpit | `devmail` | Бардык чыгып бараткан почтаны кармайт, Quire'ди сыноо үчүн |
| backup | `backup` | Бир жолу негизги камдык көчүрмө; backup-restore.md карагыла |
| backup-scheduler, backup-offsite | `backup` | Ар `QUIRE_BACKUP_INTERVAL_HOURS` сайын негизги камдык көчүрмө, жана жумасына текшерүү машыгуусу менен шифрленген хосттон тышкары көчүрмөлөр |
| h5p | `h5p` | Сиз `QUIRE_H5P_IMAGE` ичинде берген H5P LTI 1.3 курал сүрөтү, `QUIRE_H5P_PORT` (8090) үстүндө; "H5P провайдерин туташтыруу" карагыла |

`--profile full` `backup` жана `h5p`дан тышкары бардык коопсуз кызматты
баштайт. Алардын бирин `docker compose -f docker/compose.yaml --profile scan up -d`
менен баштаңыз. Коопсуз кызматсыз Quire да иштейт жана эмне жетпейт
турганын айтат: текшергич болбосо жүктөөлөр текшерилбей сакталат жана
администраторга айтылат; Gotenberg болбосо файлдар алдын ала көрүнүштүн
ордуна жүктөөнү сунуштайт; транскодер болбосо видео оригинал файл
катары ойнотулат.

Ар бир тышкы сүрөт жана анын лицензия милдеттенмелери
`docker/third-party-containers.yaml` ичинде тизилген.

### H5P провайдерин туташтыруу <!--quire:connecting-an-h5p-provider-->

Quire H5P убакыт ичинде аткаруучусун же sidecar'ын (ADR 0019) киргизбейт
жана жеткирбейт. H5P колдонсоңуз, өз хостингдеги жазылууңузду бериңиз
же өзүңүздүн өзүн-өзү кармоочу H5P инстанцияңызды Quire'ден айырмаланган
тарабынан башкарыңыз. Ошол провайдерди LTI 1.3 сырткы куралы катары
каттаңыз жана анын контентин курстарга курал иш-аракеттери катары
кошуңуз. Quire балдарды жана иш-аракет/баалоо прогрессин LTI Assignment
and Grade Services (AGS) аркылуу алмаштырат. Провайдер ошондой эле xAPI
билдирүүлөрүн жөнөтсө, аны Quire'дин xAPI билдирүүлөр кампасы үчүн
айырмаланган конфигурациялаңыз; AGS бал/прогресс алмашуусу xAPI
билдирүүлөрүн жөнөтпөйт. Moodle импорттору H5P иш-аракеттерин LTI куралынын
туташуусун талап кылат деп кабарлайт. Провайдер H5P убакыт ички
аткаруусу, авторлук иши, контент банкы жана аракет тарыхы үчүн жооптуу
бойдон калат.

Бул хостто өзүңүздүн өзүн-өзү кармоочу инстанцияңызды иштетүү үчүн,
`QUIRE_H5P_IMAGE`'ти анын сүрөтүнө коюп, `h5p` профилин баштаңыз. Compose
аны `QUIRE_H5P_PORT` (8090) үстүндө чыгарып, маалыматын `h5p-data`
томунда кармайт; сүрөт жана аны менен келген милдеттенмелер сиздики
бойдон калат.

## Жөндөөлөр <!--quire:settings-->

Ар бир процесс `docker/.env` окуйт. Шаблон, `docker/.env.example`, ар бир
жөндөөнү анын демилгелик мааны менен тизмелейт. Топтор:

### Даректер <!--quire:addresses-->

| Setting | Meaning |
| --- | --- |
| `QUIRE_APP_ORIGIN` | LMS'тин ачык дареги, мисалы `https://learn.example.com` |
| `QUIRE_CONTENT_ORIGIN` | Контент башталышы, айырмаланган хост |
| `QUIRE_PLATFORM_DOMAINS` | Уюмдар турган домендер, үтүр менен бөлүнгөн |
| `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`. `vercel` жана `cloudflare` үчүн башка нускакаларды карагыла |
| `QUIRE_TRUSTED_PROXY_CIDRS` | Алардын `X-Forwarded-For`'у ишене турган проксилер |

### Сырлар <!--quire:secrets-->

| Setting | Meaning |
| --- | --- |
| `QUIRE_SECRET_KEY` | Сессияларга жана токендерге кол коёт. 64 hex аркы |
| `QUIRE_MASTER_KEY` | SSO жана вебхук сырлары сыяктуу сакталган купуялык маалыматтарды оройт. 32 байт, base64. Веб катмары жана жумушчу бирдей маанын талап кылат. Алмаштыруу: [key-rotation.md](/ky/ops/key-rotation/) |
| `QUIRE_MASTER_KEY_VERSION` | Негизги килиттин версия белгиси, орнотулбаса `v1`. Алмаштырганда жогорулатыңыз |
| `QUIRE_MASTER_KEY_RETIRED` | Мурунку негизги килттер алар мөөрлөгөндү окуу үчүн дагы керек, `v1=<base64>` түрүндө. Алмаштыруу чечилбеген эч нерсе калбай бүткөндөн кийин чыгарыңыз |
| `QUIRE_COLLAB_SIGNING_KEY` | Веб жана collab тарабынан редакторлоо токендерине кол коюу үчүн бөлүшүлөт |
| `QUIRE_BACKUP_SIGNING_KEY` | Курс камдык көчүрмөлөрүнө кол коёт (милдеттүү эмес) |

`QUIRE_MASTER_KEY`'дин көчүрмөсүн бул хосттон тышкары бир жерде кармаңыз.
Анысыз калыбына келтирилген маалымат базасы камтый турган купуялык
маалыматтарды шифрлөөдөн чыгара албайт.

### Маалымат базасы <!--quire:database-->

| Setting | Meaning |
| --- | --- |
| `POSTGRES_PASSWORD` | Superuser, контейнер жана камдык көчүрмөлөр колдонот |
| `QUIRE_DB_APP_PASSWORD`, `QUIRE_DB_MIGRATOR_PASSWORD`, `QUIRE_DB_REPORT_PASSWORD`, `QUIRE_DB_AUDIT_PASSWORD` | Роль паролдору, биринчи иштетүүдө коюлат |
| `DATABASE_URL` | Колдонмо ролу. Анын жасаган ар бир суроого сап деңгээлинде коргоо колдонулат |
| `DATABASE_MIGRATOR_URL`, `QUIRE_MIGRATION_URL` | Миграциялоочу ролу, `migrate` жана `init` үчүн |
| `QUIRE_SUPERUSER_URL` | Гана биринчи иштетүү колдонот |
| `QUIRE_REPORT_DATABASE_URL` | Окуу гана болгон отчёт ролу, отчёттор жана отчёт куруучу үчүн |
| `QUIRE_AUDIT_DATABASE_URL` | Аудит ролу, аудит консольу жана SIEM экспорту үчүн |
| `QUIRE_DATABASE_ID` | Кайсы болбосун UUID, орнотуунун өмүрү бою бекитилет |

Роль паролдору гана маалымат базасы томунун биринчи жолу түзүлгөндө
колдонулат. Кийин аны өзгөртүү үчүн `ALTER ROLE` колдонуңуз, андан кийин
туура келүүчү даректи жаңыртыңыз.

`QUIRE_REPORT_DATABASE_URL` `DATABASE_URL` менен конфигурацияланган
физикалык маалымат базасы үчүн колдонулат. Башка каалаган катталган
физикалык маалымат базасы үчүн анын өзүнүн `quire_report` туташуу
дарегин веб жана жумушчу чөйрөлөрүнө коюңуз, андан кийин өзгөрмөнүн атын
ошол маалымат базасынын **Reporting environment variable** талаасына
`env:NAME` катары жазыңыз. Референс анын колдонмо туташуусу менен бирдей
маалымат базасын, мүмкүн болсо анын окуу репликасын көрсөтүшү керек.
Ар бир отчёт бети tenant'ты өз маалымат базасынын отчёт туташуусуна
ээрчитет: отчёт куруучу жана сакталган отчёттор, пландалган жеткирүүлөр,
отчёт экспорттору, аналитика, аудит журналы, REST аудит ресурстары жана
жардамчынын аудит издөөсү. Алардын баары эч качан башка маалымат
базасынын отчёт дарегин айлампага албайт. Маалымат базасында отчёт
туташуусу болбосо, жөнкөй отчёттор ошол маалымат базасынын өзүнүн
колдонмо туташуусунда иштетилет, ал эми аналитика жана ар бир аудит
окуусу четке кагылат жана ошондой айтат, анткени колдонмо ролу аудит
изин окуй албайт.

### Драйверлер <!--quire:drivers-->

| Setting | This release | Notes |
| --- | --- | --- |
| `QUIRE_STORAGE_DRIVER` | `local` (демилгелик), `s3` же `azure` | `local` файлдарды `files` томунда кармайт. `s3` AWS S3, R2, GCS өз ара иштешүүсүн жана башка S3 ылайыктуу кампаларды камтыйт, улантылуучу multipart жүктөөлөр менен |
| `QUIRE_REALTIME_DRIVER` | `inprocess` (демилгелик), `sse`, `centrifugo` же `durable_objects` | `inprocess` бир веб контейнер үчүн ылайык; бир нече болсо `centrifugo` же `sse` колдонуңуз |
| `QUIRE_CACHE_DRIVER` | `memory` (демилгелик), `postgres` же `valkey` | `memory` процесс сайын; ылам чектөөлөр контейнерлер аралык сакталышы үчүн `valkey` же `postgres` колдонуңуз |
| `QUIRE_VIDEO_DRIVER` | `ffmpeg` (демилгелик) же `progressive_mp4` | Же хостингдеги провайдер: Cloudflare Stream, Mux же Bunny, алардын килттери менен |
| `QUIRE_IMAGE_DRIVER` | `noop` (демилгелик), `imgproxy` же `cloudflare` | `noop` ар бир сүрөттү оригинал көлчөмүндө берет. `imgproxy` төмөндөгү `images` профилин жана жөндөөлөрдү талап кылат; `cloudflare` Cloudflare Images колдонот |
| `QUIRE_MEETING_PROVIDER` | `bbb`, `zoom`, `teams`, `meet`, `jitsi` же `in_process` | Түз эфирлер үчүн платформанын демилгелик мааны. Орнотулбаса, түз эфирлер конфигурацияланган эмес деп айтышат, бир уюм Интеграциялар, Түз эфир провайдери астында өз эсеп жазуусун туташтырганча. Уюмдун өз эсеп жазуусу ар дайым бул маанды жеңет. Ар бир провайдердин өз жөндөөлөрү (`BBB_URL` жана `BBB_SECRET`, `ZOOM_*`, `TEAMS_*`, `GOOGLE_MEET_*` жана `JITSI_*` өзгөрмөлөрү) гана бул жерде аталган провайдер үчүн окулат |
| `QUIRE_MEETING_REGIONS` | `eu`, `uk`, `us` үтүр менен тизмеси | Платформанын демилгелик провайдери жолугушууларды кайда иштетет. Орнотулбаса, аймакка бекитилген уюмга каршы текшерилбейт, мурункудай. Уюмдун өз эсеп жазуусу аймактарын өз бетинде жарыялайт |

Бул релизге кирбеген драйвер мааны веб катмары башталганда, демилгелик
маан менен тынч түрдө алмаштырылгандын ордуна, жөндөөнү атап, четке
кагылат.

### Сүрөттөр <!--quire:images-->

Беттер сүрөттөрдү `/api/files/{id}/image/{size}` аркылуу төрт так
көлчөмдө сурайт, ал файлдын өзү менен бирдей жеткиликтүүлүктү текшерет,
андан кийин сүрөт кызматына багыттайт. Ар бир уюм саатына
`QUIRE_IMAGE_SPECS_PER_HOUR` (демилгелик 2000) жаңы сүрөт жана көлчөм
жупун сурай алат; ошол саатта мурун түзүлгөн көлчөмдөр эсептен чыкпайт.
Бир нече веб контейнер болсо `valkey` же `postgres`ты `QUIRE_CACHE_DRIVER`
катары колдонуңуз, ошондо чек алар аралык сакталат.

| Setting | Driver | Notes |
| --- | --- | --- |
| `IMGPROXY_URL` | `imgproxy` | Браузерлер imgproxy'ге жетет дарек, мисалы `https://images.example.org`. `images` профили аны `QUIRE_IMAGES_PORT` (8082) үстүндө чыгарат |
| `IMGPROXY_KEY`, `IMGPROXY_SALT` | `imgproxy` | hex стрингдер, imgproxy иштетилген мааны менен бирдей. Ар бирин `openssl rand -hex 32` менен түзүңүз. Quire ар бир сүрөт дарегин алар менен кол коёт, ошондуктан imgproxy Quire сурамаган эч нерсени рендерлейбейт |
| `QUIRE_IMAGE_SOURCE_ORIGIN` | `imgproxy` жергиликтүү сактоо менен | imgproxy оригиналдарды кайдан алат. Compose `http://web:3000` коюп берет. `s3` же `azure` сактоо менен imgproxy bucket'тан алат жана бул колдонулбайт |
| `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_IMAGES_TOKEN`, `CLOUDFLARE_IMAGES_ACCOUNT_HASH` | `cloudflare` | Images өзгөртүү укугу бар API белгиси жана Images, Developer resources'тан эсеп хэши. Эсеп үчүн flexible variants'ты күйгүзүңүз |
| `CLOUDFLARE_IMAGES_SIGNING_KEY` | `cloudflare` | Милдеттүү эмес. Орнотулганда сүрөттөр жеке болот жана ар бир дарек кол коюлуу жана мөөнөтү бүтөт. Анысыз сүрөттөр эч ким болжой албаган `QUIRE_SECRET_KEY`'ден түзүлгөн даректерде ачык |

Cloudflare Images колдонгон ар бир оригиналдын өз көчүрмөсүн сактайт.
Файл өчүрүлгөндө жумушчу ал көчүрмөнү оригиналдан мурун өчүрөт.

### Кезек <!--quire:queue-->

Фон жумуштары ошол эле Postgres маалымат базасында pg-boss колдонот,
ошондуктан иштетүү керек болгон кезек кызматы жок жана эч нерсе
конфигурациялоонун кереги жок. Жумуштар пайда кылган өзгөрүү менен бирдей
транзакцияда кезекке турат, ошондуктан кулаак бирөөнү жоготпой же эки
жолу жөнөтпөйт. `QUIRE_QUEUE_DRIVER` бул жерде `pgboss`, анын демилгелиги;
`vercel` жана `cloudflare` гана жеңил билдирүү жана вебхук жеткирүүлөрүн
платформанын өз кезегине жылдырат, жана Vercel жана Cloudflare нускалары
аларды жана алардын веб катмарлары кантип кезекке турарын сүрөттөйт.

### Почта <!--quire:email-->

Бирөөсүн коюңуз:

- `QUIRE_EMAIL_PROVIDER_CONFIG`: HTTP провайдерин жана анын купуялык
  маалыматын атаган JSON объекти, мисалы
  `{"provider":"postmark","token":"..."}`. Postmark, Amazon SES, Mailgun,
  SendGrid жана Resend колдоого алынган.
- `QUIRE_SMTP_URL`: `smtp://user:password@host:587`. Гана бул максат
  үчүн; серверсиз максаттар SMTP'ни тосуп койот.

`QUIRE_MAIL_FROM` — жөнөтүүчү. Quire'ди сыноо үчүн `devmail` профилин
баштаңыз, `QUIRE_SMTP_URL=smtp://mailpit:1025` коюңуз жана почтаны
`http://localhost:8025` окуңуз.

### Коопсуз кызматтар <!--quire:optional-services-->

| Setting | With profile |
| --- | --- |
| `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` же `QUIRE_MEILISEARCH_URL` | Сырткы издөө; болбосо Postgres толук текст |
| `QUIRE_BREACH_CHECK_PROVIDER=off`, `QUIRE_BREACH_CHECK_URL` | Пароль ачыкка чыкканын текшерүү. Демилгелик түрдө `api.pwnedpasswords.com`'а каршы күйүк (беш аркыдан турган хэш префикси гана жөнөтүлөт); `off` аны өчүрөт, ал эми дарек өзүңүз башкарган range API'гин көрсөтөт |

### Байкоо <!--quire:observability-->

`OTEL_EXPORTER_OTLP_ENDPOINT` ар бир процесс издерди жана метрикаларды
жөнөткөн коллекторду атайт; `observability` профили менен бул
`http://otelcol:4318`, жана өз бэкэндиңиз үчүн экспортёрду кошкон жер —
`docker/otel-collector.yaml`. Веб катмары, жумушчу, кезектеөөчү, контент
жана collab процесстери орнотулганда OTLP/HTTP аркылуу спандарды
экспорттойт (веб суроолору, tenant маалымат базасынын транзакциялары,
жумушчу жумуштары жана чыгып бараткан чакырымдар), жана метрикаларды
ошол эле дарекке ар мүнөттө (`OTEL_METRICS_EXPORTER=none` аларды өчүрөт).
`OTEL_TRACES_SAMPLER_ARG` сакталган издердин үлүшүн коюп, чыгат. Журналдар
`LOG_LEVEL` боюнча стандарттык чыгууга кетет, жана Compose аларды
алмаштырып турат. Излер эч качан жеке маалыматты алып жүрбөйт.

### Аймактык чыгуу (ЕБ маалыматынын жайгашкан жери) <!--quire:regional-egress-eu-data-residency-->

`QUIRE_REGION=eu` топтом Европа Биримдигинин уюмдарын тейлөөрүн айтат.
Андан кийин жумушчу ЕБ'ге бекитилген уюм үчүн жасалган ар бир чыгып
барган суроону акылдуу тизмеге (21-compliance.md 8.1-бөлүмү) кармайт.
Акылдуу тизме — конфигурацияланган кызматтар аймак үчүн жарыялаган
хосттор (сактоо дареги, почта провайдери, хостингдеги видео провайдери,
уюмдун өзүнүн сактоо багыттары, ЖИ провайдерлери жана почта эсеп
жазуусу), иштеп турган жагдай алдындагы каалаган кызматтын хосттору,
жана `QUIRE_EGRESS_ALLOW_HOSTS` ичинде сиз тизген хосттор. Башка каалаган
ачык хостко суроо жөнөтүлгөнгө чейин четке кагылат, баш тартуу уюмдун
аудит изине `privacy/egress_refused` катары жазылат жана ал Compliance,
Data residency астында тизмеленет.

| Setting | Values | Effect |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | Хост аттарынын үтүр тизмеси же ар бир поддомен үчүн `*.example.org` | ЕБ уюму жете ала турган кошумча хосттор. Вебхук, xAPI жана SIEM учурлары, блог фидтери жана Amazon SES хосттору бул жерге кирет, анткени алар уюмдун өз тандоосу жана эч кандай кызмат жарыялабайт. Loopback, жеке даректер жана `web` же `clamav` сыяктуу бир тамгалуу аттар — өз тармагыңыз жана эч качан текшерилбейт |

Британия жана АКШ уюмдары хост тизмесине кармалбайт; алар кызматтын
аймак текшерүүлөрүн сактайт. Тизмени жумушчуга коюңуз; админ бети аны
акылдуу тизмени көрсөтүш үчүн веб катмарында окуйт, ошондуктан аны
бардык кызмат окуган `docker/.env`'ге коюңуз.

Колдонмо текшерүү так ката жана аудит жазуусун берет, жана бул кепилдик
эмес: код туура эмес болушу мүмкүн. Кепилдик — бул тармак. Compose аны
сиз үчүн мажбурлабайт. Аймактык топтом үчүн `worker` жана `web`
кызматтарын `internal: true` тармагына коюңуз, анын чыгып бараткан жалгыз
жолу — `QUIRE_EGRESS_ALLOW_HOSTS` уруксат берген хостторго жана
конфигурацияланган кызматтарыңыздын хостторуна уруксат берген чыгуу
проксиси (мисалы Squid же tinyproxy контейнеринен), жана ошол кызматтар
үчүн `HTTPS_PROXY` коюңуз. Жайгашкан жер бети колдонмо уруксат берген так
хостторду тизмелейт, ошондуктан эки тизмени салыштырса болот.

## Абал <!--quire:health-->

| Endpoint | Meaning |
| --- | --- |
| `/healthz` | Тирүүлүк: процесс жооп берет. Compose абал текшерүүлөрү буну колдонот |
| `/readyz` | Даярдык: көз карандылыктар жеткиликтүү, жана ар коопсуз кызмат конфигурацияланган же жок деп кабарлайт. Жүктү бөлүштүргүчүңүздү бул жерге багыттаңыз |

`docker compose -f docker/compose.yaml ps` ар бир кызматтын абалын
көрсөтөт.

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

`proxy` кызматы (Caddy, Apache-2.0, `docker/caddy/Caddyfile`) демилгелик
топтун бир бөлүгү. Ал 80 жана 443 портторунда жооп берет жана
маршуттайт:

| Host or path | Goes to |
| --- | --- |
| `QUIRE_PROXY_CONTENT_HOST` | `content` |
| `QUIRE_PROXY_APP_HOST`, ар бир tenant поддомени жана кастомдук домен | `web` |
| Ошол хосттордоги `/_collab/` | `collab` (websocket, `QUIRE_COLLAB_URL`) |
| Ошол хосттордоги `/_realtime/connection/` | `centrifugo`'нун клиент websocket'и; анын сервер API'си эч качан ачыкка чыгарылбайт |
| Ошол хосттордоги `/_images/` | `imgproxy`, `images` профили менен (`IMGPROXY_URL`) |

`init-env.sh` `QUIRE_PROXY_APP_HOST`, `QUIRE_PROXY_CONTENT_HOST`,
`QUIRE_PROXY_HTTPS_PORT`, `QUIRE_COLLAB_URL` жана `IMGPROXY_URL`'ди эки
башталыштан түзөт, ошондуктан алар ажырабай калышы мүмкүн эмес. Башталышты
кол менен өзгөртсөңүз, аларды чогуу түзөтүңүз.

Сертификаттар `QUIRE_PROXY_TLS`'ти ээрчитет:

- `internal` (демилгелик): Caddy'дин өзүнүн сертификат башкармалыгы,
  `localhost`, `*.localhost` жана `lvh.me` үчүн. Анын тамырына бир жолу
  ишендириңиз, андан кийин сейилдеңиз:

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

  `quire-local-ca.crt`'ти система же браузер ишенүү кампасына кошуңуз.
  `curl` аны `--cacert` менен алат.
- Электрондук почта дареги: чыныгы хост аттары үчүн автоматтык ACME
  сертификаттары (Let's Encrypt, андан кийин ZeroSSL). Эки башталыштын
  жана ар бир tenant хостунун DNS'и бул жерди көрсөтүшү керек жана 80
  жана 443 порттору интернеттен жеткиликтүү болушу керек.

Tenant хосттору керек болгондо, биринчи сапарда жана гана web бул ат
ушул орнотуга таандык экенин растаганда чыгарылат (`/tls-allowed`,
Compose тармагынан суранылат). Ушул ат менен wildcard сертификат же DNS
провайдери плагининин кереги жок, жана атты хостка багыттаган белгисиз
адам сертификат сурагызга келтирүүсү мүмкүн эмес. Сертификаттар жана
жергиликтүү башкармалык `caddy-data` томунда турат; `internal`
колдонсоңуз, калгандары менен бирге камдыкка көчүрүңүз.

Web проксинин гана `X-Forwarded-For`'уна ишенет: проксиндин так дареги
(`QUIRE_PROXY_ADDRESS`, демилгелик `172.29.64.10`) так поднетте
(`QUIRE_COMPOSE_SUBNET`) турат, жана `QUIRE_TRUSTED_PROXY_CIDRS` ошол
даректи атайт. Поднет хосттоги тармак менен кагышса, экөөнү да
өзгөртүп, `docker compose down`'ди `up`'тан мурун иштетиңиз.

## Өзүңүздүн тескери проксиңиздин артында <!--quire:behind-your-own-reverse-proxy-->

Ордунан мурун иштетип жаткан жүктү бөлүштүргүч же проксинди колдонуу
үчүн, `proxy`'ни калтырып коюңуз (`docker compose up -d --scale proxy=0`)
жана TLS'ни `web` (8080), `content` (8081), `collab` (1234, websocket) жана
`centrifugo` (8000, websocket) алдында аяктаңыз. Ачык даректерди
`QUIRE_APP_ORIGIN`, `QUIRE_CONTENT_ORIGIN` жана `QUIRE_COLLAB_URL`
(`wss://`) ичине, ал эми проксиңиздин дарек диапазонун
`QUIRE_TRUSTED_PROXY_CIDRS` ичине коюңуз.

## Маселелерди чечүү <!--quire:troubleshooting-->

- `init` "QUIRE_DATABASE_ID is not a UUID" менен чыгат: аны `uuidgen`
  менен коюңуз.
- `web` "did not start on compose" менен кайра иштетилет: журнал аткара
  албаган ар бир жөндөөнү жана ордуна эмне колдонууну тизмелейт.
- Биринчи иштетүүдөн кийин `.env` ичинде роль паролун өзгөртүү эч нерсе
  кылбайт: башталыш скрипти бир жолу иштетилет. `ALTER ROLE` колдонуңуз.
- `CLAMAV_URL` орнотулганда жүктөөлөр сканер катасы менен ийгиликсиз
  болот: ClamAV биринчи иштетүүдө сигнатураларын жүктөйт, бул бир
  нече мүнөт алат.

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