---
title: "Docker Compose सह Quire ची स्थापना"
description: "Docker Compose सह Quire तुमच्या स्वतःच्या मालमत्तेवर स्थापित करा."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/mr/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](/mr/ops/vercel/) आणि [Cloudflare Workers](/mr/ops/cloudflare/)
फक्त वेब थिअर चालवतात. अपग्रेड [upgrade.md](/mr/ops/upgrade/) मध्ये आणि
बॅकअप व रिस्टोअर ड्रिल [backup-restore.md](/mr/ops/backup-restore/) मध्ये.

## काय लागते <!--quire:what-you-need-->

- Docker Engine 27 किंवा त्यावरील, Compose प्लगइन 2.30 किंवा
  त्यावरील.
- डीफॉल्ट स्टॅकसाठी 4 CPU कोर आणि 8 GB मेमरी; `--profile full` सह
  8 कोर आणि 16 GB (फक्त ClamAV चे सुमारे 1.5 GB सिग्नेचरचे
  ठेवले जाते).
- वेब थिअरसाठी DNS नाव आणि अविश्वसनीय सामग्रीसाठी दुसरे. ती
  वेगवेगळे होस्ट असायला हवे: SCORM पॅकेज आणि अपलोड केलेले HTML
  कंटेंट ओरिजिनवर चालतात ज्यामुळे ती LMS चे कुकीज कधीही वाचू
  शकत नाहीत.
- स्थानिक चाचणीसाठी, `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` निरोगी होतो. पहिल्यांदा सुरू होताना त्याची init
   स्क्रिप्ट (`docker/postgres/init/90-passwords.sh`) चार
   भूमिका पासवर्ड सेट करते.
