이것은 한 호스트 위의 전체 제품입니다. LMS, 백그라운드 작업, 실시간·협업
편집 서비스, 그리고 프로필 뒤의 모든 선택적 서비스가 포함됩니다. 설계는
docs/architecture/23-ops.md 2절입니다.
다른 타깃: Vercel과 Cloudflare Workers는 웹 계층만 실행합니다. 업그레이드는 upgrade.md에, 백업과 복구 훈련은 backup-restore.md에 있습니다.
필요한 것
- Docker Engine 27 이상과 Compose 플러그인 2.30 이상.
- 기본 스택에는 4 CPU 코어와 8GB 메모리.
--profile full에는 8 코어와 16GB(ClamAV만 시그니처를 약 1.5GB 가집니다). - 웹 계층용 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_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를 거부하며, 등록 가능한 도메인을 공유해서도 안 됩니다. proxy 서비스가
둘 다의 TLS를 종료합니다(“TLS” 참조). init-env.sh는 http:// 오리진을
거부합니다.
스택은 고정된 순서로 시작하며 각 단계는 앞 단계를 기다립니다.
postgres가 건강해집니다. 첫 시작에서 초기화 스크립트 (docker/postgres/init/90-passwords.sh)가 네 역할의 비밀번호를 설정합니다.migrate가 모든 마이그레이션을 적용하고 제어 데이터베이스와 모든 전용 테넌트 데이터베이스에 작업 큐를 부트스트랩하며, 둘이 일치하는지 확인한 뒤 종료합니다(docs/ops/upgrade.md). 마이그레이션은 매 실행에서 실행되고 멱등하므로 업그레이드는 새 이미지와 재시작입니다.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 로그가 정확한 로그인
주소를 출력합니다)을 열어 로그인하세요. 로컬 설치라면 먼저 프록시의 인증
기관을 신뢰하세요(“TLS” 참조). 생성된 비밀번호는 /account/security에서
바꾸세요.
필수 시크릿 없이 시작된 프로세스는 시작을 거부하고 로그에 누락된 설정을 명시합니다. 설정이 반쯤 된 채로 시작되는 것은 없습니다.
서비스와 프로필
| 서비스 | 프로필 | 하는 일 |
|---|---|---|
| postgres | 항상 | 데이터베이스(pgvector가 있는 PostgreSQL 18, docker/postgres.Dockerfile로 빌드), 첫 부팅부터 WAL 보관 |
| migrate, init | 항상 | 일회성: 마이그레이션, 그다음 첫 실행 |
| web | 항상 | LMS, QUIRE_HTTP_PORT(8080) |
| content | 항상 | 신뢰하지 않는 콘텐츠 오리진, QUIRE_CONTENT_PORT(8081) |
| worker | 항상 | 백그라운드 작업: 이메일, 리포트, 파일 처리, 웹훅 |
| scheduler | 항상 | 반복 작업: 64개의 런타임 스케줄을 등록해 워커에 넘김. 한 번에 하나의 리더 |
| collab | 항상 | 협업 편집 웹소켓, 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는 H5P 런타임이나 사이드카를 임베드하거나 제공하지 않습니다(ADR 0019). H5P를 쓴다면 자체 호스팅 구독을 제공하거나, Quire와 별도로 직접 운영하는 셀프호스트 H5P 인스턴스를 두세요. 그 공급자를 LTI 1.3 외부 도구로 등록하고 그 콘텐츠를 도구 활동으로 코스에 추가하세요. Quire는 LTI 과제 및 성적 서비스(AGS)로 성적과 활동/채점 진행을 주고받습니다. 공급자가 xAPI 진술도 보낸다면 Quire의 xAPI 진술 저장소를 위해 별도로 설정하세요. AGS 성적/진행 교환은 xAPI 진술을 보내지 않습니다. Moodle 가져오기는 H5P 활동이 LTI 도구 연결이 필요하다고 보고합니다. H5P 런타임, 저작, 콘텐츠 뱅크, 응시 이력에 대한 책임은 공급자에게 있습니다.
이 호스트에서 직접 셀프호스트 인스턴스를 돌리려면 QUIRE_H5P_IMAGE를 그
이미지로 설정하고 h5p 프로필을 시작하세요. Compose는
QUIRE_H5P_PORT(8090)로 공개하고 데이터를 h5p-data 볼륨에 보관합니다.
이미지와 그에 따르는 의무는 당신의 것입니다.
설정
모든 프로세스는 docker/.env를 읽습니다. 템플릿 docker/.env.example에는
각 설정과 기본값이 나열되어 있습니다. 그 그룹들:
주소
| 설정 | 의미 |
|---|---|
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_SECRET_KEY |
세션과 토큰에 서명. 16진수 64자 |
QUIRE_MASTER_KEY |
SSO나 웹훅 시크릿 같은 저장된 자격 증명을 감쌈. 32바이트, base64. 웹 계층과 워커가 같은 값을 써야 합니다. 로테이션: 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 |
슈퍼유저. 컨테이너와 백업이 사용 |
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을 설정한 뒤, 그 변수 이름을 해당 데이터베이스의
Reporting environment variable 필드에 env:NAME으로 넣으세요. 참조는
앱 연결과 같은 데이터베이스, 가능하면 읽기 복제본을 가리켜야 합니다. 모든
리포트 화면은 테넌트를 따라 그 데이터베이스의 리포트 연결로 갑니다. 리포트
빌더와 저장된 리포트, 예약 전달, 리포트 내보내기, 분석, 감사 로그, REST
감사 리소스, 어시스턴트의 감사 검색이 그렇습니다. 어느 것도 다른
데이터베이스의 리포트 URL을 빌려 쓰지 않습니다. 리포트 연결이 없는
데이터베이스에서는 일반 리포트는 그 데이터베이스 자체의 애플리케이션
연결에서 실행되지만, 분석과 모든 감사 읽기는 거부하고 그렇게 알립니다.
애플리케이션 역할은 감사 추적을 읽을 수 없기 때문입니다.
드라이버
| 설정 | 이번 릴리스 | 참고 |
|---|---|---|
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 |
라이브 세션의 플랫폼 기본값. 미설정이면 라이브 세션은 구성되지 않았다고 알리며, 조직이 연동 아래의 Live session provider에서 자체 계정을 연결할 때까지 그럽니다. 조직의 자체 계정이 항상 이 값보다 이깁니다. 각 공급자 자체의 설정(BBB_URL과 BBB_SECRET, ZOOM_*, TEAMS_*, GOOGLE_MEET_*, JITSI_* 변수)은 여기에 명시된 공급자에 대해서만 읽습니다 |
QUIRE_MEETING_REGIONS |
eu, uk, us의 쉼표 목록 |
플랫폼 기본 공급자가 회의를 처리하는 지역. 미설정이면 이전처럼 지역에 고정된 조직과 대조하지 않습니다. 조직의 자체 계정은 그 페이지에 지역을 명시합니다 |
이 릴리스에 없는 드라이버 값은 조용히 기본값으로 대체되지 않고 웹 계층이 시작할 때 설정 이름과 함께 거부합니다.
이미지
페이지는 /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를 시작할 때 쓰는 것과 같은 값의 16진수 문자열. 각각 openssl rand -hex 32로 만드세요. Quire가 이것들로 모든 이미지 주소에 서명하므로 imgproxy는 Quire가 요청하지 않은 것을 렌더링하지 않습니다 |
QUIRE_IMAGE_SOURCE_ORIGIN |
로컬 저장소가 있는 imgproxy |
imgproxy가 원본을 가져오는 곳. Compose는 http://web:3000으로 설정합니다. s3나 azure 저장소에서는 버킷에서 가져오므로 쓰이지 않습니다 |
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_IMAGES_TOKEN, CLOUDFLARE_IMAGES_ACCOUNT_HASH |
cloudflare |
Images 편집 권한이 있는 API 토큰과 Images, Developer resources의 계정 해시. 계정의 flexible variants를 켜세요 |
CLOUDFLARE_IMAGES_SIGNING_KEY |
cloudflare |
선택 사항. 설정하면 이미지가 비공개가 되고 모든 주소에 서명과 만료가 붙습니다. 없으면 QUIRE_SECRET_KEY에서 파생되어 아무도 추측할 수 없는 주소로 이미지가 공개됩니다 |
Cloudflare Images는 제공하는 각 원본의 자체 사본을 보관합니다. 파일이 삭제되면 워커가 원본보다 먼저 그 사본을 삭제합니다.
큐
백그라운드 작업은 같은 Postgres 데이터베이스에서 pg-boss를 사용하므로 실행할
큐 서비스도, 설정할 것도 없습니다. 작업은 그것을 발생시킨 변경과 같은
트랜잭션에서 대기열에 들어가므로 충돌이 작업을 잃거나 두 번 보내지
않습니다. QUIRE_QUEUE_DRIVER는 여기서 기본값인 pgboss이며, vercel과
cloudflare는 가벼운 알림·웹훅 전달만 플랫폼 자체 큐로 옮깁니다. Vercel과
Cloudflare 가이드가 그것들과 웹 계층이 어떻게 대기열에 넣는지 설명합니다.
이메일
다음 중 하나를 설정하세요.
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에서 메일을 보세요.
선택적 서비스
| 설정 | 프로필 |
|---|---|
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 대상으로 켜져 있습니다(5자 해시 접두어만 전송); off로 끌 수 있고, URL은 직접 호스팅하는 범위 API를 가리킵니다 |
관측 가능성
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_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 조직이 도달할 수 있는 추가 호스트. 웹훅, xAPI, SIEM 엔드포인트, 블로그 피드, Amazon SES 호스트는 조직의 자체 선택이며 어떤 서비스도 선언하지 않으므로 여기에 속합니다. 루프백, 사주소, web이나 clamav 같은 단일 레이블 이름은 자체 네트워크이므로 결코 검사하지 않습니다 |
영국과 미국 조직은 호스트 목록의 구속을 받지 않으며 서비스 지역 검사를
유지합니다. 목록은 워커에 설정하세요. 관리 페이지는 웹 계층에서 이 목록을
읽어 허용 목록을 표시하므로, 모든 서비스가 읽는 docker/.env에 넣으세요.
애플리케이션 검사는 명확한 오류와 감사 항목을 주지만 그것이 보장은
아닙니다. 코드는 틀릴 수 있습니다. 보장은 네트워크입니다. Compose가 대신
강제하지는 않습니다. 지역 스택이라면 worker와 web 서비스를
internal: true 네트워크에 두고, 그 유일한 출구는
QUIRE_EGRESS_ALLOW_HOSTS에 있는 호스트와 구성된 서비스의 호스트를 허용하는
아웃바운드 프록시(예: Squid나 tinyproxy 컨테이너)여야 하며, 그 서비스들에
HTTPS_PROXY를 설정하세요. 거주지 페이지는 애플리케이션이 허용하는 정확한
호스트를 나열하므로 두 목록을 비교할 수 있습니다.
상태 확인
| 엔드포인트 | 의미 |
|---|---|
/healthz |
생존성: 프로세스가 응답하는지. Compose 헬스 체크가 이것을 사용합니다 |
/readyz |
준비성: 의존성에 접근 가능한지, 그리고 각 선택적 서비스가 구성 여부를 보고했는지. 로드 밸런서를 여기에 가리키세요 |
docker compose -f docker/compose.yaml ps가 각 서비스의 상태를 보여줍니다.
TLS
proxy 서비스(Caddy, Apache-2.0, docker/caddy/Caddyfile)는 기본 스택의
일부입니다. 80과 443 포트에 응답하며 라우팅합니다.
| 호스트 또는 경로 | 가는 곳 |
|---|---|
QUIRE_PROXY_CONTENT_HOST |
content |
QUIRE_PROXY_APP_HOST, 모든 테넌트 하위 도메인과 커스텀 도메인 |
web |
그 호스트들의 /_collab/ |
collab(웹소켓, QUIRE_COLLAB_URL) |
그 호스트들의 /_realtime/connection/ |
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.crtquire-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 전에 실행하세요.
자체 리버스 프록시 뒤에서
이미 돌리고 있는 로드 밸런서나 프록시를 대신 쓰려면 proxy를 빼고
(docker compose up -d --scale proxy=0), web(8080), content(8081),
collab(1234, 웹소켓), centrifugo(8000, 웹소켓) 앞에서 TLS를 종료하세요.
공개 주소는 QUIRE_APP_ORIGIN, QUIRE_CONTENT_ORIGIN,
QUIRE_COLLAB_URL(wss://)에, 프록시의 주소 범위는
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는 첫 시작에 시그니처를 내려받으며 몇 분이 걸립니다.