---
title: "Εγκατάσταση του Quire με Docker Compose"
description: "Εγκαταστήστε το Quire στη δική σας υποδομή με Docker Compose."
image: "https://docs.quirelms.com/og.png"
---

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

# Εγκατάσταση του Quire με Docker Compose

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

Αυτό είναι το πλήρες προϊόν σε έναν host: το LMS, οι εργασίες παρασκηνίου, οι υπηρεσίες realtime και συνεργατικής επεξεργασίας και όλες οι προαιρετικές υπηρεσίες πίσω από ένα προφίλ. Το σχέδιο βρίσκεται στην ενότητα 2 του `docs/architecture/23-ops.md`.

Άλλοι προορισμοί: τα [Vercel](/el/ops/vercel/) και [Cloudflare Workers](/el/ops/cloudflare/) εκτελούν μόνο τον web tier. Οι αναβαθμίσεις περιγράφονται στο [upgrade.md](/el/ops/upgrade/), ενώ τα αντίγραφα ασφαλείας και η άσκηση επαναφοράς στο [backup-restore.md](/el/ops/backup-restore/).

## Απαιτήσεις <!--quire:what-you-need-->

- Docker Engine 27 ή νεότερο με Compose plugin 2.30 ή νεότερο.
- 4 πυρήνες CPU και 8 GB μνήμης για τον προεπιλεγμένο stack· 8 πυρήνες και 16 GB με `--profile full` (μόνο οι υπογραφές του ClamAV καταλαμβάνουν περίπου 1,5 GB).
- Ένα όνομα DNS για τον web tier και ένα δεύτερο για μη έμπιστο περιεχόμενο. Πρέπει να είναι διαφορετικοί hosts: τα πακέτα SCORM και το μεταφορτωμένο HTML εκτελούνται στο content origin, ώστε να μην μπορούν ποτέ να διαβάσουν τα cookies του LMS.
- Για τοπική δοκιμή, τα `lvh.me` και `*.localhost` επιλύονται στη διεύθυνση 127.0.0.1, όπως ορίζει το `docker/.env.example`. Η υπηρεσία `proxy` του stack εξυπηρετεί και τα δύο μέσω HTTPS με τοπική αρχή πιστοποίησης, επομένως δεν χρειάζεται άλλη εγκατάσταση (δείτε «TLS»).
- Οι θύρες 80 και 443 πρέπει να είναι ελεύθερες στον host (οι `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 προσαρτά στους workers ως μυστικό. Χρειάζεται μόνο τα `sh`, `awk` και `openssl` και αρνείται να αντικαταστήσει υπάρχον `docker/.env`. Αντιγράψτε και τα δύο αρχεία εκτός host: χωρίς το `QUIRE_MASTER_KEY` μια επαναφερμένη βάση δεδομένων δεν μπορεί να αποκρυπτογραφήσει τα αποθηκευμένα διαπιστευτήριά της. Για να συμπληρώσετε το αρχείο χειροκίνητα, εκτελέστε `cp docker/.env.example docker/.env`· το αρχείο περιγράφει πώς δημιουργείται κάθε μυστικό.

Και τα δύο origin πρέπει να είναι `https`: η υπηρεσία περιεχομένου απορρίπτει απλό http στην παραγωγή, και τα origin δεν πρέπει να μοιράζονται καταχωρίσιμο τομέα. Η υπηρεσία `proxy` τερματίζει το TLS και για τα δύο (δείτε «TLS»)· το `init-env.sh` απορρίπτει origin `http://`.

Ο stack ξεκινά με σταθερή σειρά και κάθε βήμα περιμένει να ολοκληρωθεί το προηγούμενο:

1. Το `postgres` γίνεται υγιές. Στην πρώτη εκκίνηση το σενάριο αρχικοποίησης (`docker/postgres/init/90-passwords.sh`) ορίζει τους τέσσερις κωδικούς ρόλων.
2. Το `migrate` εφαρμόζει κάθε μετανάστευση και αρχικοποιεί την ουρά εργασιών στην ελεγκτική βάση και σε κάθε αποκλειστική βάση μισθωτή, ελέγχει ότι συμφωνούν όλες και τερματίζεται (docs/ops/upgrade.md). Οι μεταναστεύσεις εκτελούνται σε κάθε εκκίνηση και είναι ιδιοδύναμες, επομένως μια αναβάθμιση σημαίνει νέο image και επανεκκίνηση.
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` εμφανίζει την ακριβή διεύθυνση σύνδεσης) και συνδεθείτε. Σε τοπική εγκατάσταση, εμπιστευτείτε πρώτα την αρχή πιστοποίησης του proxy (δείτε «TLS»). Αλλάξτε τον παραγόμενο κωδικό πρόσβασης στο `/account/security`.

Μια διεργασία που ξεκινά χωρίς απαιτούμενο μυστικό αρνείται να εκκινηθεί και ονομάζει τη ρύθμιση που λείπει στο αρχείο καταγραφής της. Καμία υπηρεσία δεν ξεκινά με μερική διαμόρφωση.

## Υπηρεσίες και προφίλ <!--quire:services-and-profiles-->

| Υπηρεσία | Προφίλ | Λειτουργία |
| --- | --- | --- |
| postgres | always | Η βάση δεδομένων (PostgreSQL 18 με pgvector, δημιουργημένη από το `docker/postgres.Dockerfile`), με αρχειοθέτηση WAL από την πρώτη εκκίνηση |
| migrate, init | always | Μία εκτέλεση: μεταναστεύσεις και έπειτα πρώτη εκκίνηση |
| web | always | Το LMS στη θύρα `QUIRE_HTTP_PORT` (8080) |
| content | always | Το origin μη έμπιστου περιεχομένου στη θύρα `QUIRE_CONTENT_PORT` (8081) |
| worker | always | Εργασίες παρασκηνίου: email, αναφορές, επεξεργασία αρχείων, webhooks |
| scheduler | always | Επαναλαμβανόμενες εργασίες: καταχωρίζει τα 64 προγράμματα χρόνου εκτέλεσης και τα αναθέτει στον worker· μόνο ένας ηγέτης κάθε φορά |
| collab | always | WebSocket συνεργατικής επεξεργασίας στη θύρα `QUIRE_COLLAB_HTTP_PORT` (1234) |
| centrifugo | always | Διανομή realtime στη θύρα `QUIRE_REALTIME_PORT` (8000) |
| proxy | always | Caddy, η είσοδος TLS στις θύρες 80 και 443 (δείτε «TLS») |
| valkey | `cache` | Cache και όρια ρυθμού |
| clamav | `scan` | Σάρωση κακόβουλου λογισμικού σε μεταφορτώσεις |
| gotenberg | `preview` | Προεπισκόπηση Office σε PDF και απόδοση πιστοποιητικών |
| imgproxy | `images` | Αλλαγή μεγέθους και μετατροπή εικόνων |
| transcoder | `video` | Image worker με ffmpeg αποκλειστικά LGPL για παραλλαγές βίντεο |
| seaweedfs | `storage` | Αποθήκευση αντικειμένων συμβατή με S3 σε αυτόν τον host |
| otelcol | `observability` | Συλλέκτης OpenTelemetry |
| mailpit | `devmail` | Συλλαμβάνει όλη την εξερχόμενη αλληλογραφία για δοκιμή του Quire |
| backup | `backup` | Εφάπαξ βασικό αντίγραφο· δείτε backup-restore.md |
| backup-scheduler, backup-offsite | `backup` | Βασικό αντίγραφο κάθε `QUIRE_BACKUP_INTERVAL_HOURS` και κρυπτογραφημένα αντίγραφα εκτός host με εβδομαδιαία άσκηση επαλήθευσης |
| h5p | `h5p` | Image εργαλείου H5P LTI 1.3 που παρέχετε στο `QUIRE_H5P_IMAGE`, στη θύρα `QUIRE_H5P_PORT` (8090)· δείτε «Σύνδεση παρόχου H5P» |

Το `--profile full` ξεκινά κάθε προαιρετική υπηρεσία εκτός από τις `backup` και `h5p`. Ξεκινήστε ένα προφίλ με `docker compose -f docker/compose.yaml --profile scan up -d`. Το Quire εξακολουθεί να λειτουργεί και χωρίς προαιρετική υπηρεσία, ενημερώνοντας για ό,τι λείπει: χωρίς σαρωτή οι μεταφορτώσεις αποθηκεύονται χωρίς σάρωση και ενημερώνεται ο διαχειριστής· χωρίς Gotenberg τα αρχεία προσφέρουν λήψη αντί για προεπισκόπηση· χωρίς transcoder το βίντεο αναπαράγεται ως το αρχικό αρχείο.

Κάθε image τρίτου μέρους και οι σχετικές υποχρεώσεις αδειοδότησης παρατίθενται στο `docker/third-party-containers.yaml`.

### Σύνδεση παρόχου H5P <!--quire:connecting-an-h5p-provider-->

Το Quire δεν ενσωματώνει ούτε παρέχει περιβάλλον εκτέλεσης H5P ή sidecar (ADR 0019). Αν χρησιμοποιείτε H5P, εξασφαλίστε δική σας φιλοξενούμενη συνδρομή ή λειτουργήστε ξεχωριστή αυτοδιαχειριζόμενη εγκατάσταση H5P. Καταχωρίστε τον πάροχο ως εξωτερικό εργαλείο LTI 1.3 και προσθέστε το περιεχόμενό του στα μαθήματα ως δραστηριότητες εργαλείου. Το Quire ανταλλάσσει βαθμούς και πρόοδο δραστηριοτήτων ή βαθμολόγησης μέσω των LTI Assignment and Grade Services (AGS). Αν ο πάροχος στέλνει επίσης δηλώσεις xAPI, διαμορφώστε το ξεχωριστά για τον χώρο αποθήκευσης δηλώσεων xAPI του Quire· η ανταλλαγή βαθμών και προόδου AGS δεν στέλνει δηλώσεις xAPI. Οι εισαγωγές Moodle αναφέρουν ότι οι δραστηριότητες H5P χρειάζονται σύνδεση εργαλείου LTI. Ο πάροχος παραμένει υπεύθυνος για το περιβάλλον εκτέλεσης, τη συγγραφή περιεχομένου, τη βιβλιοθήκη περιεχομένου και το ιστορικό προσπαθειών του H5P.

Για να εκτελέσετε τη δική σας αυτοδιαχειριζόμενη εγκατάσταση σε αυτόν τον host, ορίστε το `QUIRE_H5P_IMAGE` στο image της και ξεκινήστε το προφίλ `h5p`. Το Compose τη δημοσιεύει στη θύρα `QUIRE_H5P_PORT` (8090) και διατηρεί τα δεδομένα της στο volume `h5p-data`· το image και οι υποχρεώσεις που το συνοδεύουν παραμένουν δικά σας.

## Ρυθμίσεις <!--quire:settings-->

Κάθε διεργασία διαβάζει το `docker/.env`. Το πρότυπο `docker/.env.example` παραθέτει κάθε ρύθμιση και την προεπιλεγμένη τιμή της. Οι ομάδες:

### Διευθύνσεις <!--quire:addresses-->

| Ρύθμιση | Σημασία |
| --- | --- |
| `QUIRE_APP_ORIGIN` | Δημόσια διεύθυνση του LMS, όπως `https://learn.example.com` |
| `QUIRE_CONTENT_ORIGIN` | Origin περιεχομένου, σε διαφορετικό host |
| `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` | Proxy των οποίων το `X-Forwarded-For` θεωρείται αξιόπιστο |

### Μυστικά <!--quire:secrets-->

| Ρύθμιση | Σημασία |
| --- | --- |
| `QUIRE_SECRET_KEY` | Υπογράφει συνεδρίες και token. 64 δεκαεξαδικοί χαρακτήρες |
| `QUIRE_MASTER_KEY` | Περιτυλίγει αποθηκευμένα διαπιστευτήρια, όπως μυστικά SSO και webhook. 32 byte, base64. Ο web tier και ο worker χρειάζονται την ίδια τιμή. Περιστροφή: [key-rotation.md](/el/ops/key-rotation/) |
| `QUIRE_MASTER_KEY_VERSION` | Ετικέτα έκδοσης του κύριου κλειδιού, `v1` αν δεν έχει οριστεί. Αυξήστε την στην περιστροφή |
| `QUIRE_MASTER_KEY_RETIRED` | Παλαιότερα κύρια κλειδιά που χρειάζονται ακόμη για την ανάγνωση όσων περιτύλιξαν, όπως `v1=<base64>`. Αφαιρέστε τα μόλις ολοκληρωθεί περιστροφή χωρίς ανεπίλυτες τιμές |
| `QUIRE_COLLAB_SIGNING_KEY` | Κοινόχρηστο από web και collab για την υπογραφή token επεξεργασίας |
| `QUIRE_BACKUP_SIGNING_KEY` | Υπογράφει αντίγραφα μαθημάτων (προαιρετικό) |

Κρατήστε αντίγραφο του `QUIRE_MASTER_KEY` σε διαφορετικό σημείο από αυτόν τον host. Μια βάση δεδομένων που επαναφέρθηκε χωρίς αυτό δεν μπορεί να αποκρυπτογραφήσει τα διαπιστευτήρια που περιέχει.

### Βάση δεδομένων <!--quire:database-->

| Ρύθμιση | Σημασία |
| --- | --- |
| `POSTGRES_PASSWORD` | Ο superuser, για το κοντέινερ και τα αντίγραφα ασφαλείας |
| `QUIRE_DB_APP_PASSWORD`, `QUIRE_DB_MIGRATOR_PASSWORD`, `QUIRE_DB_REPORT_PASSWORD`, `QUIRE_DB_AUDIT_PASSWORD` | Κωδικοί ρόλων, ορίζονται στην πρώτη εκκίνηση |
| `DATABASE_URL` | Ρόλος εφαρμογής. Η row-level security ισχύει για κάθε ερώτημα που εκτελεί |
| `DATABASE_MIGRATOR_URL`, `QUIRE_MIGRATION_URL` | Ρόλος μετανάστευσης για `migrate` και `init` |
| `QUIRE_SUPERUSER_URL` | Χρησιμοποιείται μόνο στην πρώτη εκκίνηση |
| `QUIRE_REPORT_DATABASE_URL` | Ρόλος αναφορών μόνο για ανάγνωση, για αναφορές και τον δημιουργό αναφορών |
| `QUIRE_AUDIT_DATABASE_URL` | Ρόλος ελέγχου, για την κονσόλα ελέγχου και την εξαγωγή SIEM |
| `QUIRE_DATABASE_ID` | Οποιοδήποτε UUID, σταθερό για όλη τη διάρκεια της εγκατάστασης |

Οι κωδικοί ρόλων εφαρμόζονται μόνο όταν δημιουργείται για πρώτη φορά το volume της βάσης δεδομένων. Για να αλλάξετε έναν αργότερα, χρησιμοποιήστε `ALTER ROLE` και έπειτα ενημερώστε την αντίστοιχη URL.

Το `QUIRE_REPORT_DATABASE_URL` χρησιμοποιείται για τη φυσική βάση που έχει ρυθμιστεί μέσω του `DATABASE_URL`. Για κάθε άλλη καταχωρισμένη φυσική βάση, ορίστε τη δική της URL σύνδεσης `quire_report` στα περιβάλλοντα web και worker και έπειτα καταχωρίστε το όνομα μεταβλητής στο πεδίο **Μεταβλητή περιβάλλοντος αναφορών** της βάσης ως `env:NAME`. Η αναφορά πρέπει να οδηγεί στην ίδια βάση με τη σύνδεση της εφαρμογής, ιδανικά στη δευτερεύουσα βάση μόνο για ανάγνωση. Κάθε επιφάνεια αναφορών χρησιμοποιεί τη σύνδεση αναφορών της βάσης του συγκεκριμένου μισθωτή: τον δημιουργό και τις αποθηκευμένες αναφορές, προγραμματισμένες παραδόσεις, εξαγωγές αναφορών, αναλυτικά στοιχεία, το αρχείο ελέγχου, τους πόρους ελέγχου REST και την αναζήτηση ελέγχου του βοηθού. Καμία δεν δανείζεται ποτέ URL αναφορών άλλης βάσης. Αν μια βάση δεν έχει σύνδεση αναφορών, οι συνήθεις αναφορές εκτελούνται μέσω της δικής της σύνδεσης εφαρμογής, ενώ τα αναλυτικά στοιχεία και κάθε ανάγνωση ελέγχου απορρίπτονται και αναφέρουν τον λόγο, επειδή ο ρόλος εφαρμογής δεν μπορεί να διαβάσει το αρχείο ελέγχου.

### Προγράμματα οδήγησης <!--quire:drivers-->

| Ρύθμιση | Αυτή η έκδοση | Σημειώσεις |
| --- | --- | --- |
| `QUIRE_STORAGE_DRIVER` | `local` (προεπιλογή), `s3` ή `azure` | Το `local` διατηρεί αρχεία στο volume `files`. Το `s3` καλύπτει AWS S3, R2, διαλειτουργικότητα GCS και άλλα συμβατά αποθετήρια S3, με επαναλήψιμες μεταφορτώσεις πολλών τμημάτων |
| `QUIRE_REALTIME_DRIVER` | `inprocess` (προεπιλογή), `sse`, `centrifugo` ή `durable_objects` | Το `inprocess` είναι κατάλληλο για έναν web container· όταν υπάρχουν πολλοί, χρησιμοποιήστε `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` χωρισμένα με κόμμα | Περιοχές όπου ο προεπιλεγμένος πάροχος πλατφόρμας επεξεργάζεται συναντήσεις. Αν δεν οριστεί, δεν ελέγχεται όπως και πριν έναντι οργανισμού που έχει δεσμευτεί σε περιοχή. Ο λογαριασμός του οργανισμού αναφέρει τις περιοχές του στη δική του σελίδα |

Μια τιμή προγράμματος οδήγησης που δεν περιλαμβάνεται σε αυτή την έκδοση απορρίπτεται κατά την εκκίνηση του web tier με αναφορά της ρύθμισης, αντί να αντικατασταθεί σιωπηλά από την προεπιλογή.

### Εικόνες <!--quire:images-->

Οι σελίδες ζητούν εικόνες σε τέσσερα προκαθορισμένα μεγέθη μέσω του `/api/files/{id}/image/{size}`, που ελέγχει τα ίδια δικαιώματα πρόσβασης με το ίδιο το αρχείο και έπειτα ανακατευθύνει στην υπηρεσία εικόνων. Κάθε οργανισμός μπορεί να ζητήσει `QUIRE_IMAGE_SPECS_PER_HOUR` (προεπιλογή 2000) νέους συνδυασμούς εικόνας και μεγέθους ανά ώρα· μεγέθη που έχουν ήδη δημιουργηθεί αυτή την ώρα δεν υπολογίζονται. Χρησιμοποιήστε `valkey` ή `postgres` για το `QUIRE_CACHE_DRIVER` όταν υπάρχουν πολλοί web container, ώστε το όριο να ισχύει μεταξύ τους.

| Ρύθμιση | Πρόγραμμα οδήγησης | Σημειώσεις |
| --- | --- | --- |
| `IMGPROXY_URL` | `imgproxy` | Διεύθυνση στην οποία φτάνουν οι browser για το 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` | Token API με δικαίωμα επεξεργασίας Images και το hash λογαριασμού από την ενότητα Images, Developer resources. Ενεργοποιήστε flexible variants για τον λογαριασμό |
| `CLOUDFLARE_IMAGES_SIGNING_KEY` | `cloudflare` | Προαιρετικό. Όταν οριστεί, οι εικόνες είναι ιδιωτικές και κάθε διεύθυνση υπογράφεται και λήγει. Χωρίς αυτό, οι εικόνες είναι δημόσιες σε διευθύνσεις που προκύπτουν από το `QUIRE_SECRET_KEY` και δεν μπορεί κανείς να μαντέψει |

Το Cloudflare Images διατηρεί δικό του αντίγραφο κάθε πρωτοτύπου που εξυπηρετεί. Όταν διαγράφεται ένα αρχείο, ο worker διαγράφει πρώτα εκείνο το αντίγραφο.

### Ουρά <!--quire:queue-->

Οι εργασίες παρασκηνίου χρησιμοποιούν pg-boss στην ίδια βάση Postgres, επομένως δεν απαιτείται υπηρεσία ουράς ούτε διαμόρφωση. Οι εργασίες μπαίνουν στην ουρά στην ίδια συναλλαγή με την αλλαγή που τις προκάλεσε, έτσι μια κατάρρευση δεν μπορεί να χάσει ή να στείλει δύο φορές μια εργασία. Εδώ η προεπιλεγμένη τιμή του `QUIRE_QUEUE_DRIVER` είναι `pgboss`· οι τιμές `vercel` και `cloudflare` μεταφέρουν μόνο απλές παραδόσεις ειδοποιήσεων και webhook στην ουρά της αντίστοιχης πλατφόρμας, όπως περιγράφουν οι οδηγοί Vercel και Cloudflare, μαζί με τον τρόπο που οι web tier τους βάζουν εργασίες στην ουρά.

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

Ορίστε μία από τις παρακάτω ρυθμίσεις:

- `QUIRE_EMAIL_PROVIDER_CONFIG`: αντικείμενο JSON που κατονομάζει πάροχο HTTP και διαπιστευτήρια, όπως `{"provider":"postmark","token":"..."}`. Υποστηρίζονται Postmark, Amazon SES, Mailgun, SendGrid και Resend.
- `QUIRE_SMTP_URL`: `smtp://user:password@host:587`. Μόνο για αυτόν τον προορισμό· οι serverless προορισμοί αποκλείουν το 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` (στέλνεται μόνο πρόθεμα hash πέντε χαρακτήρων)· το `off` τον απενεργοποιεί και η URL δείχνει σε API εύρους που φιλοξενείτε εσείς |

### Παρατηρησιμότητα <!--quire:observability-->

Το `OTEL_EXPORTER_OTLP_ENDPOINT` ορίζει τον collector στον οποίο στέλνει κάθε διεργασία traces και μετρήσεις· με το προφίλ `observability` είναι `http://otelcol:4318`, ενώ στο `docker/otel-collector.yaml` προσθέτετε τον exporter για το backend σας. Όταν οριστεί, οι διεργασίες web tier, worker, scheduler, content και collab εξάγουν spans μέσω OTLP/HTTP (αιτήματα web, συναλλαγές βάσεων μισθωτών, εργασίες worker και εξερχόμενες κλήσεις) και στέλνουν μετρήσεις στο ίδιο τελικό σημείο κάθε λεπτό (`OTEL_METRICS_EXPORTER=none` τις απενεργοποιεί). Το `OTEL_TRACES_SAMPLER_ARG` ορίζει το ποσοστό των traces που διατηρούνται. Τα αρχεία καταγραφής στέλνονται στην τυπική έξοδο στο `LOG_LEVEL` και το Compose τα περιστρέφει. Τα traces δεν περιέχουν προσωπικά δεδομένα.

### Περιφερειακή εξερχόμενη κίνηση (διαμονή δεδομένων ΕΕ) <!--quire:regional-egress-eu-data-residency-->

Το `QUIRE_REGION=eu` δηλώνει ότι ο stack εξυπηρετεί οργανισμούς της Ευρωπαϊκής Ένωσης. Ο worker περιορίζει τότε κάθε εξερχόμενο αίτημα για οργανισμό δεσμευμένο στην ΕΕ σε λίστα επιτρεπόμενων host (21-compliance.md, ενότητα 8.1). Η λίστα περιλαμβάνει τους host που δηλώνουν οι διαμορφωμένες υπηρεσίες για την περιοχή (τελικό σημείο αποθήκευσης, πάροχος email, φιλοξενούμενος πάροχος βίντεο, στόχοι αποθήκευσης του οργανισμού, πάροχοι AI και λογαριασμός email), τους host υπηρεσιών που καλύπτονται από ενεργή παρέκκλιση και όσους αναφέρετε στο `QUIRE_EGRESS_ALLOW_HOSTS`. Αίτημα προς οποιονδήποτε άλλο δημόσιο host απορρίπτεται πριν αποσταλεί, η απόρριψη καταγράφεται στο αρχείο ελέγχου του οργανισμού ως `privacy/egress_refused` και εμφανίζεται στην ενότητα Συμμόρφωση, Διαμονή δεδομένων.

| Ρύθμιση | Τιμές | Αποτέλεσμα |
| --- | --- | --- |
| `QUIRE_EGRESS_ALLOW_HOSTS` | Λίστα hostnames χωρισμένων με κόμμα ή `*.example.org` για κάθε υποτομέα | Πρόσθετοι host στους οποίους μπορεί να φτάσει ένας οργανισμός ΕΕ. Εδώ ανήκουν τελικά σημεία webhook, xAPI και SIEM, ροές ιστολογίων και host Amazon SES, επειδή αποτελούν επιλογές του οργανισμού και καμία υπηρεσία δεν τους δηλώνει. Loopback, ιδιωτικές διευθύνσεις και ονόματα μίας ετικέτας όπως `web` ή `clamav` ανήκουν στο δικό σας δίκτυο και δεν ελέγχονται ποτέ |

Οι οργανισμοί Ηνωμένου Βασιλείου και ΗΠΑ δεν δεσμεύονται από λίστα host· εξακολουθούν να ισχύουν οι έλεγχοι περιοχής υπηρεσιών. Ορίστε τη λίστα στον worker· η σελίδα διαχείρισης τη διαβάζει στον web tier για να εμφανίσει τη λίστα επιτρεπόμενων, γι' αυτό βάλτε την στο `docker/.env`, που διαβάζεται από κάθε υπηρεσία.

Ο έλεγχος της εφαρμογής δίνει σαφές σφάλμα και εγγραφή ελέγχου, αλλά δεν αποτελεί εγγύηση: ο κώδικας μπορεί να είναι λανθασμένος. Εγγύηση είναι το δίκτυο. Το Compose δεν την επιβάλλει για εσάς. Για περιφερειακό stack, τοποθετήστε τις υπηρεσίες `worker` και `web` σε δίκτυο `internal: true` με μοναδική διαδρομή εξόδου μέσω proxy εξερχόμενης κίνησης (για παράδειγμα κοντέινερ Squid ή tinyproxy), που επιτρέπει τους ίδιους host με το `QUIRE_EGRESS_ALLOW_HOSTS` συν τους host των διαμορφωμένων υπηρεσιών, και ορίστε το `HTTPS_PROXY` για αυτές τις υπηρεσίες. Η σελίδα διαμονής δεδομένων παραθέτει τους ακριβείς host που επιτρέπει η εφαρμογή, ώστε να μπορείτε να συγκρίνετε τις δύο λίστες.

## Κατάσταση υγείας <!--quire:health-->

| Τελικό σημείο | Σημασία |
| --- | --- |
| `/healthz` | Ζωτικότητα: η διεργασία αποκρίνεται. Το Compose χρησιμοποιεί αυτόν τον έλεγχο υγείας |
| `/readyz` | Ετοιμότητα: οι εξαρτήσεις είναι προσβάσιμες και κάθε προαιρετική υπηρεσία αναφέρεται ως ρυθμισμένη ή μη. Στρέψτε εδώ τον load balancer σας |

Το `docker compose -f docker/compose.yaml ps` εμφανίζει την κατάσταση υγείας κάθε υπηρεσίας.

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

Η υπηρεσία `proxy` (Caddy, Apache-2.0, `docker/caddy/Caddyfile`) ανήκει στον προεπιλεγμένο stack. Απαντά στις θύρες 80 και 443 και δρομολογεί:

| Host ή διαδρομή | Προορισμός |
| --- | --- |
| `QUIRE_PROXY_CONTENT_HOST` | `content` |
| `QUIRE_PROXY_APP_HOST`, κάθε υποτομέας μισθωτή και προσαρμοσμένος τομέας | `web` |
| `/_collab/` σε αυτούς τους host | `collab` (WebSocket, `QUIRE_COLLAB_URL`) |
| `/_realtime/connection/` σε αυτούς τους host | WebSocket πελάτη του `centrifugo`· το API διακομιστή του δεν εκτίθεται ποτέ |
| `/_images/` σε αυτούς τους host | `imgproxy`, με το προφίλ `images` (`IMGPROXY_URL`) |

Το `init-env.sh` παράγει τις τιμές `QUIRE_PROXY_APP_HOST`, `QUIRE_PROXY_CONTENT_HOST`, `QUIRE_PROXY_HTTPS_PORT`, `QUIRE_COLLAB_URL` και `IMGPROXY_URL` από τα δύο origin, ώστε να μη διαφέρουν. Αλλάξτε τις μαζί αν τροποποιήσετε χειροκίνητα ένα origin.

Τα πιστοποιητικά καθορίζονται από το `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` στον χώρο αξιόπιστων πιστοποιητικών του συστήματος ή του browser. Το `curl` το δέχεται με το `--cacert`.
- Μια διεύθυνση email: αυτόματα πιστοποιητικά ACME (Let's Encrypt και μετά ZeroSSL) για πραγματικά hostnames. Το DNS και των δύο origin και κάθε host μισθωτή πρέπει να δείχνει εδώ, ενώ οι θύρες 80 και 443 πρέπει να είναι προσβάσιμες από το διαδίκτυο.

Τα πιστοποιητικά για host μισθωτών εκδίδονται κατά απαίτηση, στην πρώτη επίσκεψη, και μόνο όταν το web επιβεβαιώσει ότι το όνομα ανήκει σε αυτή την εγκατάσταση (`/tls-allowed`, με αίτημα στο δίκτυο Compose). Δεν χρειάζεται wildcard πιστοποιητικό ή πρόσθετο DNS παρόχου, και ένας τρίτος που κατευθύνει ένα όνομα στον host δεν μπορεί να προκαλέσει αίτημα έκδοσης πιστοποιητικού. Τα πιστοποιητικά και η τοπική αρχή βρίσκονται στο volume `caddy-data`· δημιουργήστε αντίγραφό του μαζί με τα υπόλοιπα αν χρησιμοποιείτε το `internal`.

Το web εμπιστεύεται το `X-Forwarded-For` μόνο από τον proxy: ο proxy έχει σταθερή διεύθυνση `QUIRE_PROXY_ADDRESS` (προεπιλογή `172.29.64.10`) σε σταθερό υποδίκτυο `QUIRE_COMPOSE_SUBNET`, και το `QUIRE_TRUSTED_PROXY_CIDRS` ορίζει αυτή τη διεύθυνση. Αν το υποδίκτυο συγκρούεται με δίκτυο του host, αλλάξτε και τα δύο και εκτελέστε `docker compose down` πριν από το `up`.

## Πίσω από δικό σας reverse proxy <!--quire:behind-your-own-reverse-proxy-->

Για να χρησιμοποιήσετε αντ' αυτού έναν load balancer ή 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://`), και το εύρος διευθύνσεων του proxy σας στο `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/el/ops/install/index.mdx