2. `migrate` प्रत्येक मायग्रेशन लागू करतो आणि कंट्रोल
   डेटाबेसमध्ये आणि प्रत्येक समर्पित टेनंट डेटाबेसमध्ये जॉब
   क्यू बूटस्ट्रॅप करतो, ती सर्व एकमेकांशी जुळतात का ते तपासतो,
   नंतर बाहेर पडतो (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-->

| सेवा | प्रोफाइल | ती काय करते |
| --- | --- | --- |
| postgres | नेहमी | डेटाबेस (pgvector सह PostgreSQL 18, `docker/postgres.Dockerfile` मधून बिल्ड), पहिल्या बूटपासून WAL आर्काइव्हसह |
| migrate, init | नेहमी | एकदाच: मायग्रेशन, नंतर पहिली वेळ |
| web | नेहमी | LMS, `QUIRE_HTTP_PORT` (8080) वर |
| content | नेहमी | अविश्वसनीय-सामग्री ओरिजिन, `QUIRE_CONTENT_PORT` (8081) वर |
| worker | नेहमी | बॅकग्राउंड जॉब: ईमेल, अहवाल, फाइल प्रक्रिया, webhooks |
| scheduler | नेहमी | पुनरावृत्ती जॉब: 64 रनटाइम वेळापत्रके नोंदणी करतो आणि वर्करला देतो; एकदा एकच नेता |
| collab | नेहमी | सहसंपादन websocket, `QUIRE_COLLAB_HTTP_PORT` (1234) वर |
| centrifugo | नेहमी | रियलटाइम फॅन-आउट, `QUIRE_REALTIME_PORT` (8000) वर |
| proxy | नेहमी | 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 रनटाइम किंवा साइडकार एम्बेड किंवा वितरित करत नाही
(ADR 0019). तुम्ही H5P वापरत असाल तर स्वतःची होस्ट केलेली
सदस्यता द्या किंवा Quire पासून स्वतंत्रपणे स्वतःची स्वतः-होस्ट
H5P इन्स्टन्स चालवा. तो प्रदाता 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-->

| सेटिंग | अर्थ |
| --- | --- |
| `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-->

| सेटिंग | अर्थ |
| --- | --- |
| `QUIRE_SECRET_KEY` | सत्रे आणि टोकन सही करते. 64 हेक्स अक्षरे |
| `QUIRE_MASTER_KEY` | SSO आणि webhook गोपनीय मूल्यांसारखी जतन केलेली प्रमाणपत्रे आवरते. 32 बाइट्स, base64. वेब थिअर आणि वर्करला हेच मूल्य लागते. फेरबदल: [key-rotation.md](/mr/ops/key-rotation/) |
| `QUIRE_MASTER_KEY_VERSION` | मास्टर कुंजीचे आवृत्ती लेबल, सेट नसेल तर `v1`. फेरबदल करताना ते वाढवा |
| `QUIRE_MASTER_KEY_RETIRED` | ज्या मास्टर कुंज्या त्यांनी सीलबंद केलेले वाचण्यासाठी अजून लागते ती, `v1=<base64>` म्हणून. फेरबदल काहीही अनिर्धारित न राहता पूर्ण झाल्यावर काढा |
| `QUIRE_COLLAB_SIGNING_KEY` | web आणि collab दोन्ही द्वारे संपादन टोकन सही करण्यासाठी साझे |
| `QUIRE_BACKUP_SIGNING_KEY` | अभ्यासक्रम बॅकअप सही करते (पर्यायी) |

`QUIRE_MASTER_KEY` ची प्रत या होस्टबाहेर कुठेतरी ठेवा. त्याशिवाय
पुनर्स्थापित केलेला डेटाबेस त्यातील प्रमाणपत्रे डिक्रिप्ट
करू शकत नाही.

### डेटाबेस <!--quire:database-->

| सेटिंग | अर्थ |
| --- | --- |
| `POSTGRES_PASSWORD` | सुपरयुझर, कंटेनर आणि बॅकअप वापरतात |
| `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` वापरा आणि नंतर
जुळणारे URL अपडेट करा.

`QUIRE_REPORT_DATABASE_URL` हे `DATABASE_URL` ने कॉन्फिगर
केलेल्या भौतिक डेटाबेससाठी वापरले जाते. इतर कोणत्याही
नोंदणीकृत भौतिक डेटाबेससाठी, web आणि worker
एन्व्हायरमेंटमध्ये त्याचे स्वतःचे `quire_report` कनेक्शन URL
सेट करा, नंतर त्या डेटाबेसच्या **Reporting environment variable**
फील्डमध्ये व्हेरिएबल नाव `env:NAME` म्हणून टाका. संदर्भला
त्याच्या ॲप कनेक्शनप्रमाणेच त्याच डेटाबेसाकडे निर्देश करायलाच
हवे, शक्य असल्यास त्याच्या वाचन रेप्लिकाकडे. प्रत्येक अहवाल
सपाटे टेनंटला त्याच्या स्वतःच्या डेटाबेसच्या अहवाल
कनेक्शनकडे जाते: अहवाल निर्माता आणि जतन केलेले अहवाल,
शेड्यूल केलेल्या डिलिव्हरी, अहवाल एक्सपोर्ट, अॅनालिटिक्स,
ऑडिट लॉग, REST ऑडिट संसाधने आणि सहाय्यकाचा ऑडिट शोध. त्यापैकी
कोणतेही कधीही दुसऱ्या डेटाबेसचा अहवाल URL उधार घेत नाही.
डेटाबेसला अहवाल कनेक्शन नसल्यास सामान्य अहवाल त्या
डेटाबेसच्या स्वतःच्या अनुप्रयोग कनेक्शनवर चालतात, तर
अॅनालिटिक्स आणि प्रत्येक ऑडिट वाचन नाकारतात आणि कारण
सांगतात, कारण अनुप्रयोग भूमिका ऑडिट ट्रेल वाचू शकत नाही.

### ड्रायव्हर <!--quire:drivers-->

| सेटिंग | या आवृत्तीत | टिप्पण्या |
| --- | --- | --- |
| `QUIRE_STORAGE_DRIVER` | `local` (डीफॉल्ट), `s3` किंवा `azure` | `local` फाइली `files` वॉल्यूममध्ये ठेवते. `s3` हे AWS S3, R2, GCS इंटरअपरेबिलिटी आणि इतर S3-अनुकूल स्टोअर कव्हर करते, पुन्हा सुरू होणाऱ्या मल्टिपार्ट अपलोडसह |
| `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` साठी वापरा,
ज्यामुळे मर्यादा त्या सर्वभर टिकते.

| सेटिंग | ड्रायव्हर | टिप्पण्या |
| --- | --- | --- |
| `IMGPROXY_URL` | `imgproxy` | ब्राउझर imgproxy पर्यंत पोहोचणारा पत्ता, उदाहरणार्थ `https://images.example.org`. `images` प्रोफाइल तो `QUIRE_IMAGES_PORT` (8082) वर प्रकाशित करते |
| `IMGPROXY_KEY`, `IMGPROXY_SALT` | `imgproxy` | हेक्स स्ट्रिंग, imgproxy ला सुरू करताना वापरली जाणारी तीच मूल्ये. प्रत्येक `openssl rand -hex 32` ने तयार करा. Quire प्रत्येक प्रतिमा पत्ता त्यांने सही करते, त्यामुळे imgproxy Quire ने मागावी न दिलेले काहीही रेंडर करत नाही |
| `QUIRE_IMAGE_SOURCE_ORIGIN` | `imgproxy` स्थानिक स्टोरेजसह | imgproxy मूळ प्रतिमा कुठून घेते. Compose `http://web:3000` सेट करते. `s3` किंवा `azure` स्टोरेजसह imgproxy बकेटमधून घेते आणि हे वापरले जात नाही |
| `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_IMAGES_TOKEN`, `CLOUDFLARE_IMAGES_ACCOUNT_HASH` | `cloudflare` | Images संपादन परवानगी असलेले API टोकन, आणि Images, Developer resources मधून खाते हॅश. खात्यासाठी फ्लेक्सिबल व्हेरिएंट्स चालू करा |
| `CLOUDFLARE_IMAGES_SIGNING_KEY` | `cloudflare` | पर्यायी. सेट असल्यास प्रतिमा खाजगी असतात आणि प्रत्येक पत्ता सही केलेला असतो आणि कालबाह्य होतो. नसेल तर प्रतिमा `QUIRE_SECRET_KEY` पासून तयार होणाऱ्या, कोणालाही अंदाजू न येणाऱ्या पत्त्यांवर सार्वजनिक असतात |

Cloudflare Images ते प्रत्येक मूळ प्रत जिथे पुरवते तिथे
स्वतःची प्रत ठेवते. फाइल हटवली गेल्यावर वर्कर मूळपूर्वी ती
प्रत हटवते.

### क्यू <!--quire:queue-->

बॅकग्राउंड जॉब त्याच Postgres डेटाबेसमध्ये pg-boss वापरतात,
त्यामुळे चालवायची क्यू सेवा नाही आणि कॉन्फिगर करायचे काहीही
नाही. जॉब त्यांना कारण ठरवणाऱ्या बदलाच्याच ट्रान्झॅक्शनमध्ये
क्यूमध्ये जातात, त्यामुळे क्रॅश एकही जॉब गमावू किंवा एक दोनदा
पाठवू शकत नाही. `QUIRE_QUEUE_DRIVER` इथे `pgboss` आहे, त्याचे
डीफॉल्ट; `vercel` आणि `cloudflare` फक्त हलक्या सूचना आणि
webhook डिलिव्हरी प्लॅटफॉर्मच्या स्वतःच्या क्यूकडे हलवतात आणि
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-->

| सेटिंग | प्रोफाइलसह |
| --- | --- |
| `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` ते बंद करते आणि URL हे तुम्ही चालवलेल्या रेंज API कडे निर्देश करते |

### निरीक्षणयोग्यता <!--quire:observability-->

`OTEL_EXPORTER_OTLP_ENDPOINT` प्रत्येक प्रक्रिया ज्या कलेक्टरकडे
ट्रेस आणि मेट्रिक पाठवते त्याचे नाव सांगते; `observability`
प्रोफाइलसह ते `http://otelcol:4318` असते आणि
`docker/otel-collector.yaml` जिथे तुम्ही तुमच्या बॅकएंडसाठी
एक्सपोर्टर जोडता ते तिथे आहे. सेट असल्यावर वेब थिअर, वर्कर,
शेड्यूलर, कंटेंट आणि collab प्रक्रिया OTLP/HTTP वर स्पॅन
एक्सपोर्ट करतात (वेब विनंत्या, टेनंट डेटाबेस ट्रान्झॅक्शन,
वर्कर जॉब आणि बाहेरील कॉल) आणि दर मिनिटाला त्याच
एंडपॉइंटवर मेट्रिक (`OTEL_METRICS_EXPORTER=none` ती बंद करते).
`OTEL_TRACES_SAMPLER_ARG` ठेवल्या जाणाऱ्या ट्रेसचा प्रमाण
सेट करते. लॉग `LOG_LEVEL` वर प्रमाणित आउटपुटकडे जातात आणि
Compose ती फिरवते. ट्रेस कधीही वैयक्तिक डेटा घेऊन जात नाहीत.

### प्रादेशिक ईग्रेस (EU डेटा निवास) <!--quire:regional-egress-eu-data-residency-->

`QUIRE_REGION=eu` स्टॅक युरोपियन युनियन संघटनांना सेवा देतो
असे सांगते. तेव्हा वर्कर EU शी बांधलेल्या संघटनेसाठी केलेली
प्रत्येक बाहेरील विनंती अनुमती यादीत ठेवतो (21-compliance.md
विभाग 8.1). अनुमती यादी म्हणजे कॉन्फिगर केलेल्या सेवा या
प्रदेशासाठी जाहीर केलेले होस्ट (स्टोरेज एंडपॉइंट, ईमेल
प्रदाता, होस्ट केलेला व्हिडिओ प्रदाता, संघटनेचे स्वतःचे
स्टोरेज लक्ष्ये, AI प्रदाते आणि ईमेल खाते), सक्रिय सवलत
अखालील कोणत्याही सेवेचे होस्ट, आणि
`QUIRE_EGRESS_ALLOW_HOSTS` मध्ये तुम्ही नेमलेले होस्ट. इतर
कोणत्याही सार्वजनिक होस्टकडील विनंती पाठवण्यापूर्वीच नाकारली
जाते, नाकारणी संघटनेच्या ऑडिट ट्रेलमध्ये `privacy/egress_refused`
म्हणून लिहिली जाते आणि ती Compliance, Data residency खाली
दिसते.

| सेटिंग | मूल्ये | परिणाम |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | होस्टनेम्सची अल्पविराम यादी, किंवा प्रत्येक सबडोमेनसाठी `*.example.org` | EU संघटनेला पोहोचता येणारे अतिरिक्त होस्ट. Webhook, xAPI आणि SIEM endpoints, ब्लॉग फीड आणि Amazon SES होस्ट इथे येतात, कारण ते संघटनेची स्वतःची निवड असतात आणि कोणतीही सेवा ते जाहीर करत नाही. लूपबॅक, खाजगी पत्ते आणि `web` किंवा `clamav` सारखी एक-अक्षरी नावे हे तुमचे स्वतःचे नेटवर्क आहेत आणि ती कधीही तपासली जात नाहीत |

UK आणि US संघटना होस्ट यादीसाठी बांधलेल्या नसतात; त्या
सेवा प्रदेश तपासण्या पाळतात. यादी वर्करवर सेट करा; अडमिन
पृष्ठ अनुमती यादी दाखवण्यासाठी वेब थिअरवर ती वाचते, त्यामुळे
ती प्रत्येक सेवा वाचणाऱ्या `docker/.env` मध्ये टाका.

अनुप्रयोग तपासणी स्पष्ट त्रुटी आणि ऑडिट एन्ट्री देते आणि
ती खात्री नाही: कोड चूक असू शकतो. खात्री ही नेटवर्ची आहे.
Compose ते तुमच्यासाठी लागू करत नाही. प्रादेशिक स्टॅकसाठी,
`worker` आणि `web` सेवा अशा `internal: true` नेटवर्कवर ठेवा
ज्याचा बाहेर जाण्याचा एकमेव मार्ग हा ईग्रेस प्रॉक्सी आहे
(उदाहरणार्थ Squid किंवा tinyproxy कंटेनर) जो
`QUIRE_EGRESS_ALLOW_HOSTS` मधील त्याच होस्ट आणि तुमच्या
कॉन्फिगर केलेल्या सेवांचे होस्ट परवानगी देतो आणि त्या
सेवांसाठी `HTTPS_PROXY` सेट करा. निवास पृष्ठ अनुप्रयोग
परवानगी देणारे अचूक होस्ट दाखवते, त्यामुळे दोन्ही यादींची
तुलना करता येते.

## आरोग्य <!--quire:health-->

| Endpoint | अर्थ |
| --- | --- |
| `/healthz` | जिवंतता: प्रक्रिया उत्तर देते. Compose आरोग्य तपासण्या हे वापरतात |
| `/readyz` | तयारपणा: अवलंबित्या पोहोचण्यायोग्य, आणि प्रत्येक पर्यायी सेवा कॉन्फिगर केलेली आहे का ते नोंदवलेले. तुमचा लोड बॅलन्सर इथे निर्देश करा |

`docker compose -f docker/compose.yaml ps` प्रत्येक सेवेचे
आरोग्य दाखवते.

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

`proxy` सेवा (Caddy, Apache-2.0, `docker/caddy/Caddyfile`) ही
डीफॉल्ट स्टॅकचा भाग आहे. ती पोर्ट 80 आणि 443 वर उत्तर देते
आणि रूट करते:

| होस्ट किंवा पाथ | कुठे जाते |
| --- | --- |
| `QUIRE_PROXY_CONTENT_HOST` | `content` |
| `QUIRE_PROXY_APP_HOST`, प्रत्येक टेनंट सबडोमेन आणि कस्टम डोमेन | `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). दोन्ही ओरिजिन आणि प्रत्येक
  टेनंट होस्टचे DNS इथेच निर्देश करायलाच हवे आणि पोर्ट 80 आणि
  443 इंटरनेटमधून पोहोचण्यायोग्य असायले हवे.

टेनंट होस्ट मागण्यानुसार, पहिल्या भेटीत जारी होतात, आणि
फक्त तेव्हाच जेव्हा web हे नाव या स्थापनेचे आहे ते खात्री
करते (`/tls-allowed`, Compose नेटवर्कवर विचारले जाते). कोणत्याही
वाइल्डकार्ड प्रमाणपत्र किंवा 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`) आणि
`web` (8080), `content` (8081), `collab` (1234, websocket) आणि
`centrifugo` (8000, websocket) समोर TLS समाप्त करा. सार्वजनिक
पत्ते `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` मध्ये भूमिका पासवर्ड बदलल्याने
  काहीही होत नाही: init स्क्रिप्ट एकदाच चालते. `ALTER ROLE`
  वापरा.
- `CLAMAV_URL` सेट असताना अपलोड स्कॅन त्रुटीसह अपयशस्वी होतात:
  ClamAV पहिल्या सुरुवातीला त्याची सिग्नेचर डाउनलोड करतो, ज्यास
  काही मिनिटे लागतात.

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