---
title: "Docker Compose-ৰে Quire ইনষ্টল"
description: "নিজৰ infrastructure-ত Docker Compose-ৰে Quire ইনষ্টল কৰক।"
image: "https://docs.quirelms.com/og.png"
---

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

# Docker Compose-ৰে Quire ইনষ্টল

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

এইটো এটা host-ত সম্পূৰ্ণ product: LMS, ইয়াৰ background কাম, realtime আৰু collaborative editing service, আৰু profile-ৰ পিছত থকা প্ৰতিটো ঐচ্ছিক service। ডিজাইন `docs/architecture/23-ops.md`ৰ section 2-ত।

আন target: [Vercel](/as/ops/vercel/) আৰু [Cloudflare Workers](/as/ops/cloudflare/)-ত কেৱল web tier চলে। Upgrade [upgrade.md](/as/ops/upgrade/)ত, backup আৰু restore drill [backup-restore.md](/as/ops/backup-restore/)ত আছে।

## কি লাগিব <!--quire:what-you-need-->

- Docker Engine 27 বা তাৰ পিছৰ version, Compose plugin 2.30 বা তাৰ পিছৰ সৈতে।
- Default stack-ৰ বাবে 4 CPU core আৰু 8 GB memory; `--profile full`ৰ বাবে 8 core আৰু 16 GB (ClamAV-এ অকলেই প্ৰায় 1.5 GB signature ৰাখে)।
- Web tier-ৰ বাবে এটা DNS name আৰু বিশ্বাস কৰিব নোৱাৰা content-ৰ বাবে দ্বিতীয় এটা। পৃথক host হ’ব লাগিব: SCORM package আৰু upload কৰা HTML content origin-ত চলে, যাতে LMS cookie কেতিয়াও পঢ়িব নোৱাৰে।
- Local test-ৰ বাবে `lvh.me` আৰু `*.localhost`-এ 127.0.0.1লৈ resolve কৰে, `docker/.env.example`-এ ইয়াক ব্যৱহাৰ কৰে। Stack-ৰ নিজা `proxy` service-এ local certificate authority-সহ https-ত দুয়ো serve কৰে, সেয়ে আন একো install নালাগে (চাওক “TLS”)।
- Host-ত 80 আৰু 443 port খালী থাকিব লাগিব (`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`ৰ পৰা লিখে আৰু সকলো secret সৃষ্টি কৰে (database password, signing আৰু master key, content launch key pair); লগতে `docker/secrets/audit-signing-key.pem`ত audit checkpoint signing key সৃষ্টি কৰে, Compose-এ worker-ত secret হিচাপে mount কৰে। ইয়াক কেৱল `sh`, `awk` আৰু `openssl` লাগে আৰু আগৰ `docker/.env` overwrite কৰিবলৈ অস্বীকাৰ কৰে। দুয়োটা file host-ৰ বাহিৰত copy কৰক: `QUIRE_MASTER_KEY` অবিহনে restored database-ৰ সংৰক্ষিত credential decrypt নহয়। হাতেৰে file পূৰ কৰিবলৈ `cp docker/.env.example docker/.env` চলাওক; প্ৰতিটো secret কেনেকৈ সৃষ্টি কৰিব file-ত লিখা আছে।

দুয়ো origin `https` হ’ব লাগিব: production-ত content service-এ সাধাৰণ http অস্বীকাৰ কৰে আৰু দুয়োটাই registrable domain share কৰিব নোৱাৰে। `proxy` service-এ দুয়োটাৰ TLS terminate কৰে (চাওক “TLS”); `init-env.sh`-এ `http://` origin নাকচ কৰে।

Stack নিৰ্দিষ্ট ক্ৰমত আৰম্ভ হয় আৰু প্ৰতিটো step-এ আগৰটোৰ বাবে অপেক্ষা কৰে:

1. `postgres` সুস্থ হয়। প্ৰথমবাৰ আৰম্ভ হওঁতে ইয়াৰ init script (`docker/postgres/init/90-passwords.sh`)-এ চাৰিটা role password ছেট কৰে।
2. `migrate`-এ প্ৰতিটো migration প্ৰয়োগ কৰি control database আৰু প্ৰতিটো dedicated tenant database-ত job queue bootstrap কৰে, সকলো মিলিছে নে পৰীক্ষা কৰি ওলাই যায় (docs/ops/upgrade.md)। প্ৰতিটো startup-ত migration চলে আৰু idempotent, সেয়ে upgrade মানে নতুন image আৰু restart।
3. `init` (`apps/web/src/first-run.ts`)-এ application database `QUIRE_DATABASE_ID`ৰ অধীনত register কৰে আৰু `QUIRE_SETUP_ADMIN_EMAIL` set থাকিলে প্ৰথম organisation আৰু administrator সৃষ্টি কৰে। Sign-in address আৰু generate কৰা password এবাৰ `docker compose logs init`ত ছপা হয়।
4. `web`, `content`, `worker`, `scheduler`, `collab` আৰু `centrifugo` আৰম্ভ হয়।
5. `proxy` আৰম্ভ হয় `web` আৰু `content` সুস্থ হ’লে।

`https://demo.`ৰ পিছত আপোনাৰ application domain লিখি খোলক (`init` log-ত হুবহু sign-in address ছপা হয়) আৰু sign in কৰক। Local install-ত প্ৰথমে proxy-ৰ certificate authority trust কৰক (চাওক “TLS”)। `/account/security`ত generate কৰা password সলনি কৰক।

প্ৰয়োজনীয় secret নথকা process আৰম্ভ হ’বলৈ অস্বীকাৰ কৰি log-ত অনুপস্থিত setting নামসহ কয়। আধা-configured অৱস্থাত একো আৰম্ভ নহয়।

## Service আৰু profile <!--quire:services-and-profiles-->

| Service | Profile | কাম |
| --- | --- | --- |
| postgres | সদায় | Database (pgvector-সহ PostgreSQL 18, `docker/postgres.Dockerfile`ৰ পৰা build), প্ৰথম boot-ৰ পৰাই WAL archive হয় |
| migrate, init | সদায় | এবাৰ: migration, তাৰ পিছত প্ৰথম run |
| web | সদায় | LMS, `QUIRE_HTTP_PORT`ত (8080) |
| content | সদায় | বিশ্বাস নকৰা content origin, `QUIRE_CONTENT_PORT`ত (8081) |
| worker | সদায় | Background job: email, report, file processing, webhook |
| scheduler | সদায় | পুনৰাবৃত্ত job: runtime-ৰ 64টা schedule register কৰি worker-লৈ দিয়ে; একে সময়ত এজন leader |
| collab | সদায় | Collaborative editing websocket, `QUIRE_COLLAB_HTTP_PORT`ত (1234) |
| centrifugo | সদায় | Realtime fan-out, `QUIRE_REALTIME_PORT`ত (8000) |
| proxy | সদায় | Caddy, port 80 আৰু 443-ৰ TLS front door (চাওক “TLS”) |
| valkey | `cache` | Cache আৰু rate limit |
| clamav | `scan` | Upload-ৰ malware scan |
| gotenberg | `preview` | Office-ৰ পৰা PDF preview, certificate render |
| imgproxy | `images` | Image size আৰু format সলনি |
| transcoder | `video` | Video rendition-ৰ বাবে কেৱল LGPL ffmpeg-সহ worker image |
| seaweedfs | `storage` | এই host-ত S3-compatible object storage |
| otelcol | `observability` | OpenTelemetry collector |
| mailpit | `devmail` | Quire চেষ্টা কৰোঁতে সকলো outgoing mail ধৰে |
| backup | `backup` | এবাৰ চলা base backup; backup-restore.md চাওক |
| backup-scheduler, backup-offsite | `backup` | `QUIRE_BACKUP_INTERVAL_HOURS`ত base backup আৰু সাপ্তাহিক verification drill-সহ host-ৰ বাহিৰত encrypted copy |
| h5p | `h5p` | `QUIRE_H5P_IMAGE`ত আপুনি দিয়া H5P LTI 1.3 tool image, `QUIRE_H5P_PORT`ত (8090); “H5P provider সংযোগ” চাওক |

`--profile full`-এ `backup` আৰু `h5p`ৰ বাহিৰে প্ৰতিটো optional service আৰম্ভ কৰে। এটা আৰম্ভ কৰিবলৈ `docker compose -f docker/compose.yaml --profile scan up -d` চলাওক। Optional service নাথাকিলেও Quire চলে আৰু কি নাই কয়: scanner নাথাকিলে upload scan নকৰাকৈ store হয় আৰু administrator-ক জনোৱা হয়; Gotenberg নাথাকিলে file preview-ৰ সলনি download দিয়ে; transcoder নাথাকিলে video original file হিচাপে চলে।

প্ৰতিটো third-party image আৰু licence-ৰ দায়িত্ব `docker/third-party-containers.yaml`ত তালিকাভুক্ত।

### H5P provider সংযোগ <!--quire:connecting-an-h5p-provider-->

Quire-এ H5P runtime বা sidecar embed বা ship নকৰে (ADR 0019)। H5P ব্যৱহাৰ কৰিলে নিজৰ hosted subscription দিয়ক অথবা Quire-ৰ পৰা পৃথকে নিজৰ self-hosted H5P instance চলাওক। Provider-টোক LTI 1.3 external tool হিচাপে register কৰি course-ত tool activity হিচাপে content যোগ কৰক। Quire-এ LTI Assignment and Grade Services (AGS)-ৰে grade আৰু কাৰ্য/নম্বৰ দিয়াৰ অগ্ৰগতি আদান-প্ৰদান কৰে। Provider-এ xAPI statement-ও পঠিয়ালে Quire-ৰ xAPI statement store-ৰ বাবে পৃথকে configure কৰক; AGS grade/progress exchange-এ xAPI statement নপঠিয়ায়। Moodle import-এ H5P activity-ৰ বাবে LTI tool connection লাগে বুলি report কৰে। H5P runtime, authoring, content bank আৰু attempt history-ৰ দায়িত্ব provider-ৰেই।

এই host-ত নিজা self-hosted instance চলাবলৈ `QUIRE_H5P_IMAGE` ইয়াৰ image-ত set কৰি `h5p` profile আৰম্ভ কৰক। Compose-এ `QUIRE_H5P_PORT`ত (8090) publish কৰে আৰু data `h5p-data` volume-ত ৰাখে; image আৰু ইয়াৰ দায়িত্ব আপোনাৰ।

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

প্ৰতিটো process-এ `docker/.env` পঢ়ে। Template `docker/.env.example`-এ default-সহ প্ৰতিটো setting তালিকাভুক্ত কৰে। গোটসমূহ:

### ঠিকনা <!--quire:addresses-->

| Setting | অৰ্থ |
| --- | --- |
| `QUIRE_APP_ORIGIN` | LMS-ৰ public ঠিকনা, যেনে `https://learn.example.com` |
| `QUIRE_CONTENT_ORIGIN` | Content origin, বেলেগ host |
| `QUIRE_PLATFORM_DOMAINS` | Organisation থকা domain-সমূহ, comma-separated |
| `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`। আন guide-ত `vercel` আৰু `cloudflare` চাওক |
| `QUIRE_TRUSTED_PROXY_CIDRS` | যাৰ `X-Forwarded-For` বিশ্বাস কৰা proxy |

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

| Setting | অৰ্থ |
| --- | --- |
| `QUIRE_SECRET_KEY` | Session আৰু token sign কৰে। 64 hexadecimal character |
| `QUIRE_MASTER_KEY` | SSO আৰু webhook secret-ৰ দৰে সংৰক্ষিত credential wrap কৰে। 32 byte, base64। Web tier আৰু worker-এ একে value লাগে। Rotation: [key-rotation.md](/as/ops/key-rotation/) |
| `QUIRE_MASTER_KEY_VERSION` | Master key-ৰ version label, unset হ’লে `v1`। Rotate কৰোঁতে বঢ়াওক |
| `QUIRE_MASTER_KEY_RETIRED` | আগতে secret seal কৰা master key, পঢ়িবলৈ এতিয়াও লাগে, `v1=<base64>` হিচাপে। কোনো unresolved নথকাকৈ rotation শেষ হ’লে আঁতৰাওক |
| `QUIRE_COLLAB_SIGNING_KEY` | Editing token sign কৰিবলৈ web আৰু collab-এ share কৰে |
| `QUIRE_BACKUP_SIGNING_KEY` | Course backup sign কৰে (ঐচ্ছিক) |

`QUIRE_MASTER_KEY`ৰ copy এই host-ৰ বাহিৰত ৰাখক। ইয়াৰ অবিহনে restore কৰা database-এ নিজৰ credential decrypt কৰিব নোৱাৰে।

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

| Setting | অৰ্থ |
| --- | --- |
| `POSTGRES_PASSWORD` | Superuser, container আৰু backup-এ ব্যৱহাৰ কৰে |
| `QUIRE_DB_APP_PASSWORD`, `QUIRE_DB_MIGRATOR_PASSWORD`, `QUIRE_DB_REPORT_PASSWORD`, `QUIRE_DB_AUDIT_PASSWORD` | Role password, প্ৰথম আৰম্ভণিত set হয় |
| `DATABASE_URL` | Application role। ইয়াৰ প্ৰতিটো query-ত row-level security প্ৰযোজ্য |
| `DATABASE_MIGRATOR_URL`, `QUIRE_MIGRATION_URL` | `migrate` আৰু `init`ৰ বাবে migrator role |
| `QUIRE_SUPERUSER_URL` | কেৱল first run-এ ব্যৱহাৰ কৰে |
| `QUIRE_REPORT_DATABASE_URL` | Report আৰু report builder-ৰ read-only report role |
| `QUIRE_AUDIT_DATABASE_URL` | Audit console আৰু SIEM export-ৰ audit role |
| `QUIRE_DATABASE_ID` | যিকোনো UUID, install-ৰ জীৱনকাললৈ স্থিৰ |

Database volume প্ৰথমবাৰ সৃষ্টি হওঁতেহে role password প্ৰয়োগ হয়। পিছত সলনি কৰিবলৈ `ALTER ROLE` ব্যৱহাৰ কৰি মিল থকা URL update কৰক।

`QUIRE_REPORT_DATABASE_URL` হৈছে `DATABASE_URL`-এ নাম দিয়া physical database-ৰ বাবে ব্যৱহৃত URL। আন registered physical database-ৰ বাবে web আৰু worker environment-ত নিজা `quire_report` connection URL set কৰি, তাৰ database-ৰ **Reporting environment variable** field-ত `env:NAME` ৰূপে variable name দিয়ক। Reference-টো application connection-ৰ একে database-লৈ, ভাল হ’লে read replica-লৈ, আঙুলিয়াব লাগিব। প্ৰতিটো report surface-এ tenant-ৰ নিজা database-ৰ report connection অনুসৰণ কৰে: report builder আৰু saved report, scheduled delivery, report export, analytics, audit log, REST audit resource আৰু assistant-ৰ audit search। আন database-ৰ report URL কেতিয়াও ধাৰ নলয়। Database-ত report connection নাথাকিলে সাধাৰণ report সেই database-ৰ নিজা application connection-ত চলে; analytics আৰু audit read-এ application role-এ audit trail পঢ়িব নোৱাৰা বাবে নাকচ কৰি এই কথা কয়।

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

| Setting | এই release-ত | টোকা |
| --- | --- | --- |
| `QUIRE_STORAGE_DRIVER` | `local` (default), `s3` অথবা `azure` | `local`-এ `files` volume-ত file ৰাখে। `s3`-এ AWS S3, R2, GCS interoperability আৰু আন S3-compatible store-সহ resumable multipart upload সামৰে |
| `QUIRE_REALTIME_DRIVER` | `inprocess` (default), `sse`, `centrifugo` অথবা `durable_objects` | এটা web container-ৰ বাবে `inprocess` উপযুক্ত; কেইবাটাও হ’লে `centrifugo` বা `sse` ব্যৱহাৰ কৰক |
| `QUIRE_CACHE_DRIVER` | `memory` (default), `postgres` অথবা `valkey` | `memory` প্ৰতিটো process-ৰ বাবে; container-সমূহৰ মাজত rate limit ৰাখিবলৈ `valkey` বা `postgres` ব্যৱহাৰ কৰক |
| `QUIRE_VIDEO_DRIVER` | `ffmpeg` (default) অথবা `progressive_mp4` | অথবা Cloudflare Stream, Mux বা Bunny-ৰ দৰে hosted provider আৰু ইয়াৰ key |
| `QUIRE_IMAGE_DRIVER` | `noop` (default), `imgproxy` অথবা `cloudflare` | `noop`-এ প্ৰতিটো image মূল আকাৰত দিয়ে। `imgproxy`-ৰ বাবে `images` profile আৰু তলৰ setting লাগে; `cloudflare`-এ Cloudflare Images ব্যৱহাৰ কৰে |
| `QUIRE_MEETING_PROVIDER` | `bbb`, `zoom`, `teams`, `meet`, `jitsi` অথবা `in_process` | Live session-ৰ platform default। Unset হ’লে Integrations, Live session provider-ৰ অধীনত organisation-এ নিজা account সংযোগ নকৰালৈ live session configured নহয় বুলি কয়। Organisation-ৰ নিজা account-এ এই value-তকৈ সদায় অগ্ৰাধিকাৰ পায়। ইয়াত নাম দিয়া provider-ৰ বাবেহে নিজা setting (`BBB_URL` আৰু `BBB_SECRET`, `ZOOM_*`, `TEAMS_*`, `GOOGLE_MEET_*`, `JITSI_*`) পঢ়া হয় |
| `QUIRE_MEETING_REGIONS` | `eu`, `uk`, `us`ৰ comma-list | Platform default provider-এ meeting ক’ত process কৰে। Unset হ’লে আগৰ দৰে region-ত pinned organisation-ৰ সৈতে তুলনা কৰি নাচায়। Organisation-ৰ নিজা account-এ নিজৰ page-ত region কয় |

এই release-ত নথকা driver value-এ web tier আৰম্ভ হওঁতে default-ৰে নীৰৱে সলনি নকৰি, setting name-সহ নাকচ হয়।

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

Page-এ `/api/files/{id}/image/{size}`-ৰে চাৰিটা fixed size-ত image বিচাৰে; ই file-ৰ একে access পৰীক্ষা কৰি image service-লৈ redirect কৰে। প্ৰতিটো organisation-এ ঘণ্টাত `QUIRE_IMAGE_SPECS_PER_HOUR` (default 2000)টা নতুন image আৰু size pair বিচাৰিব পাৰে; সেই ঘণ্টাত আগতে তৈয়াৰ কৰা size গণনা নহয়। একাধিক web container-ত limit সকলোতে বলৱৎ কৰিবলৈ `valkey` বা `postgres` `QUIRE_CACHE_DRIVER`ৰ বাবে ব্যৱহাৰ কৰক।

| Setting | Driver | টোকা |
| --- | --- | --- |
| `IMGPROXY_URL` | `imgproxy` | Browser-এ পোৱা imgproxy address, যেনে `https://images.example.org`। `images` profile-এ `QUIRE_IMAGES_PORT`ত (8082) publish কৰে |
| `IMGPROXY_KEY`, `IMGPROXY_SALT` | `imgproxy` | Hex string, imgproxy আৰম্ভ কৰিবলৈ ব্যৱহাৰ কৰা একে value। প্ৰতিটো `openssl rand -hex 32`ৰে সৃষ্টি কৰক। Quire-এ প্ৰতিটো image address sign কৰে, যাতে imgproxy-এ Quire-এ বিচৰা image-হে render কৰে |
| `QUIRE_IMAGE_SOURCE_ORIGIN` | local storage-সহ `imgproxy` | imgproxy-এ original ক’ৰ পৰা আনে। Compose-এ `http://web:3000` set কৰে। `s3` বা `azure` storage-ত imgproxy-এ bucket-ৰ পৰা আনে, এই setting ব্যৱহাৰ নহয় |
| `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_IMAGES_TOKEN`, `CLOUDFLARE_IMAGES_ACCOUNT_HASH` | `cloudflare` | Images edit permission-সহ API token আৰু Images, Developer resources-ৰ account hash। Account-ৰ flexible variant অন কৰক |
| `CLOUDFLARE_IMAGES_SIGNING_KEY` | `cloudflare` | ঐচ্ছিক। Set কৰিলে image private হয় আৰু প্ৰতিটো address sign হৈ expire হয়। নাথাকিলে `QUIRE_SECRET_KEY`ৰ পৰা derive কৰা কোনেও অনুমান কৰিব নোৱাৰা address-ত image public হয় |

Cloudflare Images-এ serve কৰা প্ৰতিটো original-ৰ নিজা copy ৰাখে। File delete হ’লে worker-এ original-ৰ আগতে সেই copy delete কৰে।

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

Background job-এ একে Postgres database-ত pg-boss ব্যৱহাৰ কৰে, সেয়ে queue service চলাব বা configure কৰিব নালাগে। Job-সমূহে ইয়াক সৃষ্টি কৰা পৰিৱৰ্তনৰ একে transaction-তে queue হয়, সেয়ে crash-এ job হেৰুৱাব বা দুবাৰ পঠিয়াব নোৱাৰে। ইয়াত `QUIRE_QUEUE_DRIVER` default `pgboss`; `vercel` আৰু `cloudflare`-এ কেৱল light notification আৰু webhook delivery platform-ৰ নিজা queue-লৈ নিয়ে। Vercel আৰু Cloudflare guide-ত সেইবোৰ আৰু তেওঁলোকৰ web tier-এ কেনেকৈ queue কৰে বৰ্ণনা আছে।

### Email <!--quire:email-->

এটা set কৰক:

- `QUIRE_EMAIL_PROVIDER_CONFIG`: HTTP provider আৰু credential নাম দিয়া JSON object, যেনে `{"provider":"postmark","token":"..."}`। Postmark, Amazon SES, Mailgun, SendGrid আৰু Resend সমৰ্থিত।
- `QUIRE_SMTP_URL`: `smtp://user:password@host:587`। কেৱল এই target-ত; serverless target-এ SMTP block কৰে।

`QUIRE_MAIL_FROM` হৈছে sender। Quire চেষ্টা কৰিবলৈ `devmail` profile আৰম্ভ কৰি `QUIRE_SMTP_URL=smtp://mailpit:1025` set কৰক আৰু `http://localhost:8025`ত mail চাওক।

### ঐচ্ছিক service <!--quire:optional-services-->

| Setting | 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` | বাহ্যিক search; নহ’লে Postgres full text |
| `QUIRE_BREACH_CHECK_PROVIDER=off`, `QUIRE_BREACH_CHECK_URL` | Password breach check। ডিফল্টভাৱে `api.pwnedpasswords.com`ৰ বিৰুদ্ধে on (কেৱল পাঁচ character-ৰ hash prefix পঠিওৱা হয়); `off`-এ বন্ধ কৰে আৰু URL-এ আপুনি host কৰা range API-লৈ আঙুলিয়ায় |

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

`OTEL_EXPORTER_OTLP_ENDPOINT`-এ প্ৰতিটো process-এ trace আৰু metric পঠিওৱা collector-ৰ নাম দিয়ে; `observability` profile-ত ই `http://otelcol:4318` আৰু backend-ৰ exporter যোগ কৰিবলৈ `docker/otel-collector.yaml` সম্পাদনা কৰক। Set কৰিলে web tier, worker, scheduler, content আৰু collab process-এ OTLP/HTTP-ৰে span (web request, tenant database transaction, worker job আৰু বাহিৰলৈ call) export কৰে আৰু একে endpoint-লৈ প্ৰতি মিনিটত metric পঠিয়ায় (`OTEL_METRICS_EXPORTER=none`-এ বন্ধ কৰে)। `OTEL_TRACES_SAMPLER_ARG`-এ ৰখা trace-ৰ অংশ set কৰে। Log `LOG_LEVEL`ত standard output-লৈ যায় আৰু Compose-এ rotate কৰে। Trace-ত ব্যক্তিগত তথ্য কেতিয়াও নাথাকে।

### আঞ্চলিক egress (EU data residency) <!--quire:regional-egress-eu-data-residency-->

`QUIRE_REGION=eu` মানে stack-এ European Union-ৰ organisation serve কৰে। EU-ত pinned organisation-ৰ হৈ কৰা প্ৰতিটো outbound request-ত worker-এ allowlist মানে (21-compliance.md section 8.1)। Allowlist-ত সেই region-ৰ বাবে configured service-এ ঘোষণা কৰা host (storage endpoint, email provider, hosted video provider, organisation-ৰ নিজা storage target, AI provider আৰু email account), সক্ৰিয় derogation থকা service-ৰ host, আৰু `QUIRE_EGRESS_ALLOW_HOSTS`ত আপোনাৰ তালিকাভুক্ত host থাকে। আন public host-লৈ request পঠিওৱাৰ আগতেই নাকচ হয়; নাকচটো organisation-ৰ audit trail-ত `privacy/egress_refused` হিচাপে লিখি Compliance, Data residency-ত দেখুওৱা হয়।

| Setting | Value | প্ৰভাৱ |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | Hostname-ৰ comma-list, অথবা সকলো subdomain-ৰ বাবে `*.example.org` | EU organisation-এ পাব পৰা অতিৰিক্ত host। Webhook, xAPI আৰু SIEM endpoint, blog feed আৰু Amazon SES host ইয়াত লাগে, কাৰণ এইবোৰ organisation-ৰ নিজা পছন্দ আৰু কোনো service-এ ঘোষণা নকৰে। Loopback, private address আৰু `web` বা `clamav`ৰ দৰে single-label name আপোনাৰ নিজা network, কেতিয়াও check নহয় |

UK আৰু US organisation-ৰ বাবে host-list বাধ্যতামূলক নহয়; service region check থাকে। Worker-ত list set কৰক; Admin page-এ allowlist দেখুৱাবলৈ web tier-ত পঢ়ে, সেয়ে প্ৰতিটো service-এ পঢ়া `docker/.env`ত ৰাখক।

Application check-এ স্পষ্ট error আৰু audit entry দিয়ে, কিন্তু ই নিশ্চয়তা নহয়: code ভুল হ’ব পাৰে। নিশ্চয়তা network-ত। Compose-এ আপোনাৰ হৈ ইয়াক বলৱৎ নকৰে। Regional stack-ৰ বাবে `worker` আৰু `web` service-সমূহক `internal: true` network-ত ৰাখক, যাৰ বাহিৰলৈ যোৱাৰ একমাত্ৰ পথ egress proxy (যেনে Squid বা সৰু tinyproxy container), যিয়ে `QUIRE_EGRESS_ALLOW_HOSTS`ৰ একে host আৰু configured service-ৰ host অনুমতি দিয়ে; সেই service-সমূহত `HTTPS_PROXY` set কৰক। Application-এ অনুমতি দিয়া হুবহু host residency page-এ দেখুৱায়, যাতে দুয়োটা list তুলনা কৰিব পাৰি।

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

| Endpoint | অৰ্থ |
| --- | --- |
| `/healthz` | Liveness: process-এ উত্তৰ দিয়ে। Compose health check-এ ইয়াক ব্যৱহাৰ কৰে |
| `/readyz` | Readiness: dependency পোৱা যায় আৰু প্ৰতিটো optional service configured নে নহয় report হৈছে। Load balancer ইয়ালৈ দিয়ক |

`docker compose -f docker/compose.yaml ps`-এ প্ৰতিটো service-ৰ health দেখুৱায়।

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

`proxy` service (Caddy, Apache-2.0, `docker/caddy/Caddyfile`) default stack-ৰ অংশ। ই port 80 আৰু 443ত উত্তৰ দি route কৰে:

| Host বা path | ক’লৈ যায় |
| --- | --- |
| `QUIRE_PROXY_CONTENT_HOST` | `content` |
| `QUIRE_PROXY_APP_HOST`, প্ৰতিটো tenant subdomain আৰু custom domain | `web` |
| সেই host-ত `/_collab/` | `collab` (websocket, `QUIRE_COLLAB_URL`) |
| সেই host-ত `/_realtime/connection/` | `centrifugo`-ৰ client websocket; server API কেতিয়াও বাহিৰলৈ দিয়া নহয় |
| সেই host-ত `/_images/` | `imgproxy` profile-সহ `images` (`IMGPROXY_URL`) |

`init-env.sh`-এ দুয়ো origin-ৰ পৰা `QUIRE_PROXY_APP_HOST`, `QUIRE_PROXY_CONTENT_HOST`, `QUIRE_PROXY_HTTPS_PORT`, `QUIRE_COLLAB_URL` আৰু `IMGPROXY_URL` derive কৰে, যাতে ইবোৰৰ মাজত অমিল নহয়। হাতেৰে origin সলনি কৰিলে একেলগে ইবোৰ সম্পাদনা কৰক।

Certificate-এ `QUIRE_PROXY_TLS` অনুসৰণ কৰে:

- `internal` (default): `localhost`, `*.localhost` আৰু `lvh.me`ৰ বাবে Caddy-ৰ নিজা certificate authority। Root-টো এবাৰ trust কৰি তাৰ পিছত browser কৰক:

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

  `quire-local-ca.crt` system বা browser trust store-ত যোগ কৰক। `curl`-এ `--cacert`ৰে লয়।
- এটা email address: প্ৰকৃত hostname-ৰ বাবে automatic ACME certificate (Let's Encrypt, তাৰ পিছত ZeroSSL)। দুয়ো origin আৰু প্ৰতিটো tenant host-ৰ DNS ইয়ালৈ আঙুলিয়াব লাগিব; internet-ৰ পৰা port 80 আৰু 443 পোৱা যাব লাগিব।

প্ৰথম visit-ত tenant host-এ on demand certificate পায়, আৰু web-এ এই install-ৰ বুলি নিশ্চিত কৰিলেহে (`/tls-allowed`, Compose network-ত সোধে)। Wildcard certificate বা DNS provider plugin নালাগে; host-লৈ নাম point কৰা অচিনাকি ব্যক্তিয়ে তাৰ বাবে certificate request কৰাব নোৱাৰে। Certificate আৰু local authority `caddy-data` volume-ত থাকে; `internal` ব্যৱহাৰ কৰিলে বাকী বস্তুৰ সৈতে ইয়াকো backup কৰক।

Web-এ `X-Forwarded-For` কেৱল proxy-ৰ পৰা বিশ্বাস কৰে: proxy-ৰ fixed address (`QUIRE_PROXY_ADDRESS`, default `172.29.64.10`) fixed subnet (`QUIRE_COMPOSE_SUBNET`)-ত থাকে আৰু `QUIRE_TRUSTED_PROXY_CIDRS`-এ সেই address কয়। Subnet-টো host-ৰ network-ৰ সৈতে সংঘাত হ’লে দুয়ো সলনি কৰি `docker compose down` চলাই তাৰ পিছত `up` কৰক।

## নিজৰ reverse proxy-ৰ পিছত <!--quire:behind-your-own-reverse-proxy-->

আগৰে পৰা থকা load balancer বা proxy ব্যৱহাৰ কৰিবলৈ `proxy` বাদ দিয়ক (`docker compose up -d --scale proxy=0`) আৰু `web` (8080), `content` (8081), `collab` (1234, websocket) আৰু `centrifugo` (8000, websocket)-ৰ আগত TLS terminate কৰক। `QUIRE_APP_ORIGIN`, `QUIRE_CONTENT_ORIGIN`, `QUIRE_COLLAB_URL` (`wss://`)-ত public address আৰু `QUIRE_TRUSTED_PROXY_CIDRS`ত proxy-ৰ address range set কৰক।

## সমস্যা সমাধান <!--quire:troubleshooting-->

- `init`-এ “QUIRE_DATABASE_ID is not a UUID” কৈ ওলাই যায়: `uuidgen`ৰে set কৰক।
- `web`-এ “did not start on compose” কৈ restart কৰে: কি মানিব নোৱাৰে আৰু তাৰ সলনি কি ব্যৱহাৰ কৰিব লাগে log-এ তালিকাভুক্ত কৰে।
- প্ৰথম start-ৰ পিছত `.env`ত role password সলনি কৰিলে কাম নকৰে: init script এবাৰহে চলে। `ALTER ROLE` ব্যৱহাৰ কৰক।
- `CLAMAV_URL` set থকাৰ সময়ত upload scan error-ত বিফল হয়: ClamAV-এ প্ৰথম start-ত signature download কৰে, কেইমিনিটমান লাগে।

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