זהו המוצר המלא במארח אחד: מערכת הלמידה, עבודות הרקע, שירותי realtime ועריכה
משותפת וכל שירות אופציונלי נוסף שמוגדר בפרופיל. התכנון נמצא בסעיף 2 של
docs/architecture/23-ops.md.
יעדים אחרים: Vercel ו-Cloudflare Workers מפעילים רק את שכבת האינטרנט. הוראות השדרוג נמצאות ב-upgrade.md, והגיבויים ותרגול השחזור ב-backup-restore.md.
מה צריך
- Docker Engine 27 ומעלה עם תוסף Compose בגרסה 2.30 ומעלה.
- 4 ליבות CPU ו-8 GB זיכרון עבור ה-stack ברירת המחדל; 8 ליבות ו-16 GB עם
--profile full(ClamAV לבדו מחזיק כ-1.5 GB של חתימות). - שם DNS לשכבת האינטרנט ושם נוסף לתוכן לא מהימן. אלה חייבים להיות hosts שונים: חבילות SCORM ו-HTML שהועלה פועלים במקור התוכן, כדי שלא יוכלו לקרוא את העוגיות של מערכת הלמידה.
- לבדיקה מקומית,
lvh.meו-*.localhostנפתרים ל-127.0.0.1, כפי שמוגדר ב-docker/.env.example. שירות ה-proxyשל ה-stack עצמו מגיש את שניהם ב-https באמצעות רשות אישורים מקומית, כך שלא נדרשת התקנה נוספת (ראו “TLS”). - יש לפנות במארח את הפורטים 80 ו-443 (
QUIRE_PROXY_HTTP_PORTו-QUIRE_PROXY_HTTPS_PORTמשנים אותם).
הרצה ראשונה
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 initdocker/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 פשוט ב-production, והם
אינם יכולים לחלוק דומיין שניתן לרשום. שירות proxy מסיים את TLS לשניהם (ראו “TLS”);
init-env.sh מסרב למקור http://.
ה-stack מופעל בסדר קבוע, וכל שלב ממתין לקודמו:
postgresמגיע למצב בריא. בהפעלה הראשונה, סקריפט האתחול שלו (docker/postgres/init/90-passwords.sh) מגדיר סיסמאות לארבעת התפקידים.migrateמחיל כל מיגרציה ומאתחל את תור העבודות במסד הניהול ובכל מסד tenant ייעודי, מוודא שכולם תואמים ואז יוצא (ראו docs/ops/upgrade.md). מיגרציות פועלות בכל הפעלה והן idempotent, לכן שדרוג הוא תמונה חדשה והפעלה מחדש.init(apps/web/src/first-run.ts) רושם את מסד היישום תחתQUIRE_DATABASE_IDוכאשר מוגדרQUIRE_SETUP_ADMIN_EMAIL, יוצר את הארגון הראשון ואת מנהל המערכת שלו. כתובת הכניסה והסיסמה שנוצרה מוצגות פעם אחת ביומןdocker compose logs init.web,content,worker,scheduler,collabו-centrifugoמופעלים.proxyמופעל לאחר ש-webו-contentבריאים.
פתחו את https://demo. ואחריו את דומיין היישום (יומן init מציג את כתובת הכניסה
המדויקת) והיכנסו. בהתקנה מקומית, סמכו תחילה על רשות האישורים של ה-proxy (ראו “TLS”).
שנו את הסיסמה שנוצרה ב-/account/security.
תהליך שמופעל בלי סוד נדרש מסרב לעלות ומציין ביומן את ההגדרה החסרה. שום שירות אינו מופעל במצב שתצורתו חלקית.
שירותים ופרופילים
| שירות | פרופיל | תפקיד |
|---|---|---|
| postgres | תמיד | מסד הנתונים (PostgreSQL 18 עם pgvector, נבנה מ-docker/postgres.Dockerfile), עם ארכוב WAL מההפעלה הראשונה |
| migrate, init | תמיד | הרצה חד-פעמית: מיגרציות ואחריהן הרצה ראשונה |
| web | תמיד | מערכת הלמידה, ב-QUIRE_HTTP_PORT (8080) |
| content | תמיד | מקור לתוכן לא מהימן, ב-QUIRE_CONTENT_PORT (8081) |
| worker | תמיד | עבודות רקע: דוא״ל, דוחות, עיבוד קבצים ו-webhooks |
| scheduler | תמיד | עבודות מחזוריות: רושם את 64 לוחות הזמנים של זמן ריצה ומעביר אותם לעובד; מוביל אחד בכל פעם |
| collab | תמיד | WebSocket לעריכה משותפת, ב-QUIRE_COLLAB_HTTP_PORT (1234) |
| centrifugo | תמיד | הפצת realtime, ב-QUIRE_REALTIME_PORT (8000) |
| proxy | תמיד | Caddy, שער TLS קדמי בפורטים 80 ו-443 (ראו “TLS”) |
| valkey | cache |
מטמון ומגבלות קצב |
| clamav | scan |
סריקת קבצים שהועלו לאיתור נוזקות |
| gotenberg | preview |
תצוגות מקדימות של Office ל-PDF ורינדור תעודות |
| imgproxy | images |
שינוי גודל והמרת תמונות |
| transcoder | video |
תמונת worker עם ffmpeg ברישיון LGPL בלבד, להמרת סרטונים |
| 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 |
תמונת כלי 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, הווידאו מופעל כקובץ המקורי.
כל תמונת צד שלישי וחובות הרישוי שלה מפורטות ב-docker/third-party-containers.yaml.
חיבור ספק H5P
Quire אינו מטמיע או מספק סביבת H5P או רכיב נלווה (ADR 0019). אם אתם משתמשים ב-H5P, ספקו מנוי מתארח משלכם או הפעילו בנפרד מופע H5P באירוח עצמי. רשמו את הספק ככלי חיצוני LTI 1.3 והוסיפו את התוכן שלו לקורסים כפעילויות כלי. Quire מעביר ציונים והתקדמות בפעילות ובבדיקה דרך Assignment and Grade Services (AGS) של LTI. אם הספק שולח גם הצהרות xAPI, הגדירו את הדבר בנפרד למאגר ההצהרות xAPI של Quire; העברת ציונים והתקדמות ב-AGS אינה שולחת הצהרות xAPI. ייבוא Moodle מדווח שפעילויות H5P צריכות חיבור לכלי LTI. הספק נשאר אחראי על סביבת H5P, יצירת התוכן, בנק התוכן והיסטוריית הניסיונות.
כדי להפעיל מופע באירוח עצמי במארח הזה, הגדירו את QUIRE_H5P_IMAGE לתמונה שלו
והפעילו את פרופיל h5p. Compose מפרסם אותו ב-QUIRE_H5P_PORT (8090) ושומר את
נתוניו ב-volume h5p-data; התמונה והחובות הנלוות אליה נשארות באחריותכם.
הגדרות
כל תהליך קורא את docker/.env. תבנית docker/.env.example מפרטת כל הגדרה ואת
ברירת המחדל שלה. הקבוצות:
כתובות
| הגדרה | משמעות |
|---|---|
QUIRE_APP_ORIGIN |
הכתובת הציבורית של מערכת הלמידה, כגון 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_SECRET_KEY |
חתימת הפעלות ואסימונים. 64 תווי hex |
QUIRE_MASTER_KEY |
עטיפת פרטי גישה שמורים, כגון סודות SSO ו-webhook. 32 bytes, base64. שכבת האינטרנט וה-worker זקוקים לערך זהה. החלפה: key-rotation.md |
QUIRE_MASTER_KEY_VERSION |
תווית הגרסה של המפתח הראשי, v1 אם לא הוגדר. הגדילו בעת החלפה |
QUIRE_MASTER_KEY_RETIRED |
מפתחות ראשיים קודמים שנדרשים עדיין לקריאת מה שחתמו, בפורמט v1=<base64>. הסירו לאחר שההחלפה מסתיימת בלי פריטים שלא נפתרו |
QUIRE_COLLAB_SIGNING_KEY |
משותף ל-web ול-collab כדי לחתום על אסימוני עריכה |
QUIRE_BACKUP_SIGNING_KEY |
חתימה על גיבויי קורסים (אופציונלי) |
שמרו עותק של QUIRE_MASTER_KEY במקום שאינו המארח הזה. מסד ששוחזר בלעדיו אינו יכול
לפענח את פרטי הגישה שבו.
מסד נתונים
| הגדרה | משמעות |
|---|---|
POSTGRES_PASSWORD |
superuser, לשימוש הקונטיינר והגיבויים |
QUIRE_DB_APP_PASSWORD, QUIRE_DB_MIGRATOR_PASSWORD, QUIRE_DB_REPORT_PASSWORD, QUIRE_DB_AUDIT_PASSWORD |
סיסמאות תפקידים, נקבעות בהפעלה הראשונה |
DATABASE_URL |
תפקיד היישום. אבטחה ברמת שורה חלה על כל שאילתה שלו |
DATABASE_MIGRATOR_URL, QUIRE_MIGRATION_URL |
תפקיד הממגר, עבור migrate ו-init |
QUIRE_SUPERUSER_URL |
משמש רק בהרצה הראשונה |
QUIRE_REPORT_DATABASE_URL |
תפקיד דוחות לקריאה בלבד, עבור דוחות ובונה דוחות |
QUIRE_AUDIT_DATABASE_URL |
תפקיד הביקורת, עבור מסוף הביקורת וייצוא SIEM |
QUIRE_DATABASE_ID |
כל UUID שהוא, קבוע לאורך חיי ההתקנה |
סיסמאות תפקיד מוחלות רק בעת יצירת volume מסד הנתונים. לשינוי מאוחר יותר, השתמשו
ב-ALTER ROLE ועדכנו את כתובת ה-URL המתאימה.
QUIRE_REPORT_DATABASE_URL משמש למסד הפיזי שהוגדר ב-DATABASE_URL. עבור כל מסד
פיזי רשום אחר, הגדירו בסביבות web ו-worker כתובת חיבור quire_report משלו, ואז הכניסו
את שם משתנה הסביבה בשדה Reporting environment variable של אותו מסד, בתור
env:NAME. ההפניה צריכה להיות לאותו מסד של חיבור היישום, ועדיף לעותק לקריאה בלבד.
כל ממשק דוחות עוקב אחר ה-tenant לחיבור הדוחות של המסד שלו: בונה דוחות ודוחות
שמורים, שליחות מתוזמנות, ייצוא דוחות, analytics, יומן הביקורת, משאבי הביקורת של
REST וחיפוש הביקורת של העוזר. אף אחד מהם לעולם אינו משתמש בכתובת דוחות של מסד אחר.
כשאין חיבור דוחות למסד מסוים, דוחות רגילים פועלים באמצעות חיבור היישום שלו; analytics
וכל קריאת ביקורת נדחים ומסבירים זאת, מפני שלתפקיד היישום אין גישה לנתיב הביקורת.
Drivers
| הגדרה | בגרסה זו | הערות |
|---|---|---|
QUIRE_STORAGE_DRIVER |
local (ברירת מחדל), s3 או azure |
local שומר קבצים ב-volume files. s3 תומך ב-AWS S3, R2, תאימות GCS ומאגרי S3 אחרים, עם העלאות multipart שניתנות לחידוש |
QUIRE_REALTIME_DRIVER |
inprocess (ברירת מחדל), sse, centrifugo או durable_objects |
inprocess מתאים לקונטיינר web יחיד; השתמשו ב-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 |
ספק ברירת המחדל של הפלטפורמה למפגשים חיים. אם אינו מוגדר, מצוין שמפגשים חיים אינם מוגדרים עד שארגון מחבר חשבון משלו תחת Integrations, Live session provider. חשבון הארגון גובר תמיד על ערך זה. הגדרות ייחודיות לספק (BBB_URL ו-BBB_SECRET, משתני ZOOM_*, TEAMS_*, GOOGLE_MEET_* ו-JITSI_*) נקראות רק עבור הספק שנבחר כאן |
QUIRE_MEETING_REGIONS |
רשימת eu, uk, us, מופרדת בפסיקים |
האזורים שבהם ספק ברירת המחדל מעבד מפגשים. אם אינו מוגדר, הוא לא נבדק מול ארגון המשויך לאזור — כמו בעבר. חשבון ארגון מצהיר על האזורים בעמוד שלו |
ערך driver שאינו נכלל בגרסה זו נדחה בעת הפעלת שכבת האינטרנט, תוך ציון ההגדרה, במקום שיוחלף בשקט בערך ברירת המחדל.
תמונות
עמודים מבקשים תמונות בארבעה גדלים קבועים דרך /api/files/{id}/image/{size}.
הנתיב בודק את אותה גישה לקובץ עצמו ואז מפנה לשירות התמונות. כל ארגון רשאי לבקש
QUIRE_IMAGE_SPECS_PER_HOUR תמונות וצמדי גודל חדשים בשעה (ברירת מחדל 2000); גדלים
שכבר נוצרו באותה שעה אינם נספרים. השתמשו ב-valkey או ב-postgres עבור
QUIRE_CACHE_DRIVER כשיש יותר מקונטיינר web אחד, כדי שהמכסה תחול על כולם.
| הגדרה | Driver | הערות |
|---|---|---|
IMGPROXY_URL |
imgproxy |
הכתובת שאליה דפדפנים מגיעים, למשל https://images.example.org. פרופיל images מפרסם אותו ב-QUIRE_IMAGES_PORT (8082) |
IMGPROXY_KEY, IMGPROXY_SALT |
imgproxy |
מחרוזות hex, זהות לערכים שאיתם imgproxy מופעל. צרו כל אחת באמצעות openssl rand -hex 32. Quire חותם באמצעותן על כל כתובת תמונה, כך ש-imgproxy אינו מרנדר דבר ש-Quire לא ביקש |
QUIRE_IMAGE_SOURCE_ORIGIN |
imgproxy עם אחסון מקומי |
המקום שממנו imgproxy מביא קובצי מקור. Compose מגדיר http://web:3000. עם אחסון s3 או azure imgproxy מביא מה-bucket וההגדרה אינה משמשת |
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_IMAGES_TOKEN, CLOUDFLARE_IMAGES_ACCOUNT_HASH |
cloudflare |
אסימון API עם הרשאת עריכת Images, וגיבוב החשבון מתוך Images, Developer resources. הפעילו וריאציות גמישות לחשבון |
CLOUDFLARE_IMAGES_SIGNING_KEY |
cloudflare |
אופציונלי. כשהוא מוגדר, התמונות פרטיות וכל כתובת חתומה ופגה. בלעדיו התמונות ציבוריות בכתובות הנגזרות מ-QUIRE_SECRET_KEY שאיש אינו יכול לנחש |
Cloudflare Images שומר עותק משלו של כל מקור תמונה שהוא מגיש. כשקובץ נמחק, ה-worker מוחק תחילה את העותק הזה ורק אחר כך את המקור.
תור
עבודות רקע משתמשות ב-pg-boss באותו מסד PostgreSQL, לכן אין צורך להפעיל שירות תור
או להגדיר דבר. עבודות נכנסות לתור באותה טרנזקציה כמו השינוי שגרם להן, ולכן קריסה
אינה יכולה לאבד עבודה או לשלוח אותה פעמיים. כאן QUIRE_QUEUE_DRIVER הוא pgboss,
ערך ברירת המחדל; vercel ו-cloudflare מעבירים רק שליחות קלות של התראות ו-webhooks
לתור של הפלטפורמה, ומדריכי Vercel ו-Cloudflare מסבירים עליהם ועל אופן הכנסתם לתור
על ידי שכבות האינטרנט שלהם.
דוא״ל
הגדירו אחת מהאפשרויות:
QUIRE_EMAIL_PROVIDER_CONFIG: אובייקט JSON שמציין ספק HTTP ואת פרטי הגישה, למשל{"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.
שירותים אופציונליים
| הגדרה | עם פרופיל |
|---|---|
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 מכבה אותה, והכתובת מכוונת ל-API טווח שאתם מארחים |
תצפיתיות
OTEL_EXPORTER_OTLP_ENDPOINT מציין את האוסף שאליו כל תהליך שולח traces ומדדים;
עם פרופיל observability הערך הוא http://otelcol:4318, ו-
docker/otel-collector.yaml הוא המקום שבו מוסיפים exporter למערכת שלכם. שכבת
האינטרנט, worker, scheduler, content ו-collab מייצאים spans דרך OTLP/HTTP
(בקשות אינטרנט, טרנזקציות במסדי tenant, עבודות worker וקריאות יוצאות) אם ההגדרה
קיימת, ומדדים לאותה כתובת בכל דקה (OTEL_METRICS_EXPORTER=none מכבה אותם).
OTEL_TRACES_SAMPLER_ARG מגדיר את שיעור ה-traces שנשמרים. יומנים נשלחים לפלט
הרגיל ברמה LOG_LEVEL, ו-Compose מבצע להם רוטציה. Traces לעולם אינם מכילים מידע אישי.
תעבורה יוצאת לפי אזור (ריבונות נתוני EU)
QUIRE_REGION=eu מציין שה-stack משרת ארגונים מהאיחוד האירופי. ה-worker מגביל כל
בקשה יוצאת עבור ארגון שמשויך ל-EU לרשימת היתרים (21-compliance.md סעיף 8.1).
הרשימה כוללת את המארחים שהשירותים שהוגדרו מציינים עבור האזור (נקודת קצה לאחסון,
ספק דוא״ל, ספק וידאו מתארח, יעדי האחסון של הארגון, ספקי AI וחשבון דוא״ל), את
המארחים של שירות תחת חריגה פעילה ואת המארחים שציינתם ב-QUIRE_EGRESS_ALLOW_HOSTS.
בקשה לכל מארח ציבורי אחר נדחית לפני שליחתה, הסירוב נרשם ביומן הביקורת של הארגון
בתור privacy/egress_refused והוא מופיע תחת Compliance, Data residency.
| הגדרה | ערכים | השפעה |
|---|---|---|
QUIRE_EGRESS_ALLOW_HOSTS |
רשימת שמות מארח מופרדת בפסיקים, או *.example.org עבור כל תת-דומיין |
מארחים נוספים שארגון באיחוד יכול להגיע אליהם. נקודות קצה של webhook, xAPI ו-SIEM, הזנות בלוגים ומארחי Amazon SES שייכים לכאן, כי אלה בחירות של הארגון ושום שירות אינו מצהיר עליהם. כתובות loopback, כתובות פרטיות ושמות בעלי תווית אחת כמו web או clamav הם הרשת שלכם ולעולם אינם נבדקים |
ארגוני UK ו-US אינם מוגבלים לרשימת מארחים; בדיקות אזור השירות נשארות בתוקף.
הגדירו את הרשימה ב-worker; עמוד הניהול קורא אותה בשכבת האינטרנט כדי להציג אותה,
לכן שימו אותה ב-docker/.env, שכל השירותים קוראים.
בדיקת היישום נותנת הודעת שגיאה ברורה ורשומת ביקורת, אך היא אינה הערובה: הקוד עלול
להיות שגוי. הערובה היא הרשת. Compose אינו אוכף אותה עבורכם. עבור stack אזורי, הציבו
את שירותי worker ו-web ברשת internal: true שהנתיב היחיד שלה החוצה הוא proxy
לתעבורה יוצאת (למשל Squid או קונטיינר tinyproxy) שמתיר את אותם מארחים כמו
QUIRE_EGRESS_ALLOW_HOSTS ואת מארחי השירותים שהגדרתם, והגדירו HTTPS_PROXY לשירותים
הללו. עמוד ריבונות הנתונים מפרט את המארחים שהיישום מתיר, כך שאפשר להשוות בין שתי
הרשימות.
תקינות
| נקודת קצה | משמעות |
|---|---|
/healthz |
חיוניות: התהליך מגיב. בדיקות התקינות של Compose משתמשות בה |
/readyz |
מוכנות: אפשר להגיע לתלויות, וכל שירות אופציונלי מדווח אם הוגדר. כוונו אליה את מאזן העומסים |
docker compose -f docker/compose.yaml ps מציג את מצב הבריאות של כל שירות.
TLS
שירות proxy (Caddy, Apache-2.0, docker/caddy/Caddyfile) הוא חלק מה-stack
ברירת המחדל. הוא מאזין בפורטים 80 ו-443 ומנתב:
| מארח או נתיב | מועבר אל |
|---|---|
QUIRE_PROXY_CONTENT_HOST |
content |
QUIRE_PROXY_APP_HOST, כל תת-דומיין tenant ודומיין מותאם אישית |
web |
/_collab/ במארחים האלה |
collab (websocket, QUIRE_COLLAB_URL) |
/_realtime/connection/ במארחים האלה |
websocket לקוח של centrifugo; ה-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. בטחו פעם אחת באישור השורש ואז גלשו: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 של שני המקורות ושל כל מארחי ה-tenants חייב להפנות לכאן, והאינטרנט חייב להגיע לפורטים 80 ו-443.
אישורי מארחי tenant מונפקים לפי דרישה, בביקור הראשון, ורק לאחר שה-web מאשר שהשם
שייך להתקנה הזאת (/tls-allowed, בבקשה ברשת Compose). אין צורך באישור wildcard או
בתוסף לספק DNS, ואדם זר שמפנה שם אל המארח אינו יכול לגרום לבקשת אישור. האישורים
ורשות האישורים המקומית נמצאים ב-volume caddy-data; אם אתם משתמשים ב-internal,
גבו אותו יחד עם השאר.
ה-web מאמין לערך X-Forwarded-For מה-proxy בלבד: ל-proxy כתובת קבועה
(QUIRE_PROXY_ADDRESS, ברירת מחדל 172.29.64.10) ברשת משנה קבועה
(QUIRE_COMPOSE_SUBNET), ו-QUIRE_TRUSTED_PROXY_CIDRS מציין כתובת זו. אם רשת המשנה
מתנגשת עם רשת אחרת במארח, שנו את שתיהן והפעילו docker compose down לפני up.
מאחורי reverse proxy משלכם
כדי להשתמש במאזן עומסים או ב-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.
פתרון בעיות
initיוצא עם “QUIRE_DATABASE_ID is not a UUID”: הגדירו אותו באמצעותuuidgen.webמופעל מחדש עם “did not start on compose”: היומן מפרט כל הגדרה שאי אפשר לכבד ומה לשים במקומה.- שינוי סיסמת תפקיד ב-
.envלאחר ההפעלה הראשונה אינו משפיע: סקריפט האתחול רץ פעם אחת בלבד. השתמשו ב-ALTER ROLE. - העלאות נכשלות עם שגיאת סריקה כש-
CLAMAV_URLמוגדר: ClamAV מוריד חתימות בהפעלה הראשונה וזה נמשך כמה דקות.