বিষয়বস্তুতে যান

Docker Compose দিয়ে Quire ইনস্টল

নিজস্ব পরিকাঠামোয় Docker Compose দিয়ে Quire ইনস্টল করুন।

Markdown হিসেবে দেখুন

এক হোস্টে এটিই সম্পূর্ণ পণ্য: LMS, এর পটভূমির কাজ, রিয়েলটাইম ও যৌথ সম্পাদনার সেবা, এবং প্রোফাইলের মাধ্যমে চালু করা সব ঐচ্ছিক সেবা। নকশা docs/architecture/23-ops.md-এর section 2-এ।

অন্য লক্ষ্য: Vercel ও Cloudflare Workers শুধু web tier চালায়। Upgrade নির্দেশনা upgrade.md-তে; পরিবর্তনের আগে backup ও restore drill-এর জন্য backup-restore.md কাছে রাখুন।

যা প্রয়োজন

  • Docker Engine 27 বা পরের সংস্করণ এবং Compose plugin 2.30 বা পরের সংস্করণ।
  • Default stack-এর জন্য 4 CPU core ও 8 GB memory; --profile full-সহ 8 core ও 16 GB (শুধু ClamAV-এর signature প্রায় 1.5 GB জায়গা নেয়)।
  • 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-এ দুটিই পরিবেশন করে, তাই অন্য কিছু ইনস্টল করতে হয় না (দেখুন “TLS”)।
  • Host-এ 80 ও 443 port খালি রাখুন (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 init

docker/scripts/init-env.sh docker/.env-এ সব secret তৈরি করে এবং docker/.env.example থেকে file লেখে (database password, signing ও master key, content launch key pair); পাশাপাশি audit checkpoint signing key রাখে docker/secrets/audit-signing-key.pem-এ, যা Compose secret হিসেবে worker-এ mount করে। শুধু sh, awk ও openssl দরকার; বিদ্যমান docker/.env overwrite করতে এটি অস্বীকার করে। দুটি file-ই host-এর বাইরে copy করে রাখুন: QUIRE_MASTER_KEY ছাড়া restore করা database তার credential decrypt করতে পারে না। হাতে file পূরণ করতে চাইলে cp docker/.env.example docker/.env চালান; প্রতিটি secret তৈরির নির্দেশ file-এ আছে।

দুটি origin-ই https হতে হবে: production-এ content service plain http প্রত্যাখ্যান করে এবং দুটির registrable domain এক হতে পারবে না। proxy service দুটির TLS termination করে (দেখুন “TLS”); init-env.sh http:// origin প্রত্যাখ্যান করে।

Stack নির্দিষ্ট ক্রমে চলে এবং প্রতিটি ধাপ আগেরটি শেষ হওয়া পর্যন্ত অপেক্ষা করে:

  1. postgres healthy হয়। প্রথম startup-এ এর init script (docker/postgres/init/90-passwords.sh) চারটি role password সেট করে।
  2. migrate control database ও প্রতিটি নির্দিষ্ট tenant database-এ সব migration চালায় এবং 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-এর অধীনে নথিভুক্ত করে এবং QUIRE_SETUP_ADMIN_EMAIL সেট করা থাকলে প্রথম organisation ও তার administrator তৈরি করে। Sign-in address ও তৈরি করা password একবারই docker compose logs init-এ ছাপা হয়।
  4. web, content, worker, scheduler, collab ও centrifugo চালু হয়।
  5. proxy চালু হয়, যখন web ও content সুস্থ হয়।

https://demo.-এর পরে আপনার application domain লিখে খুলুন (সঠিক sign-in address init log-এ ছাপা হয়), তারপর sign in করুন। Local install-এ আগে proxy-র certificate authority-কে trust করুন (দেখুন “TLS”)। তৈরি করা password /account/security-এ বদলান।

প্রয়োজনীয় secret ছাড়া শুরু করা process startup প্রত্যাখ্যান করে এবং log-এ অনুপস্থিত setting-এর নাম জানায়। কোনো কিছু আংশিক configuration নিয়ে চালু হয় না।

সেবা ও profile

সেবা Profile কাজ
postgres সবসময় Database (PostgreSQL 18 ও pgvector, docker/postgres.Dockerfile থেকে তৈরি), প্রথম boot থেকেই WAL archive হয়
migrate, init সবসময় একবার চলে: migration, তারপর প্রথম setup
web সবসময় LMS, QUIRE_HTTP_PORT-এ (8080)
content সবসময় অবিশ্বস্ত content origin, QUIRE_CONTENT_PORT-এ (8081)
worker সবসময় Background job: email, report, file processing, webhook
scheduler সবসময় পুনরাবৃত্ত কাজ: 64টি runtime schedule নিবন্ধন করে worker-কে দেয়; একবারে একজন leader
collab সবসময় যৌথ সম্পাদনার websocket, QUIRE_COLLAB_HTTP_PORT-এ (1234)
centrifugo সবসময় Realtime fan-out, QUIRE_REALTIME_PORT-এ (8000)
proxy সবসময় Caddy, 80 ও 443 port-এর TLS front door (দেখুন “TLS”)
valkey cache Cache ও rate limit
clamav scan Upload-এ malware scan
gotenberg preview Office থেকে PDF preview, certificate rendering
imgproxy images Image resize ও conversion
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 এবং সাপ্তাহিক যাচাই drill-সহ host-এর বাইরে encrypted copy
h5p h5p আপনার দেওয়া H5P LTI 1.3 tool image QUIRE_H5P_IMAGE-এ, QUIRE_H5P_PORT-এ (8090); দেখুন “H5P provider যুক্ত করা”

--profile full backup ও h5p বাদে সব ঐচ্ছিক service চালায়। একটি service চালাতে docker compose -f docker/compose.yaml --profile scan up -d ব্যবহার করুন। ঐচ্ছিক service ছাড়াও Quire চলে এবং কী নেই তা জানায়: scanner না থাকলে upload scan ছাড়াই সংরক্ষিত হয় এবং administrator-কে জানানো হয়; Gotenberg না থাকলে file preview-এর বদলে download করা যায়; transcoder না থাকলে video মূল file হিসেবেই চলে।

প্রতিটি third-party image ও এর license-এর শর্ত docker/third-party-containers.yaml-এ তালিকাভুক্ত।

H5P provider যুক্ত করা

Quire H5P runtime বা sidecar embed বা ship করে না (ADR 0019)। H5P ব্যবহার করলে নিজস্ব hosted subscription নিন অথবা Quire থেকে আলাদা নিজস্ব self-hosted H5P instance পরিচালনা করুন। Provider-কে LTI 1.3 external tool হিসেবে নিবন্ধন করে tool activity হিসেবে course-এ এর content যোগ করুন। Quire LTI Assignment and Grade Services (AGS) দিয়ে grade ও activity/grading progress আদানপ্রদান করে। Provider xAPI statement-ও পাঠালে Quire-এর xAPI statement store-এর জন্য আলাদাভাবে configure করুন; AGS grade/progress বিনিময়ে 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 দিয়ে h5p profile চালু করুন। Compose এটি QUIRE_H5P_PORT-এ (8090) প্রকাশ করে এবং data h5p-data volume-এ রাখে; image ও এর সঙ্গে আসা দায় আপনার।

Setting

প্রতিটি process docker/.env পড়ে। Template docker/.env.example-এ প্রতিটি setting ও default-এর তালিকা আছে। বিভাগগুলো:

ঠিকানা

Setting অর্থ
QUIRE_APP_ORIGIN LMS-এর public address, যেমন https://learn.example.com
QUIRE_CONTENT_ORIGIN content origin, অন্য host-এ
QUIRE_PLATFORM_DOMAINS প্রতিষ্ঠানের domain, comma দিয়ে আলাদা
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-এর জন্য অন্য guide দেখুন
QUIRE_TRUSTED_PROXY_CIDRS যেসব proxy-র X-Forwarded-For বিশ্বাস করা হয়

Secret

Setting অর্থ
QUIRE_SECRET_KEY Session ও token sign করে। 64টি hex character
QUIRE_MASTER_KEY SSO ও webhook secret-এর মতো সংরক্ষিত credential wrap করে। 32 byte, base64। Web tier ও worker-এ একই মান লাগবে। Rotation: key-rotation.md
QUIRE_MASTER_KEY_VERSION Master key-এর version label; unset হলে v1। Rotation করলে এটি বাড়ান
QUIRE_MASTER_KEY_RETIRED আগে seal করা তথ্য পড়তে লাগতে পারে এমন পুরোনো master key, যেমন v1=<base64>। Unresolved কিছু না রেখে rotation শেষ হলে সরান
QUIRE_COLLAB_SIGNING_KEY Editing token sign করতে web ও collab-এর মধ্যে ভাগ করা key
QUIRE_BACKUP_SIGNING_KEY Course backup sign করে (ঐচ্ছিক)

এই host ছাড়া অন্য কোথাও QUIRE_MASTER_KEY-এর copy রাখুন। এটি ছাড়া restore করা database তার credential decrypt করতে পারে না।

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, প্রথম startup-এ সেট হয়
DATABASE_URL Application role। এর প্রতিটি query-তে row-level security প্রযোজ্য
DATABASE_MIGRATOR_URL, QUIRE_MIGRATION_URL migrate ও init-এর migrator role
QUIRE_SUPERUSER_URL শুধু প্রথমবার ব্যবহৃত হয়
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 দিয়ে configure করা physical database-এর জন্য ব্যবহৃত হয়। অন্য কোনো নিবন্ধিত physical database হলে web ও worker environment-এ সেটির নিজস্ব quire_report connection URL দিন, তারপর database-এর Reporting environment variable field-এ variable name env:NAME হিসেবে লিখুন। Reference-টি app 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

Setting এই release বিবরণ
QUIRE_STORAGE_DRIVER local (default), s3 অথবা azure local file files volume-এ রাখে। s3 AWS S3, R2, GCS interoperability ও অন্যান্য S3-compatible storage সমর্থন করে, 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 অথবা key-সহ hosted provider: Cloudflare Stream, Mux বা Bunny
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 provider। Unset থাকলে প্রতিষ্ঠান Integrations, Live session provider-এ নিজস্ব account যুক্ত না করা পর্যন্ত live session configure করা নেই বলে জানায়। প্রতিষ্ঠানের নিজস্ব account সবসময় এই মানের ওপর অগ্রাধিকার পায়। প্রতিটি provider-এর নিজস্ব setting (BBB_URL ও BBB_SECRET, ZOOM_*, TEAMS_*, GOOGLE_MEET_* এবং JITSI_* variable) এখানে নাম দেওয়া provider-এর জন্যই শুধু পড়া হয়
QUIRE_MEETING_REGIONS eu, uk, us-এর comma-separated list Platform default provider meeting কোথায় process করে। Unset থাকলে আগের মতো region-এ বাঁধা প্রতিষ্ঠানের বিরুদ্ধে পরীক্ষা হয় না। প্রতিষ্ঠানের নিজস্ব account-এর page-এ তার region জানানো হয়

এই release-এ নেই এমন driver value পেলে web tier startup প্রত্যাখ্যান করে এবং setting-এর নাম জানায়; default দিয়ে নীরবে বদলে দেয় না।

Image

Page চারটি নির্দিষ্ট আকারে image চায় /api/files/{id}/image/{size} দিয়ে। এটি file-এর মতোই access পরীক্ষা করে তারপর image service-এ redirect করে। প্রতিটি প্রতিষ্ঠান প্রতি ঘণ্টায় QUIRE_IMAGE_SPECS_PER_HOUR (default 2000)টি নতুন image ও size-এর জোড়া চাইতে পারে; ওই ঘণ্টায় আগে তৈরি size গণনায় আসে না। একাধিক web container থাকলে valkey বা postgres ব্যবহার করুন QUIRE_CACHE_DRIVER-এর জন্য, যাতে সীমা সব container-এ কার্যকর হয়।

Setting Driver বিবরণ
IMGPROXY_URL imgproxy Browser থেকে imgproxy-তে যাওয়ার address, যেমন https://images.example.org। images profile এটিকে QUIRE_IMAGES_PORT-এ (8082) প্রকাশ করে
IMGPROXY_KEY, IMGPROXY_SALT imgproxy Hex string; imgproxy চালানোর সময় ব্যবহৃত মানের সঙ্গে একই। প্রতিটি তৈরি করতে openssl rand -hex 32 চালান। Quire প্রতিটি image address এগুলো দিয়ে sign করে, তাই Quire না চাইলে imgproxy কিছু render করে না
QUIRE_IMAGE_SOURCE_ORIGIN local storage-সহ imgproxy imgproxy কোথা থেকে original আনে। Compose http://web:3000 সেট করে। s3 বা azure storage হলে imgproxy bucket থেকে আনে, তাই এটি ব্যবহৃত হয় না
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 ঐচ্ছিক। সেট করা থাকলে image private হয় এবং প্রতিটি address sign করা ও মেয়াদযুক্ত হয়। এটি না থাকলে image public এবং QUIRE_SECRET_KEY থেকে তৈরি অনুমান করা যায় না এমন address-এ থাকে

Cloudflare Images পরিবেশিত প্রতিটি original-এর নিজস্ব copy রাখে। কোনো file delete হলে worker original-এর আগে ওই copy মুছে দেয়।

Queue

Background job একই Postgres database-এ pg-boss ব্যবহার করে, তাই আলাদা queue service চালাতে হয় না বা configuration লাগে না। যে পরিবর্তনের কারণে job তৈরি হয় তার একই transaction-এ এটি queue-তে যায়, ফলে crash হলে হারায় না বা দুবার পাঠানো হয় না। এখানে QUIRE_QUEUE_DRIVER-এর default pgboss; vercel ও cloudflare শুধু হালকা notification ও webhook delivery-কে platform-এর নিজস্ব queue-তে সরায়। Vercel ও Cloudflare guide-এ এগুলো এবং তাদের web tier কীভাবে enqueue করে তা বলা আছে।

Email

নিচের একটি সেট করুন:

  • 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 আটকে দেয়।

প্রেরক QUIRE_MAIL_FROM। Quire পরীক্ষা করতে devmail profile চালু করে QUIRE_SMTP_URL=smtp://mailpit:1025 সেট করুন এবং http://localhost:8025-এ mail পড়ুন।

ঐচ্ছিক service

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 External search; নইলে Postgres full text
QUIRE_BREACH_CHECK_PROVIDER=off, QUIRE_BREACH_CHECK_URL Password breach check। Default-এ api.pwnedpasswords.com-এর বিরুদ্ধে চালু (hash-এর শুধু পাঁচ character-এর prefix পাঠানো হয়); off বন্ধ করে, URL আপনার host করা range API-তে নির্দেশ করে

পর্যবেক্ষণ

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

আঞ্চলিক egress (EU data residency)

QUIRE_REGION=eu জানায় stack ইউরোপীয় ইউনিয়নের প্রতিষ্ঠান পরিবেশন করে। তখন EU অঞ্চলে বাঁধা প্রতিষ্ঠানের হয়ে worker-এর প্রতিটি outbound request allowlist-এ সীমিত থাকে (21-compliance.md section 8.1)। Configured service-গুলো region-এর জন্য যে host ঘোষণা করে (storage endpoint, email provider, hosted video provider, প্রতিষ্ঠানের নিজস্ব storage target, AI provider ও email account), সক্রিয় derogation-এ থাকা service-এর host এবং আপনার QUIRE_EGRESS_ALLOW_HOSTS-এ দেওয়া host—এগুলোই allowlist। অন্য কোনো public host-এ request পাঠানোর আগেই প্রত্যাখ্যাত হয়; প্রত্যাখ্যান প্রতিষ্ঠানের audit trail-এ privacy/egress_refused হিসেবে লেখা হয় এবং Compliance, Data residency-তে দেখায়।

Setting মান প্রভাব
QUIRE_EGRESS_ALLOW_HOSTS comma দিয়ে আলাদা hostname-এর তালিকা, অথবা সব subdomain-এর জন্য *.example.org EU প্রতিষ্ঠান যে অতিরিক্ত host-এ পৌঁছাতে পারে। Webhook, xAPI ও SIEM endpoint, blog feed এবং Amazon SES host এখানে রাখুন, কারণ প্রতিষ্ঠানের নিজের পছন্দে সেগুলো আসে এবং কোনো service সেগুলো ঘোষণা করে না। Loopback, private address ও web বা clamav-এর মতো এক label-এর name আপনার নিজের network; এগুলো কখনো পরীক্ষা হয় না

যুক্তরাজ্য ও যুক্তরাষ্ট্রের প্রতিষ্ঠান host list-এ আবদ্ধ নয়; তাদের ক্ষেত্রে service region পরীক্ষা থাকে। Worker-এ তালিকা সেট করুন; allowlist দেখাতে admin page web tier-এ এটি পড়ে, তাই সব service যে docker/.env পড়ে, সেখানেই রাখুন।

Application check স্পষ্ট error ও audit entry দেয়, কিন্তু এটিই নিশ্চয়তা নয়: code ভুল হতে পারে। নিশ্চয়তা network। Compose নিজে এটি enforce করে না। আঞ্চলিক stack-এর জন্য worker ও web service-কে internal: true network-এ রাখুন; বাইরের একমাত্র পথ হবে এমন egress proxy (যেমন Squid বা tinyproxy container), যা QUIRE_EGRESS_ALLOW_HOSTS-এর একই host এবং configure করা service-এর host অনুমোদন করে। ওই service-গুলোর জন্য HTTPS_PROXY সেট করুন। Residency page-এ application ঠিক কোন host অনুমোদন করে তা দেখা যায়, তাই দুই তালিকা তুলনা করা যায়।

স্বাস্থ্য

Endpoint অর্থ
/healthz Liveness: process উত্তর দেয়। Compose health check এটি ব্যবহার করে
/readyz Readiness: dependency পৌঁছানো যায় এবং প্রতিটি ঐচ্ছিক service configure আছে কি না জানানো হয়। Load balancer এখানে নির্দেশ করুন

docker compose -f docker/compose.yaml ps প্রতিটি service-এর health দেখায়।

TLS

proxy service (Caddy, Apache-2.0, docker/caddy/Caddyfile) default stack-এর অংশ। এটি 80 ও 443 port-এ সাড়া দেয় এবং 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, images profile-সহ (IMGPROXY_URL)

init-env.sh দুটি origin থেকে QUIRE_PROXY_APP_HOST, QUIRE_PROXY_CONTENT_HOST, QUIRE_PROXY_HTTPS_PORT, QUIRE_COLLAB_URL ও IMGPROXY_URL তৈরি করে, তাই মানগুলো পরস্পর থেকে বিচ্যুত হয় না। হাতে origin বদলালে এগুলোও একসঙ্গে সম্পাদনা করুন।

Certificate QUIRE_PROXY_TLS অনুযায়ী চলে:

  • internal (default): localhost, *.localhost ও lvh.me-এর জন্য Caddy-র নিজস্ব certificate authority। এর root একবার trust করে তারপর browse করুন:

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

    System বা browser-এর trust store-এ quire-local-ca.crt যোগ করুন। curl-এ এটি --cacert দিয়ে দিন।

  • Email address: বাস্তব hostname-এর জন্য স্বয়ংক্রিয় ACME certificate (আগে Let’s Encrypt, পরে ZeroSSL)। দুই origin ও প্রতিটি tenant host-এর DNS-কে এখানে নির্দেশ করতে হবে এবং 80 ও 443 port ইন্টারনেট থেকে পৌঁছানো যায় এমন হতে হবে।

Tenant host-এর certificate প্রথমবার আসলে চাওয়া হয়, এবং web যে নাম এই install-এর বলে নিশ্চিত করলেই শুধু (/tls-allowed, Compose network-এ জিজ্ঞাসা করা হয়)। Wildcard certificate বা DNS provider plugin দরকার নেই; কেউ host-এ নাম নির্দেশ করলেও certificate request করাতে পারবে না। Certificate ও local authority caddy-data volume-এ থাকে; internal ব্যবহার করলে বাকি backup-এর সঙ্গে এটিও backup করুন।

Web শুধু proxy থেকে পাওয়া X-Forwarded-For বিশ্বাস করে: proxy-র স্থির address (QUIRE_PROXY_ADDRESS, default 172.29.64.10) স্থির subnet-এ (QUIRE_COMPOSE_SUBNET) থাকে এবং QUIRE_TRUSTED_PROXY_CIDRS সেই address-টি উল্লেখ করে। Subnet host-এর কোনো network-এর সঙ্গে মিলে গেলে দুটোই বদলে docker compose down চালান, তারপর up করুন।

নিজের reverse proxy-র পেছনে

আগে থেকে চালানো load balancer বা proxy ব্যবহার করতে proxy বাদ দিন (docker compose up -d --scale proxy=0) এবং web (8080), content (8081), collab (1234, websocket) ও centrifugo (8000, websocket)-এর সামনে TLS termination করুন। Public address দিন QUIRE_APP_ORIGIN, QUIRE_CONTENT_ORIGIN ও QUIRE_COLLAB_URL-এ (wss://), আর proxy-র address range দিন QUIRE_TRUSTED_PROXY_CIDRS-এ।

সমস্যা সমাধান

  • init “QUIRE_DATABASE_ID is not a UUID” দিয়ে শেষ হলে uuidgen দিয়ে এটি সেট করুন।
  • web “did not start on compose” দিয়ে restart হলে log-এ মানতে পারে না এমন প্রতিটি setting ও বিকল্প লেখা থাকে।
  • প্রথম startup-এর পর .env-এ role password বদলালে কিছু হয় না: init script একবারই চলে। ALTER ROLE ব্যবহার করুন।
  • CLAMAV_URL সেট থাকা অবস্থায় scan error-এ upload ব্যর্থ হলে, প্রথম startup-এ ClamAV signature download করছে; কয়েক মিনিট লাগবে।
নেভিগেশন

খুঁজতে লিখুন…

↑↓ নেভিগেট করুন↵ নির্বাচন করুনEsc বন্ধ করুন