선택의 순간
2025년 초, davhave.com을 만들면서 가장 먼저 맞닥뜨린 질문은 "뭐로 올린다고?" 였다. AWS, GCP, Vercel, Railway 등 선택지는 무한했다. 그런데 생각해보니 내가 원한 건 단순했다:
- 정적 콘텐츠(HTML, CSS, JS) + 블로그 API
- 간단한 이미지 관리
- 관리자 인증만 있으면 됨
- 비용은 최소한으로
그때 Cloudflare는 이미 만든 사이트의 DNS를 호스팅하던 도구였다. 그런데 Workers가 있다는 걸 알았고, "혹시 이걸로 서버를 만들 수 있지 않을까?"라는 궁금증이 시작점이었다.
아키텍처: 가볍게 시작, 필요할 때 추가
┌─────────────────────────┐
│ Cloudflare Workers │ (엣지 컴퓨팅)
│ ├─ /api/* │ (CRUD, 인증)
│ ├─ /blog, /portfolio │ (SSR 페이지)
│ └─ /media/* │ (R2 이미지 프록시)
└────┬────────────────────┘
│
├─ D1 (SQLite) → 블로그/교육 콘텐츠
├─ R2 (Object Store) → 포스트 이미지
└─ env.ASSETS → 정적 HTML/CSS/JS
이 구조의 핵심은 엣지에서 모든 요청을 처리한다는 점이다. 사용자가 일본에서 접속하든, 미국에서 접속하든, Workers는 지리적으로 가장 가까운 데이터센터에서 응답한다. 그 데이터센터가 D1에 접근할 때도 마찬가지다. 글로벌 레이턴시는 자동으로 최적화된다.
실제 구현 — 세 가지 깨달음
1. 로컬 개발 환경의 중요성
첫 두 주간 나는 wrangler를 제대로 이해 못 하고 계속 "음, 왜 변화가 안 보이지?"만 반복했다. 결국 배운 것:
npx wrangler dev
이 명령 하나로 로컬에서 Workers, D1, R2를 전부 시뮬레이션할 수 있다. .dev.vars 파일에 로컬 환경 변수를 넣으면, 개발 중에는 실제 Cloudflare 계정의 시크릿에 접근하지 않아도 된다. 이건 보안과 속도 양쪽에서 큰 이득이다.
2. D1은 SQLite지만 클라우드다
D1을 "SQLite를 클라우드에 올린 것"이라고 생각했다가, 로컬 개발과 실제 배포 사이의 스키마 동기화 문제로 며칠을 날렸다. D1은:
- 마이그레이션 관리가 없다. 수동으로 SQL 스크립트를 실행해야 한다.
- 타임존 문제가 있다. SQLite의 기본 datetime은 UTC인데, 사용자의 로컬 시간대와의 변환을 앱 레벨에서 해야 한다.
- 성능은 예상보다 좋다. 블로그 같은 읽기 위주 워크로드라면 체감상 느린 적이 거의 없다.
결국 src/schema.sql 파일을 관리하고, 프로덕션 변경은 항상 로컬에서 먼저 테스트한 후 --remote 플래그로 반영하는 프로세스를 만들었다.
3. R2는 S3의 편한 버전
초기에 이미지 업로드 API를 만들 때 고민이 많았다. 파일 크기 체크? 포맷 검증? CORS? R2의 가장 좋은 점은 이런 세부사항이 Cloudflare에서 기본으로 처리된다는 것이다.
const uploadedFile = await MEDIA.put(filename, body, {
httpMetadata: {
contentType: 'image/webp',
cacheControl: 'public, max-age=31536000'
}
});
단 세 줄이면 충분하다. S3처럼 IAM 정책을 만들 필요도 없고, SDK 버전 관리도 간단하다.
비용 관점
가장 현실적인 질문은 비용이다. 나는 월 ~$5 정도에 운영하고 있다:
- Workers: 월 10달러 (요청 수 무제한은 아니지만, 개인 블로그에선 무료 티어로 충분)
- D1: 월 $0.75 정도 (읽기 1만 번, 쓰기 100번 기준)
- R2: 월 $0~$2 (이미지 저장소 10GB + 네트워크 이용)
AWS EC2 인스턴스 1개 (t3.micro)를 돌리는 것과 비교하면, 네트워크 대역폭 + 글로벌 배포를 고려할 때 Cloudflare가 훨씬 저렴하다.
마주친 한계들
물론 장점만 있는 건 아니다:
- 콜드 스타트: Workers는 엣지에서 즉시 실행되지만, 코드 번들 크기가 크면 첫 요청이 느려질 수 있다. (현재는 없지만, 알아두면 좋다)
- D1 쿼리 횟수 제한: 무료 티어에선 월 10만 쿼리까지만 가능. 비용을 내면 늘어나지만, 대규모 분석 워크로드에는 맞지 않다.
- 디버깅: wrangler 명령어만으로는 제한적이다. 프로덕션 에러는 Cloudflare 대시보드에서 직접 봐야 한다.
결론: "충분함의 기술"
Cloudflare는 완벽하지 않지만, 개인이나 소규모 팀이 '충분히 빠르고 안정적인' 서비스를 최소 비용으로 만들기에는 최고다. AWS의 모든 기능이 필요하지 않다면, Workers는 오히려 단순함 때문에 더 빠르게 움직일 수 있다.
가장 큰 배움은 "선택지가 많을수록 좋은 게 아니다"는 것. 내게 필요한 것들을 명확히 하고, 그에 딱 맞는 도구를 고르는 게 결과적으로 가장 빠르고 저렴하다.