---
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/ne/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](/ne/ops/vercel/) र [Cloudflare Workers](/ne/ops/cloudflare/) ले
वेब तह मात्र चलाउँछन्। स्तरोन्नति [upgrade.md](/ne/ops/upgrade/) मा छन्, र ब्याकअप र
पुनर्स्थापना अभ्यास [backup-restore.md](/ne/ops/backup-restore/) मा छ।

## के चाहिन्छ <!--quire:what-you-need-->

- Compose प्लगइन 2.30 वा नयाँसहित Docker Engine 27 वा नयाँ।
- पूर्वनिर्धारित स्ट्याकका लागि 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 प्रयोग गर्नुहुन्छ भने,
आफ्नै होस्ट गरिएको सदस्यता दिनुहोस् वा आफ्नै स्व-होस्टेड H5P इन्स्ट्यान्स Quire बाट छुट्टै सञ्चालन गर्नुहोस्।
त्यो प्रदायकलाई LTI 1.3 बाह्य उपकरणका रूपमा दर्ता गर्नुहोस् र यसको सामग्री पाठ्यक्रममा उपकरण गतिविधिका रूपमा थप्नुहोस्।
Quire ले LTI Assignment र 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](/ne/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-->

| सेटिङ | अर्थ |
| --- | --- |
| `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` द्वारा कन्फिगर गरिएको भौतिक डेटाबेसका लागि प्रयोग हुन्छ।
कुनै अन्य दर्ता भौतिक डेटाबेसका लागि, वेब र वर्कर वातावरणमा यसको आफ्नै
`quire_report` जडान URL सेट गर्नुहोस्, त्यसपछि चर नाम त्यो डेटाबेसको **प्रतिवेदन वातावरण चर** फिल्डमा
`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, विकासकर्ता स्रोतबाट खाता ह्यास। खाताका लागि लचिलो भेरियन्ट खोल्नुहोस् |
| `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 मा स्प्यान निर्यात गर्छन्
(वेब अनुरोध, टेनान्ट डेटाबेस कारोबार, वर्कर काम र बाह्य कल), र उही endpoint मा हरेक मिनेट मेट्रिक
(`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)। अनुमति सूची क्षेत्रका लागि कन्फिगर गरिएका सेवाले घोषणा गर्ने होस्ट हुन्
(भण्डारण endpoint, इमेल प्रदायक, होस्ट गरिएको भिडियो प्रदायक, सङ्गठनकै भण्डारण लक्ष्य, AI प्रदायक र इमेल खाता),
सक्रिय छुटअन्तर्गत कुनै सेवाका होस्ट, र तपाईंले `QUIRE_EGRESS_ALLOW_HOSTS` मा सूचीबद्ध गर्ने होस्ट।
कुनै अन्य सार्वजनिक होस्टको अनुरोध पठाउनुअघि अस्वीकार हुन्छ, अस्वीकार सङ्गठनको अडिट ट्रेलमा
`privacy/egress_refused` का रूपमा लेखिन्छ, र अनुपालन, डेटा निवास अन्तर्गत सूचीबद्ध हुन्छ।

| सेटिङ | मान | प्रभाव |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | होस्टनामको अल्पविराम सूची, वा हरेक सबडोमेनका लागि `*.example.org` | EU सङ्गठनले पुग्न सक्ने थप होस्ट। Webhook, xAPI र SIEM endpoint, ब्लग फिड र 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` (पूर्वनिर्धारित): `localhost`, `*.localhost` र `lvh.me` का लागि Caddy कै प्रमाणपत्र प्राधिकरण।
  यसको मूल एकपटक विश्वास गर्नुहोस्, त्यसपछि ब्राउज गर्नुहोस्:

  ```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 इन्टरनेटबाट पुग्न सक्नुपर्छ।

टेनान्ट होस्ट मागअनुसार जारी हुन्छन्, पहिलो भ्रमणमा, र वेबले नाम यसै स्थापनाको हो पुष्टि गर्दा मात्र
(`/tls-allowed`, Compose सञ्जालमा सोधिने)। वाइल्डकार्ड प्रमाणपत्र वा DNS प्रदायक प्लगइन चाहिँदैन,
र होस्टतिर नाम देखाउने अपरिचितले प्रमाणपत्र अनुरोध गराउन सक्दैन। प्रमाणपत्र र स्थानीय प्राधिकरण
`caddy-data` भोल्युममा बस्छन्; `internal` प्रयोग गर्दा बाँकीसँग ब्याकअप गर्नुहोस्।

वेबले प्रोक्सीबा�ट मात्र `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/ne/ops/install/index.mdx
