---
title: "Cloudflare Workers 위의 웹 계층"
description: "Cloudflare Workers에서 축소된 Quire 웹 계층 실행하기."
image: "https://docs.quirelms.com/og.png"
---

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

# Cloudflare Workers 위의 웹 계층

<span id="the-web-tier-on-cloudflare-workers"></span>

설계는 `docs/architecture/23-ops.md` 6절입니다. Workers는 축소된 웹 계층을
실행합니다. Workers에서의 기능 동등성은 범위 밖입니다(PRD 12절). 이 타깃이
할 수 없는 것은 시작할 때 이름을 밝히며 거부됩니다.

## 이번 릴리스의 상태 <!--quire:status-in-this-release-->

설정은 준비되어 있습니다(`apps/web/wrangler.jsonc`, `cloudflare-module`
Nitro 프리셋, Hyperdrive 브리지, 시작 점검). Worker에는 R2용 S3 호환 저장소
(`QUIRE_STORAGE_DRIVER=s3`), 요청 전반의 실시간 드라이버
(`QUIRE_REALTIME_DRIVER=durable_objects` 또는 `centrifugo`), 공유 캐시
(`QUIRE_CACHE_DRIVER=postgres` 또는 `valkey`), HTTP 이메일 공급자가
필요합니다. 없으면 Worker는 시작을 거부하고 로그에 각 설정을 명시합니다.
Durable Objects 드라이버는 `apps/realtime-worker`의 실시간 Worker를 클라이언트로
사용합니다(채널마다 하나의 Durable Object가 팬아웃·프레즌스·히스토리를,
사람마다 하나가 끊김을 담당합니다). 아래와 같이 함께 배포하거나 Centrifugo를
사용하세요.

## 구성 요소 <!--quire:the-pieces-->

| 요소 | Cloudflare 위에서 |
| --- | --- |
| `web` | `nodejs_compat`가 있는 Worker |
| Postgres | 외부, Hyperdrive로 접근: 애플리케이션 역할은 `HYPERDRIVE`, 같은 물리 데이터베이스의 리포트 역할은 `REPORT_HYPERDRIVE`. 웹 계층은 시작할 때 각 연결 문자열을 `DATABASE_URL`과 `QUIRE_REPORT_DATABASE_URL`에 복사합니다 |
| 파일 | R2, S3 API를 통해(`S3_ENDPOINT=https://<account>.r2.cloudflarestorage.com`); `FILES` 바인딩이 버킷을 연결합니다 |
| 백그라운드 작업 | 쓰기가 필요한 대기열 등록이면 Hyperdrive 위의 pg-boss. 동반 워커에 `QUIRE_QUEUE_DRIVER=cloudflare`를 쓰면 가벼운 작업(순서 없는 알림·웹훅 전달)은 대신 Cloudflare Queues로 가므로 Postgres를 폴링하지 않습니다. 동반 워커가 둘 다 실행합니다 |
| 실시간 | Durable Objects가 있는 실시간 Worker `apps/realtime-worker` |
| `worker`, `scheduler`, `collab`, `content`, ClamAV, Gotenberg, ffmpeg | 동반 컨테이너 호스트. Worker는 실행할 수 없습니다 |
| 추적 | `wrangler.jsonc`에서 켜는 Workers 관측 가능성 |

`REPORT_HYPERDRIVE`는 `HYPERDRIVE`가 가리키는 물리 데이터베이스의 리포트
역할을 제공합니다. 이 타깃은 아래에 설명한 대로 추가 물리 데이터베이스에
고정된 테넌트를 서비스하지 않습니다.

## 이 타깃이 할 수 없는 것 <!--quire:what-this-target-cannot-do-->

시작 시 거부되며, 모든 문제를 한 번에 나열합니다.

- **SMTP 없음.** `QUIRE_EMAIL_PROVIDER_CONFIG`에 HTTP 공급자를 사용하세요.
- **로컬 디스크 없음.** `QUIRE_STORAGE_DRIVER`는 객체 저장소를 지정해야
  합니다.
- **인프로세스 실시간·캐시 없음.** Worker는 요청 사이에 메모리를 공유하지
  않으므로 `QUIRE_REALTIME_DRIVER=inprocess`와 `QUIRE_CACHE_DRIVER=memory`는
  거부됩니다.
- **Worker에 ClamAV, Gotenberg, ffmpeg 없음.** Worker에 설정된 `CLAMAV_URL`,
  `GOTENBERG_URL`, `FFMPEG_PATH`는 거부됩니다. 대신 동반 워커에 설정하세요.
