Cloudflare에 배포하기

이 페이지

Cloudflare Workers는 EmDash를 위한 빠르고 전 세계에 분산된 런타임을 제공합니다. 이 가이드는 데이터베이스로 D1, 미디어 저장소로 R2를 사용하는 배포를 다룹니다.

사전 요구 사항

  • Cloudflare 계정
  • Wrangler CLI 설치(npm install -g wrangler)
  • Cloudflare 로그인 완료(wrangler login)

리소스 만들기

1. D1 데이터베이스 생성

wrangler d1 create emdash-db

출력에서 database_id를 기록합니다.

2. R2 버킷 생성

wrangler r2 bucket create emdash-media

3. wrangler.jsonc 생성

프로젝트 루트에 wrangler.jsonc를 만듭니다.

{
	"$schema": "node_modules/wrangler/config-schema.json",
	"name": "my-emdash-site",
	"compatibility_date": "2025-01-15",
	"compatibility_flags": ["nodejs_compat"],

	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "emdash-db",
			"database_id": "your-database-id",
		},
	],

	"r2_buckets": [
		{
			"binding": "MEDIA",
			"bucket_name": "emdash-media",
		},
	],
}

EmDash 구성

Astro 설정을 D1과 R2를 쓰도록 업데이트합니다.

import { defineConfig } from "astro/config";
import cloudflare from "@astrojs/cloudflare";
import emdash from "emdash/astro";
import { d1, r2 } from "@emdash-cms/cloudflare";

export default defineConfig({
	output: "server",
	adapter: cloudflare(),
	integrations: [
		emdash({
			database: d1({ binding: "DB" }),
			storage: r2({ binding: "MEDIA" }),
		}),
	],
});

마이그레이션 실행

데이터베이스 스키마를 생성하고 적용합니다.

1. 스키마 SQL보내기

npx emdash init --database ./data.db

2. D1에 마이그레이션 적용

wrangler d1 migrations apply emdash-db

마이그레이션 파일이 없으면 코어 스키마를 직접 적용합니다.

wrangler d1 execute emdash-db --file=./node_modules/emdash/migrations/0001_core.sql

배포

Cloudflare Workers에 배포합니다.

wrangler deploy

사이트는 https://my-emdash-site.<your-subdomain>.workers.dev에서 제공됩니다.

읽기 복제본

전 세계에 분산된 사이트의 경우 D1 읽기 복제를 켜면 읽기 쿼리가 항상 기본 데이터베이스가 아니라 가까운 복제본으로 라우팅됩니다. 기본 리전에서 먼 방문자의 지연 시간이 크게 줄어듭니다.

emdash({
	database: d1({
		binding: "DB",
		session: "auto",
	}),
	storage: r2({ binding: "MEDIA" }),
}),

D1 데이터베이스 자체에 대해서도 Cloudflare 대시보드 또는 REST API에서 읽기 복제를 활성화해야 합니다.

세션 모드와 북마크 기반 일관성은 데이터베이스 옵션 — 읽기 복제본을 참조하세요.

사용자 지정 도메인

Cloudflare 대시보드에서 사용자 지정 도메인을 추가합니다.

  1. Workers & Pages > 해당 Worker
  2. Custom Domains > Add Custom Domain
  3. 도메인을 입력하고 DNS 안내를 따릅니다

R2 공개 액세스

미디어를 R2에서 직접 제공하려면(성능상 권장):

  1. Cloudflare 대시보드에서 R2 > 해당 버킷
  2. Settings > Public access
  3. 공개 액세스를 켜고 공개 URL을 기록
  4. 스토리지 설정 업데이트:
storage: r2({
  binding: "MEDIA",
  publicUrl: "https://pub-xxx.r2.dev"
}),

Cloudflare Access 인증

조직에서 Cloudflare Access를 사용하는 경우 패스키 대신 인증 공급자로 사용할 수 있습니다. 기존 IdP와 SSO를 제공합니다.

emdash({
  database: d1({ binding: "DB" }),
  storage: r2({ binding: "MEDIA" }),
  auth: access({
    teamDomain: "myteam.cloudflareaccess.com",
    audience: "your-app-audience-tag",
    roleMapping: {
      "Admins": 50,
      "Editors": 40,
    },
  }),
}),

전체 구성 옵션은 인증 가이드를 참조하세요.

환경 변수

EmDash는 인증과 미리보기 기능에 특정 시크릿이 필요합니다.

필수 시크릿

변수용도
EMDASH_AUTH_SECRET세션 쿠키와 인증 토큰 서명. 프로덕션에 필수.
EMDASH_PREVIEW_SECRET초안 미리보기 URL 서명. 미리보기에 필수.

안전한 시크릿 생성:

npx emdash auth secret

Wrangler로 시크릿 설정:

wrangler secret put EMDASH_AUTH_SECRET
wrangler secret put EMDASH_PREVIEW_SECRET

설정에서는 import.meta.env 또는 Cloudflare env 바인딩으로 환경 변수에 액세스합니다.

프리뷰 배포

프리뷰 브랜치 배포:

wrangler deploy --env preview

wrangler.jsonc에 환경 섹션 추가:

{
	"env": {
		"preview": {
			"d1_databases": [
				{
					"binding": "DB",
					"database_name": "emdash-db-preview",
					"database_id": "your-preview-db-id",
				},
			],
		},
	},
}

문제 해결

”D1 binding not found”

wrangler.jsonc의 바인딩 이름이 데이터베이스 구성과 일치하는지 확인하세요.

// 일치해야 함: d1({ binding: "DB" })
"binding": "DB"

”R2 binding not found”

R2 버킷이 올바르게 바인딩되었는지 확인하세요.

// 일치해야 함: r2({ binding: "MEDIA" })
"binding": "MEDIA"

마이그레이션 오류

D1 마이그레이션은 런타임이 아니라 Wrangler로 실행됩니다. 스키마 오류가 있으면:

  1. 마이그레이션 적용 여부 확인: wrangler d1 migrations list emdash-db
  2. 필요 시 다시 적용: wrangler d1 migrations apply emdash-db