- **전용 데이터베이스 조직 없음.** Worker의 Hyperdrive 바인딩은 배포 시점에
  고정되므로 자체 데이터베이스를 가진 조직은 명확한 "여기서는 사용할 수
  없습니다" 페이지를 받습니다. Compose나 Vercel에서 서비스하세요.

거부되지는 않지만 알아야 할 한 가지: **프리렌더링과 증분 정적 재생성은
Workers에서 동작하지 않습니다.** 프레임워크 문서가 뭐라고 하든 모든 라우트는
요청마다 렌더링됩니다.

이 타깃에서는 트랜잭션을 짧게 유지하고 네트워크 호출을 가로질러 절대
유지하지 마세요. Hyperdrive는 연결이 풀로 돌아갈 때 세션 상태를 초기화하므로
테넌트 컨텍스트는 트랜잭션마다 설정됩니다.

## 배포 <!--quire:deploying-->

1. 자원을 만드세요.
   ```sh
   bun run --bun wrangler hyperdrive create quire-app --connection-string="postgres://quire_app:...@db.example.com:5432/quire"
   bun run --bun wrangler hyperdrive create quire-report --connection-string="postgres://quire_report:...@db.example.com:5432/quire"
   bun run --bun wrangler r2 bucket create quire-files
   bun run --bun wrangler queues create quire-jobs
   ```
   두 Hyperdrive ID를 `apps/web/wrangler.jsonc`에 넣으세요.
2. 시크릿을 하나씩 `bun run --bun wrangler secret put <NAME>`으로 설정하세요.
   `apps/web`에서 다음을 설정합니다. `QUIRE_SECRET_KEY`, `QUIRE_MASTER_KEY`,
   `QUIRE_EMAIL_PROVIDER_CONFIG`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`,
   `QUIRE_COLLAB_SIGNING_KEY`, `QUIRE_REALTIME_WORKER_SECRET`. 일반 설정
   (`QUIRE_APP_ORIGIN`, `QUIRE_CONTENT_ORIGIN`, `QUIRE_PLATFORM_DOMAINS`,
   `QUIRE_DATABASE_ID`, `S3_ENDPOINT`, `S3_BUCKET`, `QUIRE_COLLAB_URL`)은
   `vars`에 넣습니다.
3. `apps/web`에서 빌드하고 배포하세요.
   ```sh
   NITRO_PRESET=cloudflare-module bun run build
   bun run --bun wrangler deploy
   ```
4. 실시간 Worker를 배포하세요. 웹 계층의 `QUIRE_REALTIME_WORKER_SECRET`와,
   토큰 시크릿을 `QUIRE_REALTIME_TOKEN_SECRET`로 줍니다(웹 계층은 실시간
   토큰에 자체 `QUIRE_REALTIME_TOKEN_SECRET`로, 그것이 없으면
   `QUIRE_SECRET_KEY`로 서명하므로 쓰는 쪽을 사용하세요). 그리고 웹 계층에
   `QUIRE_REALTIME_WORKER_URL`을 그 주소로 설정하세요.
   ```sh
   cd apps/realtime-worker
   bun run --bun wrangler secret put QUIRE_REALTIME_WORKER_SECRET
   bun run --bun wrangler secret put QUIRE_REALTIME_TOKEN_SECRET
   bun run --bun wrangler deploy
   ```
5. Cloudflare Queues의 가벼운 작업을 위해서는 가벼운 큐마다 하나씩 큐를
   만들고, 동반 워커에 다음을 설정하세요(Queues 읽기·쓰기가 있는 API
   토큰).
   ```sh
   bun run --bun wrangler queues create quire-events-notifications
   bun run --bun wrangler queues create quire-events-notifications-dead
   bun run --bun wrangler queues create quire-events-webhooks
   bun run --bun wrangler queues create quire-events-webhooks-dead
   ```
   `QUIRE_QUEUE_DRIVER=cloudflare`, `CLOUDFLARE_ACCOUNT_ID`,
   `CLOUDFLARE_QUEUES_TOKEN`, 그리고 `QUIRE_QUEUE_PREFIX`는 기본값(`quire-`)이 아닐 때만 설정합니다.
6. [Vercel 가이드](/ko/ops/vercel/)의 3단계처럼 동반 호스트를 실행하세요.
   마이그레이션은 각 배포 전에 거기서 실행됩니다.

거부된 설정은 `bun run --bun wrangler tail`에서 "The web tier did
not start on cloudflare"로 보이고, 이어서 바꿀 설정이 나옵니다.

Source: https://docs.quirelms.com/ko/ops/cloudflare/index.mdx
