바이브 코딩으로 Cloudflare에서 홈페이지 만들기 완전 가이드 2026
Astro와 Cloudflare Pages 또는 Workers Static Assets를 기본 골격으로 두고, Workers, D1, R2, KV, Turso, Wrangler CLI를 AI와 함께 설정해 개인 홈페이지, 포트폴리오, 자영업자 사이트까지 실제 공개하는 흐름을 정리했습니다.
01
작게 공개
정적 페이지부터 배포
02
필요할 때 확장
API, DB, 파일 저장소 연결
03
권한은 사람이 통제
AI는 계획과 구현을 담당
Cloudflare Stack Map
이 글에서 쓰는 Cloudflare·보완 서비스 한눈에
필수 Cloudflare 서비스와 Turso 같은 보완 서비스를 먼저 구분해 두면, 뒤에서 나오는 D1, R2, KV, Workers 바인딩 설명이 훨씬 쉽게 읽힙니다.
| 구분 | 서비스 | 역할 | 이 글에서 쓰는 곳 | 핵심 특징 | 공식 문서 |
|---|---|---|---|---|---|
| 필수 | Workers | 서버 코드와 API 실행 | 문의 폼 처리, SSR, 웹훅, 외부 API 중계, 간단한 관리자 API | 전 세계 Cloudflare 네트워크에서 실행되는 서버리스 런타임. Node 서버와 달라 파일 시스템과 일부 Node 전용 패키지는 주의합니다. | Workers docs |
| 필수 | Workers Static Assets / Pages | 정적 사이트 배포 | 홈, 소개, 포트폴리오, 칼럼, 매장 안내, 랜딩 페이지 | HTML, CSS, 이미지, JS를 Cloudflare CDN에 올립니다. 기존 Pages는 계속 활용하고, 신규 프로젝트는 Static Assets 흐름을 함께 검토합니다. | Static Assets docs |
| 필수 | Wrangler CLI | 생성·설정·배포 도구 | 로그인, D1/R2/KV 생성, 로컬 실행, preview/production 배포 | Cloudflare 작업의 리모컨입니다. AI가 명령을 제안하고 사람이 승인하는 루프를 만들 때 핵심 도구가 됩니다. | Wrangler docs |
| 필수 | Bindings & Secrets | 코드와 리소스 연결 | env.DB, env.MEDIA, env.SITE_FLAGS, API 키, 운영 비밀값 관리 | D1/R2/KV 같은 리소스를 코드의 env 이름으로 연결합니다. 이름이 틀리면 배포 후 런타임에서 깨지므로 표로 관리해야 합니다. | Bindings docs |
| 필요 시 | D1 | 서버리스 SQL DB | 문의, 예약, 게시글 메타데이터, 포트폴리오 항목, 작은 CRM | SQLite 계열입니다. rows read/write와 인덱스 설계가 비용과 성능에 직접 연결됩니다. | D1 docs |
| 운영 보완 | Turso | D1 보완 SQL DB | 방문 로그, 이벤트 누적, 통계 집계처럼 행 수가 빠르게 늘어나는 데이터 | Cloudflare 서비스는 아니지만 libSQL/SQLite 계열이라 D1과 사고방식이 비슷합니다. 네이티브 바인딩 대신 HTTP/SDK와 secret 관리가 필요합니다. | Turso docs |
| 필요 시 | R2 | 오브젝트 저장소 | 이미지 원본, 첨부파일, PDF, 다운로드 자료, 백업 파일 | S3 호환 저장소이며 인터넷 egress 무료가 강점입니다. 공개/비공개 접근 정책과 operation 비용을 함께 봅니다. | R2 docs |
| 필요 시 | KV | 빠른 key-value 저장소 | 공지 배너, 기능 플래그, 리다이렉트, 읽기 많은 설정값 | 자주 읽고 가끔 바뀌는 값에 적합합니다. 결과적 일관성이므로 결제 상태나 재고 원본 저장소로는 피합니다. | KV docs |
| 확장 | Durable Objects | 상태 저장 조정 계층 | 채팅방, 협업 편집, 실시간 방, 분산 락, 카운터 | 특정 ID의 상태를 하나의 객체로 모읍니다. 일반 홈페이지 초반에는 선택 사항이고 실시간 기능이 생길 때 고려합니다. | DO docs |
| 확장 | Queues | 비동기 작업 큐 | 메일 발송, 이미지 후처리, 외부 API 재시도, 예약 알림 | 사용자 요청 안에서 오래 걸리는 일을 뒤로 넘깁니다. 중복 처리와 재시도 설계를 함께 해야 합니다. | Queues docs |
| 확장 | Hyperdrive | 외부 DB 연결 가속 | D1 대신 외부 Postgres/MySQL이 필요한 프로젝트 | Cloudflare-only는 아니지만 Supabase, Neon, PlanetScale 같은 외부 DB와 Workers를 연결할 때 현실적인 우회로가 됩니다. | Hyperdrive docs |
읽기 전에
이 글은 실제 비밀값, 계정 ID, 결제 정보, 운영 토큰을 공개하지 않는 방식으로 설명합니다. 명령 예시는 흐름을 이해하기 위한 기본형이며, 실행 전에는 현재 프로젝트의 package.json, wrangler 설정, Cloudflare 공식 문서를 함께 확인하세요.
Cloudflare-first | 이전 스택과 다른 제작 기준
예전 홈페이지 제작 가이드는 Next.js, Vercel, Supabase 조합을 기준으로 설명하는 경우가 많았습니다. 그 조합도 여전히 훌륭하지만, 개인 사이트나 작은 비즈니스 사이트에서는 호스팅, API, DB, 이미지 저장소, 캐시, 도메인, SSL을 한 곳에서 다루는 Cloudflare-first 흐름이 점점 더 편해졌습니다.
이 글의 기준은 현재 사이트와 잘 맞는 Astro + Cloudflare Pages + Functions 구조입니다. 콘텐츠 페이지는 빠르게 정적으로 만들고, 필요한 부분만 Workers, D1, R2, KV로 확장합니다. AI에게는 반복 작업과 설정 초안을 맡기되, 계정 권한과 비밀값은 사람이 통제하는 방식으로 진행합니다.
핵심 관점
처음부터 거대한 서비스를 만들지 않습니다. 공개 페이지를 먼저 만들고, 진짜 필요한 기능만 Cloudflare 서비스로 하나씩 붙이는 것이 바이브 코딩과 가장 잘 맞습니다.
- 정적 페이지는 Pages에 올려 빠르게 제공한다.
- 문의 폼, 예약, 작은 API는 Pages Functions 또는 Workers로 처리한다.
- 게시글, 신청 내역, 포트폴리오 데이터는 D1에 저장한다.
- 이미지와 다운로드 파일은 R2에 두고, 설정값과 플래그는 KV에 둔다.
사이트 범위 | 개인·포트폴리오·자영업자 기준
AI에게 "홈페이지 만들어줘"라고만 말하면 예쁜 첫 화면은 나올 수 있지만 운영 가능한 사이트가 되기는 어렵습니다. 먼저 방문자가 무엇을 해야 하는지 한 문장으로 정해야 합니다. 예를 들어 "내 작업물을 보고 연락하게 한다", "매장 정보를 확인하고 예약하게 한다", "글을 읽고 뉴스레터를 신청하게 한다"처럼 말입니다.
Cloudflare 조합은 이 작은 목표를 빠르게 공개하고, 트래픽이 생기면 기능을 늘리는 방식에 강합니다. 그래서 처음 설계할 때부터 데이터와 파일을 어디에 둘지 가볍게 정해 두면, 나중에 AI가 코드를 늘려도 구조가 흐트러지지 않습니다.
| 유형 | 첫 화면 목표 | 처음 붙일 기능 |
|---|---|---|
| 개인 홈페이지 | 누구인지 5초 안에 전달 | 소개, 링크, 글 목록 |
| 포트폴리오 | 대표 작업물을 바로 확인 | 프로젝트 상세, 문의 폼 |
| 자영업자 사이트 | 방문, 예약, 문의로 연결 | 위치, 영업시간, 메뉴, 전화 버튼 |
| 작은 웹앱 | 한 가지 문제를 바로 해결 | 입력 폼, 결과 저장, 관리자 확인 |
도메인·DNS·SSL | 초반 연결 안정화
Cloudflare에서 도메인을 관리하면 DNS, SSL, 캐시, 보안 설정을 같은 대시보드에서 확인할 수 있습니다. Pages 프로젝트를 만들고 나면 기본 배포 주소가 생기고, 나중에 커스텀 도메인을 연결해 실제 주소로 공개합니다.
AI에게 DNS 설정을 맡길 때는 계정 화면을 직접 열어 조작하게 하기보다, 현재 레코드 목록을 사람이 확인한 뒤 "어떤 레코드를 추가해야 하는지 계획만 제시해 달라"고 요청하는 편이 안전합니다. 특히 기존 메일, 블로그, 서브도메인을 쓰고 있다면 무심코 지우면 안 됩니다.
- 루트 도메인과 www 서브도메인을 모두 쓸지 정한다.
- 기존 MX, TXT, SPF, DKIM 레코드는 메일과 인증에 연결되어 있으므로 삭제하지 않는다.
- SSL은 기본값으로 시작하되 외부 원본 서버가 있다면 모드를 다시 확인한다.
- 새 사이트 공개 전에는 임시 Pages 주소로 먼저 QA한다.
Wrangler CLI | Cloudflare 작업 리모컨
Wrangler는 Cloudflare Workers, Pages, D1, R2, KV를 터미널에서 만들고 배포하는 CLI입니다. 바이브 코딩을 제대로 쓰려면 AI가 "어떤 명령을 실행해야 하는지" 설명하고, 사용자가 승인한 명령만 실행되는 루틴을 만드는 것이 좋습니다.
처음에는 로그인과 현재 계정 확인만 해도 충분합니다. 원격 리소스를 만드는 명령은 비용, 이름 충돌, 권한 문제와 연결될 수 있으니 계획을 확인한 뒤 실행합니다.
- npx wrangler whoami로 로그인 계정과 권한을 먼저 확인한다.
- 프로젝트 이름, DB 이름, 버킷 이름은 나중에 바꾸기 어렵기 때문에 짧고 일관되게 정한다.
- 원격 배포 명령은 로컬 build가 통과한 뒤 실행한다.
- 명령 실패 메시지는 그대로 AI에게 전달하되 토큰, 이메일, 내부 ID는 가린다.
npm create cloudflare@latest my-cloudflare-site
cd my-cloudflare-site
npm run dev
npm run build
npx wrangler whoamiAI 권한 위임 | 비밀값은 맡기지 않는다
AI가 Cloudflare 설정까지 도와주는 흐름은 강력합니다. 하지만 "모두 설정해줘"라는 말은 계정 권한, API 토큰, 데이터 삭제, 배포 변경까지 열어 줄 수 있다는 뜻이기도 합니다. 바이브 코딩에서 가장 중요한 습관은 권한을 작업 단위로 작게 나누는 것입니다.
실전에서는 AI에게 계획, 파일 수정, 명령 제안, 오류 분석을 맡깁니다. 실제 Cloudflare 로그인, API 토큰 생성, 결제 정보, 삭제 명령, 운영 DB 마이그레이션은 사람이 확인합니다. 필요한 경우에도 토큰 값 자체를 채팅에 붙여 넣지 않고 환경 변수나 Pages secrets로 저장합니다.
- API 토큰은 필요한 서비스와 계정 범위만 가진 최소 권한으로 만든다.
- AI에게는 실제 토큰 대신 CLOUDFLARE_API_TOKEN 같은 변수명만 알려 준다.
- 삭제, purge, 원격 migration, production deploy는 실행 전 계획을 먼저 받는다.
- 작업이 끝나면 임시 토큰을 폐기하거나 권한을 줄인다.
목표: Cloudflare Pages + Astro 사이트에 문의 폼을 추가해 주세요.
범위: src/pages/contact.astro, functions/api/contact.ts, D1 migration만 수정하세요.
권한: 파일 수정은 가능하지만 배포, 삭제, 원격 DB 마이그레이션은 먼저 계획을 보여주고 승인받으세요.
비밀값: 실제 API 토큰, Account ID, DB ID는 묻지 말고 placeholder만 사용하세요.
검증: npm run build 결과와 입력값 검증 케이스를 요약해 주세요.Astro·Cloudflare 배포 | 콘텐츠 중심 사이트 골격
홈페이지, 포트폴리오, 칼럼, 매장 소개처럼 읽는 페이지가 많은 사이트는 Astro가 가볍습니다. 기본은 정적 HTML로 만들고, 검색, 계산기, 관리자 일부처럼 동작이 필요한 곳에만 React 컴포넌트를 섬처럼 붙일 수 있습니다.
기존 Cloudflare Pages 프로젝트라면 Astro 빌드 결과물을 그대로 배포하기 좋습니다. 신규 프로젝트라면 Cloudflare가 권장하는 Workers Static Assets 흐름도 함께 검토하세요. 어느 쪽이든 API가 필요해지면 functions 폴더 또는 Workers 쪽으로 확장할 수 있어, 처음부터 백엔드 서버를 크게 운영하지 않아도 됩니다.
- 콘텐츠 페이지는 Astro, 상호작용 UI는 React 컴포넌트로 분리한다.
- 공통 레이아웃, SEO, OpenGraph, 사이트맵은 처음부터 템플릿화한다.
- 이미지, 폰트, 썸네일 경로는 public 또는 R2 기준으로 정리한다.
- 관리자 기능은 공개 페이지와 라우팅을 분리해 사고를 줄인다.
Functions·Workers | 서버 코드 위치 나누기
문의 폼처럼 페이지와 붙어 있는 API는 Pages Functions가 편합니다. 반대로 여러 사이트에서 공통으로 쓰는 API, 예약 알림, 크론 작업, 외부 웹훅 처리처럼 독립적인 기능은 Workers로 분리하는 편이 깔끔합니다.
AI에게 구현을 맡길 때도 "이 기능은 페이지 근처 API인지, 독립 Worker인지 먼저 판단해 달라"고 시키면 폴더 구조가 덜 흐트러집니다. 작은 사이트에서는 처음에 Pages Functions로 시작하고, 반복 작업이 많아질 때 Worker로 떼어내도 늦지 않습니다.
| 기능 | 추천 위치 | 이유 |
|---|---|---|
| 문의 폼 저장 | Pages Functions | 페이지와 입력 UI가 가까움 |
| 이미지 업로드 서명 | Pages Functions 또는 Worker | R2 권한을 서버 쪽에 숨겨야 함 |
| 정기 리포트 생성 | Worker | 스케줄과 백그라운드 작업에 적합 |
| 공통 API 게이트웨이 | Worker | 여러 프론트에서 재사용 가능 |
환경 변수·바인딩 | local·preview·production 맞추기
로컬 개발에서는 .env.local 같은 파일로 값을 읽고, 운영 배포에서는 Cloudflare Pages secrets나 Worker secrets에 저장합니다. 저장소에 올라가는 설정 파일에는 실제 값이 아니라 변수 이름과 예시만 남깁니다.
AI에게 오류를 보여줄 때도 환경 변수 값이 로그에 찍히지 않았는지 먼저 확인합니다. 특히 결제 API, OpenAI API, 이메일 발송 키, Cloudflare 토큰은 한 번 유출되면 바로 폐기하고 다시 만들어야 합니다.
- .env.example에는 키 이름과 설명만 넣고 실제 값은 넣지 않는다.
- Pages secrets는 대시보드나 Wrangler 명령으로 저장한다.
- 클라이언트 코드에 들어가는 변수와 서버 전용 변수를 구분한다.
- 로그에는 요청 본문 전체가 아니라 필요한 상태와 오류 코드만 남긴다.
name = "my-site"
compatibility_date = "2026-05-26"
pages_build_output_dir = "dist"
[[d1_databases]]
binding = "DB"
database_name = "my_site_db"
database_id = "replace-with-dashboard-value"
[[r2_buckets]]
binding = "MEDIA"
bucket_name = "my-site-media"
[[kv_namespaces]]
binding = "SITE_FLAGS"
id = "replace-with-dashboard-value"D1·Turso | 운영 데이터 분담
D1은 SQLite 기반의 Cloudflare 서버리스 데이터베이스입니다. Worker나 Pages Function에서 env.DB처럼 네이티브 바인딩으로 바로 접근하므로, 문의, 예약 신청, 포트폴리오 항목, 공지, 관리자 메모처럼 사이트 동작과 가까운 관계형 데이터에 잘 맞습니다.
다만 D1은 "작은 데이터베이스를 많이 두는" 방향으로 설계된 서비스입니다. 공식 한계 기준으로 Free는 DB당 500MB, Workers Paid는 DB당 10GB이며, 이 10GB 한계는 개별 DB에서 더 늘릴 수 없습니다. 방문 로그, 클릭 이벤트, 인기 순위 원천 로그처럼 행 수가 빠르게 늘어나는 데이터까지 모두 D1에 넣으면 비용과 스캔량 관리가 어려워집니다.
실제 운영 사이트 풋터에 보이는 Turso 병용은 그래서 중요한 단서입니다. Turso는 libSQL/SQLite 계열이라 D1과 사고방식이 비슷하지만 Cloudflare 외부 DB입니다. D1에는 사이트 핵심 메타와 작은 운영 데이터를 두고, Turso에는 누적 통계·로그·이벤트처럼 커지는 데이터를 분리하면 D1의 10GB 한계와 rows read/write 압박을 줄일 수 있습니다.
단, Turso의 Embedded Replicas는 현재 문서상 legacy 기능으로 안내되고 새 동기화 프로젝트는 Turso Sync 흐름을 보라고 되어 있습니다. Workers에서 Turso를 쓸 때도 Cloudflare 바인딩처럼 자동 연결되는 것이 아니라 URL과 토큰을 secret으로 관리하고 HTTP/SDK로 접근해야 하므로, 보완 DB라는 위치를 분명히 잡아야 합니다.
CDB형 사이트 기준 분담
칼럼·앱 카탈로그·관리 설정처럼 사이트 구조를 이루는 데이터는 D1에, 전체 방문·오늘 방문·인기 앱 순위처럼 계속 누적되는 이벤트성 데이터는 Turso나 Analytics Engine 계열로 분리하는 편이 장기 운영에 안전합니다.
- created_at, updated_at, status 컬럼을 초반부터 둔다.
- 삭제 대신 archived나 status 값을 쓰면 실수 복구가 쉽다.
- 관리자 검색이 필요한 컬럼에는 인덱스를 추가한다.
- 원격 migration 전에는 로컬 DB나 preview 환경에서 먼저 검증한다.
| 저장소 | 역할 | 넣기 좋은 데이터 | 운영 주의점 |
|---|---|---|---|
| D1 | Cloudflare 바인딩으로 바로 붙는 운영 핵심 DB | 문의, 예약, 사이트 메타데이터, 앱 카탈로그, 관리자 설정, 세션처럼 Worker와 가까운 데이터 | DB당 크기 한계와 rows read/write 비용을 보며, 인덱스 없는 전체 스캔을 피한다. |
| Turso | D1 한계를 보완하는 외부 SQLite/libSQL 계열 DB | 방문 로그, 이벤트 누적, 인기 순위 원천 데이터, 사용자별 집계처럼 행 수가 빠르게 늘어나는 데이터 | Cloudflare 네이티브 바인딩은 아니므로 URL·토큰 secret 관리, 네트워크 지연, 장애 분리를 함께 본다. |
| R2 | 파일과 큰 바이너리의 원본 저장소 | 이미지 원본, 생성 이미지 결과물, ZIP 다운로드, PDF, 백업 파일 | DB에는 파일 경로와 메타데이터만 두고, 실제 파일은 R2에 둔다. |
| KV | 빠른 읽기 캐시와 설정 저장소 | 공지 배너, 기능 플래그, 자주 읽는 인기 목록 캐시, 리다이렉트 맵 | 결과적 일관성이므로 예약·결제·원본 로그처럼 즉시 정확해야 하는 값의 원본으로 쓰지 않는다. |
CREATE TABLE inquiries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL,
message TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'new',
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_inquiries_created_at ON inquiries(created_at);R2 | 이미지와 첨부파일 보관
R2는 이미지, 문서, 다운로드 파일처럼 앱 코드와 분리해야 하는 파일에 적합합니다. 포트폴리오 스크린샷, 메뉴판 PDF, 고객 업로드 첨부파일, 칼럼용 원본 이미지를 R2에 두면 코드 저장소가 무거워지지 않습니다.
공개 이미지라면 CDN 캐시와 경로 규칙을 함께 설계하고, 비공개 파일이라면 서명 URL이나 서버 API를 통해 접근하게 합니다. AI에게는 버킷 이름과 폴더 규칙만 알려 주고 실제 접근 키는 secrets로 처리하게 합니다.
- public, original, upload, backup 같은 접두어 규칙을 정한다.
- 이미지는 업로드 시 WebP, AVIF, 썸네일 생성 여부를 결정한다.
- 사용자가 올린 파일은 확장자와 MIME 타입을 서버에서 검증한다.
- 삭제 기능은 관리자 화면에서도 확인 단계를 둔다.
KV | 가벼운 설정과 캐시
KV는 자주 읽고 가끔 바뀌는 값에 잘 맞습니다. 공지 노출 여부, 이벤트 배너, 기능 플래그, 외부 API 응답 캐시, 사이트 설정 같은 값은 D1보다 KV가 단순할 때가 많습니다.
다만 KV를 데이터베이스처럼 모든 주문, 예약, 결제 내역에 쓰는 것은 피하는 편이 좋습니다. 기록성과 관계가 중요한 데이터는 D1, 파일은 R2, 빠른 설정값은 KV처럼 역할을 나누면 AI가 코드를 확장할 때도 판단이 쉬워집니다.
- 운영자가 자주 바꾸는 문구와 플래그는 KV에 둔다.
- 캐시 만료 시간과 갱신 조건을 코드에 명확히 남긴다.
- 중요 거래 데이터는 D1에 저장하고 KV에는 복사본이나 캐시만 둔다.
- preview와 production namespace를 분리한다.
프롬프트 루프 | 기능 단위로 짧게 끊기
바이브 코딩의 장점은 속도지만, 한 번에 너무 많이 맡기면 구조가 금방 흐려집니다. "전체 사이트를 만들어줘"보다 "홈 화면의 섹션 구조를 잡아줘", "문의 폼을 D1에 저장해줘", "R2 이미지 업로드 API를 설계해줘"처럼 단위를 나누면 결과가 안정적입니다.
AI에게 매번 목표, 수정 범위, 건드리지 말 파일, 실행 가능한 명령, 검증 방법을 알려 주세요. 그러면 사람은 기획과 승인에 집중하고, AI는 반복 구현과 오류 수정을 빠르게 맡을 수 있습니다.
- 처음 요청은 계획만, 두 번째 요청은 파일 수정, 세 번째 요청은 검증으로 나눈다.
- 기존 공통 레이아웃, 버튼, 카드, SEO 컴포넌트를 먼저 찾게 한다.
- 새 패키지 설치 전에는 왜 필요한지 설명하게 한다.
- 작업 후에는 변경 파일, 테스트 결과, 남은 위험을 요약하게 한다.
첫 화면 템플릿 | 전환 목표에 맞추기
개인 홈페이지는 자기소개가 아니라 "무엇을 도와줄 수 있는 사람인지"가 먼저 보여야 합니다. 포트폴리오는 프로젝트 이미지와 성과가 먼저고, 자영업자 사이트는 전화, 길찾기, 예약, 영업시간이 먼저입니다.
AI에게 디자인을 맡길 때도 예쁜 문장보다 사용자의 다음 행동을 명시하는 것이 좋습니다. "모바일 첫 화면에서 전화 버튼과 위치 버튼이 보여야 한다"처럼 구체적으로 말하면 결과물이 훨씬 실제 사이트에 가까워집니다.
개인 홈페이지
소개, 글 목록, 연락처, 링크 허브를 먼저 만들고 나중에 뉴스레터나 자료실을 붙입니다.
포트폴리오
프로젝트 카드, 작업 과정, 기술 스택, 성과 수치, 문의 폼을 핵심 전환 흐름으로 묶습니다.
자영업자 사이트
영업시간, 위치, 메뉴, 예약, 문의, 리뷰, 자주 묻는 질문을 모바일 첫 화면에서 바로 찾게 합니다.
작은 웹앱
계산기, 신청 폼, 예약 확인, 간단한 관리자 화면처럼 한 가지 일을 빠르게 끝내는 도구에 맞습니다.
로컬 검증 | dev·build·preview 반복
AI가 코드를 고친 뒤에는 바로 배포하지 말고 로컬에서 dev 서버로 화면을 보고, build로 정적 산출물이 만들어지는지 확인하고, 가능하면 preview 환경까지 확인합니다. 특히 Cloudflare 바인딩은 로컬과 원격에서 차이가 날 수 있으므로, 어떤 값이 어느 환경에서 주입되는지 표로 남겨 두면 좋습니다.
오류가 나면 전체 로그를 다 붙이지 말고 처음 실패한 명령, 핵심 에러 20줄, 변경한 파일 목록을 AI에게 전달하세요. 그 정도면 대부분의 문제는 원인을 좁힐 수 있습니다.
- npm run dev에서 화면 동작을 확인한다.
- npm run build가 통과해야 Pages 배포를 생각한다.
- 바인딩이 필요한 API는 Wrangler 기반 로컬 실행이나 preview 환경에서 확인한다.
- production 배포는 마지막 한 번만 실행하는 습관을 만든다.
npx wrangler login
npx wrangler d1 create my_site_db
npx wrangler d1 migrations create my_site_db init
npx wrangler r2 bucket create my-site-media
npx wrangler kv namespace create SITE_FLAGS
npx wrangler pages deploy dist --project-name my-site --branch main배포 흐름 | GitHub 연결 또는 CLI 선택
처음 운영하는 사람에게는 GitHub 저장소를 Cloudflare에 연결해 main 브랜치가 배포되게 만드는 흐름이 편합니다. 기존 Pages 프로젝트는 Pages 설정을 그대로 쓰고, 새로 시작하는 프로젝트는 Workers Static Assets와 Wrangler 배포 흐름까지 함께 비교하면 현재 Cloudflare 방향과 더 잘 맞습니다.
중요한 것은 한 프로젝트에서 배포 루트를 섞지 않는 것입니다. GitHub 자동 배포를 쓰면 커밋 중심으로 운영하고, CLI 배포를 쓰면 어느 브랜치와 산출물을 올렸는지 로그를 남기세요. AI에게 배포를 맡길 때도 build와 deploy를 분리해 실패 지점을 알 수 있게 해야 합니다.
- 빌드 명령, 출력 폴더, Node 버전, 환경 변수를 배포 설정에 명확히 둔다.
- preview branch에서 먼저 확인하고 production branch로 합친다.
- 커스텀 도메인 연결 뒤 canonical URL과 사이트맵을 확인한다.
- 배포 후 주요 페이지, 문의 폼, 이미지, OpenGraph 미리보기를 점검한다.
공개 품질 | SEO·접근성·성능 기본값
홈페이지가 검색에 나오려면 title, description, canonical, OpenGraph, sitemap, robots, 구조화 데이터가 필요합니다. 이 요소들은 나중에 한 번에 붙이는 것보다 공통 레이아웃과 페이지 템플릿에 넣어 두는 편이 낫습니다.
접근성은 복잡한 규칙처럼 보이지만 기본은 분명합니다. 버튼은 버튼으로 만들고, 이미지에는 대체 텍스트를 두고, 색 대비를 지키고, 모바일에서 글자가 겹치지 않게 만듭니다. AI에게도 "모바일 360px에서 텍스트 겹침을 확인해 달라"고 지시하면 좋습니다.
- 각 페이지마다 고유 title과 description을 둔다.
- 주요 이미지는 실제 내용을 보여주고 흐릿한 장식 이미지로 대체하지 않는다.
- Lighthouse 또는 브라우저 개발자 도구로 접근성 경고를 확인한다.
- 검색 색인 전에는 sitemap과 canonical URL이 실제 공개 주소를 가리키는지 본다.
운영 습관 | 백업·로그·비용 관리
작은 사이트도 문의 데이터와 이미지가 쌓이면 운영 자산이 됩니다. D1 스키마 변경 기록, R2 버킷 구조, KV 키 목록, 배포 환경 변수는 문서로 남겨야 합니다. AI가 만든 설정이라도 사람이 이해할 수 있어야 유지보수가 됩니다.
비용은 서비스별 무료 한도와 실제 사용량에 따라 달라집니다. 정확한 한도와 과금 조건은 Cloudflare 대시보드와 공식 문서를 기준으로 확인하고, 알림이나 사용량 점검 루틴을 만들어 두세요.
- 운영 DB migration은 날짜와 목적을 파일명에 남긴다.
- R2 원본 파일은 삭제 정책과 백업 주기를 정한다.
- 로그에는 개인정보와 토큰을 남기지 않는다.
- 월 1회 사용량, 오류 로그, 검색 노출, 문의 전환을 점검한다.
문제 해결 | 연결 지점부터 좁히기
Cloudflare 기반 사이트에서 초보자가 자주 만나는 문제는 빌드 산출물 경로, 바인딩 이름 불일치, 환경 변수 누락, CORS, 캐시, DNS 전파 지연입니다. AI에게 오류를 맡길 때는 "이 문제가 프론트, 빌드, Cloudflare 설정, 런타임 중 어디에 가까운지 먼저 분류해 달라"고 요청하세요.
문제를 고칠 때는 한 번에 하나씩 바꿉니다. DNS와 코드와 환경 변수를 동시에 바꾸면 무엇이 해결했는지 알 수 없습니다. 작은 변경, 재현, 검증, 기록의 반복이 장기적으로 가장 빠릅니다.
| 증상 | 먼저 볼 곳 | AI에게 줄 정보 |
|---|---|---|
| 배포는 됐는데 404 | 출력 폴더와 라우팅 | 빌드 명령, dist 구조, Pages 설정 |
| API에서 DB 오류 | D1 바인딩 이름 | wrangler 설정, 함수 파일, 오류 메시지 |
| 이미지가 안 보임 | R2 공개 경로와 권한 | 요청 URL, 응답 코드, 버킷 정책 |
| 도메인이 안 열림 | DNS와 SSL 상태 | 레코드 종류, 연결한 Pages 프로젝트 |
가격 비교 | Cloudflare·Vercel·Supabase 같은 줄에 놓기
가격 비교는 "어디가 무조건 싸다"로 끝내면 위험합니다. Cloudflare는 Pages, Workers, D1, R2, KV가 각각 사용량 기준으로 움직이고, Vercel은 프론트 배포와 Next.js 경험이 강하며, Supabase는 Postgres, Auth, Storage, Realtime이 한 제품 경험으로 묶여 있습니다.
개인 홈페이지, 포트폴리오, 자영업자 소개 사이트처럼 정적 페이지가 많고 API가 작다면 Cloudflare가 매우 유리할 가능성이 큽니다. 반대로 로그인, 권한, 실시간 기능, 복잡한 SQL, 관리자 DB 작업이 많다면 Supabase의 통합 경험이 더 빠를 수 있고, Next.js 중심의 제품이라면 Vercel이 배포 경험에서 가장 단순할 수 있습니다.
Cloudflare에서 특히 헷갈리는 지점은 "정적 자산 요청"과 "함수 요청"이 다르게 계산된다는 점입니다. Pages의 정적 asset 요청은 무료·무제한으로 안내되지만, Pages Functions를 호출하는 순간 그 요청은 Workers 요청 한도에 들어갑니다. Free라면 하루 100,000 Workers 요청을 Pages Functions와 Workers가 함께 나눠 쓰는 식입니다.
Workers CPU도 무료와 유료를 구분해야 합니다. Free는 HTTP 요청당 10ms CPU가 기본 한도이고, Paid는 기본 30초에서 설정으로 최대 5분까지 올릴 수 있습니다. 네트워크 대기 시간 전체가 CPU로 잡히는 것은 아니지만, 이미지 처리나 큰 JSON 가공처럼 실제 계산이 많은 작업은 이 한도를 의식해야 합니다.
현실적인 결론
정적 콘텐츠와 작은 API 중심이면 Cloudflare, Next.js 배포 경험과 협업이 최우선이면 Vercel, Postgres/Auth/Realtime이 핵심이면 Supabase가 편합니다. 이 글은 "홈페이지를 싸고 빠르게 공개한 뒤 필요한 기능만 붙이는" Cloudflare-first 전략에 초점을 둡니다.
- Cloudflare Workers Standard는 월 $5 구독과 요청/CPU 사용량 과금 구조를 함께 본다.
- Pages 정적 파일 요청은 무료·무제한으로 보되, Pages Functions 요청은 Workers 요청 한도와 과금에 들어간다.
- D1은 rows read/write와 저장 용량 기준이며, 데이터 전송 egress는 별도 과금하지 않는다. DB당 10GB 한계는 설계 단계에서 따로 본다.
- KV는 Workers Paid 안에서 read/write/delete/list와 저장 용량 기준으로 과금되며, 읽기 캐시인지 원본 데이터인지 먼저 구분한다.
- R2는 저장 용량과 Class A/B operation을 보되 인터넷 egress가 무료라는 점이 강점이다.
- Supabase는 월 $25 Pro부터 운영 안정성이 좋아지고, DB/Auth/Storage가 편하지만 egress와 storage 초과 비용을 본다.
- Vercel Pro는 월 $20와 포함 크레딧이 있고, Functions/Blob/Image/Analytics 같은 항목별 사용량을 함께 본다.
| 비교 항목 | Cloudflare | Vercel | Supabase |
|---|---|---|---|
| 첫 시작 비용 | Pages 정적 사이트는 무료로 시작 가능. Workers 유료는 월 $5부터이며 사용량 과금이 붙는다. | Hobby는 개인/비상업용 무료, Pro는 월 $20에 포함 크레딧과 팀 기능을 제공한다. | Free는 무료지만 비활성 프로젝트 일시정지가 있고, Pro는 월 $25부터 시작한다. |
| 서버 함수 | Workers Free는 일 100,000 요청, Paid는 요청 100만 건당 $0.30와 CPU 100만 ms당 $0.02 기준으로 본다. | Functions는 active CPU, 메모리, invocation 기준 과금. Next.js 배포 경험은 가장 단순한 편. | Edge Functions는 Free 50만, Pro 200만 호출 포함 후 초과 호출 과금. |
| 데이터베이스 | D1은 rows read/write와 저장 용량 기준. 유휴 시간 과금은 없지만 DB당 10GB 한계가 있어 Turso 병용을 고려한다. | Vercel 자체 DB라기보다 외부 DB 또는 Marketplace 조합이 필요하다. | 전용 Postgres가 기본 제공되어 Auth, Realtime, SQL 생태계가 강하다. |
| 파일 저장 | R2는 저장/작업 과금이고 인터넷 egress가 무료라 이미지·다운로드 파일에 유리하다. | Blob은 저장, operation, data transfer, Edge Request가 함께 비용에 영향을 준다. | Storage는 Pro에서 100GB 포함, 초과 저장과 egress가 과금된다. |
| 운영 난이도 | 서비스별 바인딩과 환경 분리가 필요해 초반 설정이 복잡하다. | GitHub 연결부터 배포까지 매우 편하지만 고급 기능은 항목별 과금이 많다. | DB/Auth/Storage가 한 제품 경험으로 묶여 있어 앱 개발은 쉽지만 egress와 프로젝트 비용을 봐야 한다. |
Cloudflare 단점 | 싸고 강하지만 연결이 복잡하다
Cloudflare 방식의 가장 큰 단점은 "서비스가 잘게 나뉘어 있다"는 점입니다. Pages 프로젝트, Worker, D1 데이터베이스, R2 버킷, KV namespace를 각각 만들고, 그 리소스를 wrangler 설정의 binding으로 코드에 연결해야 합니다.
이 구조는 익숙해지면 깔끔하지만 처음에는 Vercel이나 Supabase보다 덜 친절하게 느껴질 수 있습니다. 특히 AI가 파일은 잘 고쳐도 Cloudflare 대시보드의 실제 리소스 ID와 로컬 설정의 바인딩 이름을 자동으로 완벽히 맞춰 주지는 못합니다.
서비스를 따로 만들고 연결해야 한다
Pages, Workers, D1, R2, KV가 각각 독립 서비스라 초보자는 "DB는 만들었는데 코드가 못 찾는" 상황을 자주 만납니다.
바인딩 이름이 곧 런타임 계약이다
wrangler 설정의 binding = "DB"와 코드의 env.DB가 다르면 로컬에서는 되는 것처럼 보여도 preview나 production에서 깨질 수 있습니다.
환경이 세 갈래로 갈라진다
local, preview, production의 database_id, KV namespace id, secret 값이 달라서 문서화하지 않으면 AI도 사람도 쉽게 헷갈립니다.
D1은 Postgres가 아니라 SQLite 계열이다
작은 운영 데이터에는 편하지만 복잡한 Postgres 확장, 대형 트랜잭션, 기존 Supabase SQL 기능을 그대로 기대하면 안 됩니다. 특히 DB당 10GB 한계가 있으므로 로그성 데이터는 Turso나 Analytics Engine으로 분리하는 판단이 필요합니다.
Pages도 Functions를 쓰면 Workers 과금으로 들어간다
정적 asset 요청은 무료·무제한에 가깝게 볼 수 있지만, Pages Functions를 호출하는 요청은 Workers 요청 한도에 포함됩니다. 정적 페이지와 동적 API를 분리해 생각해야 비용 감각이 맞습니다.
Worker 런타임은 Node 서버와 다르다
Node 전용 패키지, 파일 시스템 접근, 긴 작업, 일부 네이티브 모듈은 그대로 옮기기 어렵습니다.
싸게 보이지만 비용 항목이 쪼개져 있다
Workers 요청/CPU, D1 rows, R2 operation, KV operation이 따로 움직입니다. 작은 사이트에는 유리하지만 계산표 없이 운영하면 감이 흐려집니다.
복사용 프롬프트 | AI에게 바로 줄 지시문
바이브 코딩에서 편의성은 "좋은 프롬프트를 매번 새로 쓰지 않는 것"에서 나옵니다. 아래 프롬프트는 바로 복사해 쓰되, 실제 토큰이나 계정 ID는 넣지 말고 사이트 목표와 기능명만 바꿔 주세요.
중요한 점은 AI가 바로 배포 명령까지 달리지 않게 만드는 것입니다. 계획, 파일 수정, 로컬 검증, 원격 리소스 생성, production 배포를 분리하면 사고 가능성이 크게 줄어듭니다.
1. 사이트 설계 시작
당신은 Astro + Cloudflare Pages/Workers/D1/R2/KV에 익숙한 시니어 웹 개발자입니다.
목표: 개인 홈페이지/포트폴리오/자영업자 사이트 중 하나를 실제 배포 가능한 구조로 설계합니다.
먼저 질문 5개만 해서 사이트 목표, 메뉴, 필요한 데이터, 파일 업로드 여부, 예산 민감도를 확인하세요.
그 다음 IA, 페이지 목록, 데이터 저장소 선택(D1/R2/KV/Turso), 필요한 바인딩과 외부 secret, 구현 순서를 표로 제안하세요.
아직 파일 수정이나 배포 명령은 실행하지 말고 계획만 보여 주세요.2. 첫 화면 구현
이제 계획에 따라 1단계만 구현하세요.
범위: 공통 레이아웃, 홈 화면, SEO 메타, 사이트맵 연결, 모바일 반응형까지입니다.
기존 컴포넌트와 스타일 규칙을 먼저 검색해 재사용하세요.
새 패키지가 필요하면 설치 전에 이유와 대안을 설명하세요.
작업 후 변경 파일, 실행한 검증 명령, 남은 위험을 요약하세요.3. Cloudflare 설정
Cloudflare 설정을 도와주세요.
실제 토큰, Account ID, database_id, namespace id는 채팅에 쓰지 않습니다.
필요한 Wrangler 명령을 계획/생성/적용 순서로 나누고, 원격 리소스 생성과 production deploy는 실행 전 승인 단계로 멈추세요.
wrangler 설정에는 placeholder만 넣고, 사용자가 대시보드에서 바꿔 넣을 위치를 주석으로 표시하세요.
D1/R2/KV 바인딩 이름은 코드에서 사용하는 env 이름과 1:1로 맞춰 주세요.4. 가격 비교 점검
이 사이트의 예상 월 비용을 Cloudflare, Vercel, Supabase 기준으로 비교해 주세요.
조건: 월 방문자 수, 페이지뷰, API 호출 수, D1 rows read/write, Turso rows read/write, R2 저장 용량, R2 다운로드 용량, KV read/write를 내가 입력할 수 있게 표를 먼저 만드세요.
가격은 공식 문서 링크 기준으로 확인하고, 정확히 비교할 수 없는 항목은 "비교 불가/성격 다름"이라고 표시하세요.
Cloudflare가 저렴해 보이는 지점과 운영 복잡도가 늘어나는 지점을 함께 설명하세요.5. 구조 복잡도 진단
현재 프로젝트가 Vercel식 단일 배포 경험과 Cloudflare식 프리미티브 조립 경험 중 어디에 가까운지 진단해 주세요.
반드시 비교할 것: 정적 자산, 서버 함수, SQL DB, 파일 저장소, 캐시/KV, 환경 변수, preview/production 분리, 비용 항목.
Cloudflare를 쓴다면 필요한 리소스(D1/R2/KV/Workers/Static Assets)와 Turso 같은 외부 보완 DB의 secret 이름을 표로 만들고, 왜 그 리소스가 필요한지 한 줄씩 설명하세요.
Vercel이나 Supabase가 더 단순한 경우도 솔직히 말하고, Cloudflare를 고집할 때 생기는 운영 부담과 줄이는 방법을 같이 써 주세요.Vercel vs Cloudflare | 통합 제품과 조립 플랫폼의 차이
Vercel은 개발자가 느끼는 첫 경험을 "저장소를 연결하면 프레임워크를 알아서 배포해 주는 서비스"에 가깝게 설계했습니다. Next.js를 만든 회사답게 빌드, 라우팅, preview URL, 서버 함수, 이미지 최적화, 환경 변수, 협업 흐름이 하나의 제품 경험으로 묶여 있습니다. 그래서 초반에는 코드만 올리면 많은 일이 자동으로 처리되는 느낌이 납니다.
Cloudflare는 출발점이 다릅니다. Cloudflare는 DNS, CDN, 보안, 엣지 네트워크 위에 Workers, Static Assets, D1, R2, KV 같은 작은 인프라 부품을 올려 둔 플랫폼입니다. 따라서 "이 사이트의 정적 파일은 어디에 둘까", "문의 데이터는 D1에 둘까", "이미지는 R2에 둘까", "읽기 많은 설정은 KV가 맞을까"를 개발자가 코드와 설정으로 표현해야 합니다.
즉 Cloudflare가 복잡해 보이는 이유는 같은 일을 더 어렵게 만들어서가 아니라, Vercel이 숨겨 주는 인프라 결정을 개발자가 더 앞단에서 직접 고르게 하기 때문입니다. 이 선택권은 비용과 위치, 캐시, 런타임을 세밀하게 잡을 수 있다는 장점으로 돌아오지만, 초반에는 리소스 생성, 권한, 바인딩, 환경 분리 때문에 번거롭게 느껴집니다.
한 문장으로 정리
Vercel은 프레임워크 앱을 빠르게 배포하는 통합 제품에 가깝고, Cloudflare는 전 세계 네트워크 위의 컴퓨팅·스토리지 부품을 직접 조립하는 개발자 플랫폼에 가깝습니다.
- 처음 공개가 목표라면 Vercel식 통합 경험이 더 편할 수 있다.
- 도메인, CDN, API, 파일, DB, 캐시를 한 네트워크 안에서 직접 통제하려면 Cloudflare식 조립이 강하다.
- AI에게 Cloudflare 작업을 맡길 때는 "리소스 생성"과 "코드 수정"과 "production 배포"를 반드시 분리한다.
- 바인딩 표를 먼저 만들면 Cloudflare 복잡도의 절반은 사라진다.
| 비교 항목 | Vercel식 경험 | Cloudflare식 경험 |
|---|---|---|
| 추상화 단위 | 프로젝트와 프레임워크가 중심입니다. 저장소를 연결하면 Next.js, Remix, Astro 같은 프레임워크를 감지하고 빌드/라우팅/프리뷰를 한 흐름으로 묶어 줍니다. | 인프라 프리미티브가 중심입니다. Workers, Static Assets, D1, R2, KV, Durable Objects를 각각 만들고 코드의 binding으로 연결합니다. |
| 사용자가 처음 묻는 질문 | "어떤 저장소를 배포할까?"에 가깝습니다. 나머지는 플랫폼이 관례에 맞춰 많이 숨겨 줍니다. | "정적 파일은 어디서 서빙하고, API는 어디서 돌리고, 데이터와 파일은 어느 리소스에 둘까?"를 먼저 정해야 합니다. |
| 코드에서 보이는 차이 | 대부분 프레임워크 코드와 환경 변수만 보입니다. 인프라 세부는 대시보드와 플랫폼 기본값 뒤에 숨어 있습니다. | 코드가 env.DB, env.MEDIA, env.SITE_FLAGS처럼 실제 Cloudflare 리소스를 직접 호출합니다. 바인딩 이름이 곧 계약입니다. |
| 장점 | 초기 배포와 협업, preview URL, Next.js 기능 사용이 아주 쉽습니다. 앱을 빨리 보여주기 좋습니다. | 정적 자산, 서버 함수, DB, 파일, 캐시를 Cloudflare 네트워크 가까이에 두고 비용 항목을 세밀하게 통제할 수 있습니다. |
| 단점 | 편한 기본값만으로 충분하지 않은 순간에는 Functions, Blob, Edge Config, 외부 DB, 이미지/분석 비용 항목을 따로 이해해야 합니다. | 처음에는 리소스 생성, 권한, binding, preview/production id, wrangler 설정을 직접 맞춰야 해서 훨씬 번거롭게 느껴집니다. |
Cloudflare 운영 스택 | 핵심·보완 서비스 역할
Cloudflare만으로 사이트를 운영한다는 말은 단일 제품 하나를 켠다는 뜻이 아닙니다. Workers는 계산을 담당하고, Static Assets 또는 Pages는 정적 파일을 서빙하고, D1은 관계형 데이터를 저장하고, R2는 파일을 보관하고, KV는 읽기 많은 작은 설정을 빠르게 내려줍니다. 여기에 실시간 상태가 필요하면 Durable Objects, 오래 걸리는 후처리가 필요하면 Queues, 외부 Postgres/MySQL 연결이 필요하면 Hyperdrive를 더합니다.
이 조합은 개인 홈페이지나 포트폴리오처럼 정적 페이지가 많은 사이트에서 특히 좋습니다. 먼저 Astro로 HTML 중심 화면을 만들고, 문의 폼 하나만 Worker 함수로 처리하며, 문의 내역은 D1에 넣고, 이미지 원본은 R2에 두면 됩니다. 방문자가 늘어나도 대부분의 페이지는 CDN과 정적 자산으로 빠르게 나가고, 동적 요청만 필요한 만큼 비용이 붙습니다.
여기에 도메인·DNS·SSL·WAF·캐시·봇 방어·미디어 변환·분석까지 붙으면 운영 그림이 완성됩니다. Vercel이나 Supabase가 한 제품 안에서 많은 판단을 숨겨 주는 쪽이라면, Cloudflare는 이 주변 계층까지 한 네트워크 안에서 직접 조립하는 쪽입니다.
반대로 "로그인 사용자 수가 많고, 권한이 복잡하고, Postgres 확장 기능을 많이 쓰고, 관리자 SQL 작업이 많다"면 Supabase 같은 통합 백엔드가 더 빠를 수 있습니다. Cloudflare-only는 모든 경우의 정답이 아니라, 작은 공개 사이트를 빠르게 만들고 필요한 만큼만 서버 기능을 붙이는 전략에 특히 잘 맞는 선택지입니다.
실제 운영 사이트형 분담
CDB처럼 웹앱 카탈로그, 칼럼, 통계가 함께 있는 사이트라면 정적 콘텐츠는 Static Assets/Pages, API와 검색은 Workers, 사이트 핵심 데이터는 D1, 파일은 R2, 캐시는 KV, 누적 통계는 Turso 또는 Analytics Engine, 봇 방어는 Turnstile로 나누는 그림이 현실적입니다.
| 서비스 | 역할 | 어울리는 기능 | 주의할 점 |
|---|---|---|---|
| Workers | 컴퓨팅 | API, SSR, 웹훅, 폼 처리, 인증 콜백, 외부 API 중계 | Node 서버가 아니라 V8 isolate 기반 런타임입니다. 파일 시스템, 네이티브 모듈, 긴 작업은 조심해야 합니다. |
| Workers Static Assets / Pages | 정적 자산 호스팅 | 홈페이지, 블로그, 포트폴리오, 랜딩 페이지, SPA 정적 파일 | 신규 프로젝트는 Workers Static Assets가 권장 흐름입니다. 기존 Pages 프로젝트는 계속 쓸 수 있지만 장기 방향을 확인하세요. |
| D1 | SQL 데이터베이스 | 문의, 예약, 게시글 메타데이터, 관리자 설정, 작은 CRM 데이터 | SQLite 계열입니다. rows read/write, 인덱스, 10GB급 단위 설계를 이해해야 하고 Postgres 확장을 그대로 기대하면 안 됩니다. |
| R2 | 오브젝트 저장소 | 이미지 원본, 첨부파일, 다운로드 자료, 백업 파일, 생성형 이미지 결과물 | 인터넷 egress 무료가 강점이지만 Class A/B operation과 공개/비공개 접근 정책을 함께 설계해야 합니다. |
| KV | 키-값 저장소 | 공지 배너, 기능 플래그, 리다이렉트 목록, 캐시성 설정, 읽기 많은 작은 데이터 | 결과적 일관성이라 즉시 반영되어야 하는 재고, 결제 상태, 카운터의 원본 저장소로 쓰면 위험합니다. |
| Durable Objects | 상태 저장 컴퓨팅 | 채팅방, 협업 편집, 실시간 방, 분산 락, 사용자별 세션 조정 | 강한 일관성이 필요한 논리 단위마다 객체를 나누는 설계가 필요합니다. 처음 홈페이지에는 대개 나중 단계입니다. |
| Queues | 비동기 작업 | 메일 발송, 이미지 후처리, 외부 API 재시도, 로그 적재, 예약 알림 | 중복 처리와 재시도 설계를 해야 합니다. 사용자 요청 안에서 오래 걸리는 일을 분리할 때 빛납니다. |
| Hyperdrive | 외부 DB 연결 가속 | Neon, Supabase Postgres, PlanetScale 같은 외부 DB를 Workers에서 더 안정적으로 연결 | Cloudflare-only는 아니지만, D1 한계를 넘는 SQL 기능이 필요할 때 현실적인 우회로입니다. |
개인 홈페이지
Static Assets로 정적 페이지를 제공하고, KV에는 공지/링크 설정만 둡니다. 문의 폼이 필요해지면 Workers + D1을 붙입니다.
포트폴리오
작업 사례는 Astro 콘텐츠 또는 D1에 두고, 원본 이미지와 PDF는 R2에 저장합니다. 프로젝트 필터나 추천 노출은 KV로 가볍게 처리합니다.
자영업자 사이트
메뉴, 영업시간, 위치, FAQ는 정적 페이지로 만들고 예약/문의/리뷰 관리는 D1에 둡니다. 메뉴판 이미지와 쿠폰 파일은 R2가 적합합니다.
작은 SaaS/도구
로그인과 권한이 단순하면 Workers + D1로 시작하고, 실시간 협업이나 방 개념이 생기면 Durable Objects를 추가합니다.
DNS·Registrar
도메인을 Cloudflare에서 관리하면 DNS, CDN, SSL, WAF, Pages 연결이 한 대시보드에 모입니다. Registrar는 레지스트리와 ICANN 비용만 받는 무마진 모델이라 장기 운영 도메인에 유리합니다.
SSL/TLS·WAF
Universal SSL은 활성화된 도메인에 무료 인증서를 자동 발급·갱신합니다. WAF는 들어오는 웹/API 요청을 규칙으로 걸러 폼 스팸, 취약점 공격, 비정상 요청을 줄입니다.
Cache Rules·CDN
정적 파일은 기본적으로 가까운 Cloudflare 캐시에서 서빙됩니다. HTML이나 API 응답까지 캐시하려면 Cache Rules로 무엇을 얼마나 보관할지 명확히 정해야 합니다.
Turnstile
문의 폼, 로그인, 예약 신청처럼 자동 제출이 문제 되는 지점에 붙이는 봇 방어 서비스입니다. reCAPTCHA 대체재로 쓰기 좋고, 서버에서 Siteverify 검증까지 해야 효과가 납니다.
Images·Stream
R2가 원본 파일 저장소라면 Images는 이미지 리사이즈·포맷 변환·캐시 배포, Stream은 동영상 업로드·인코딩·HLS 재생을 담당합니다.
Web Analytics·Analytics Engine
Web Analytics는 쿠키 없는 기본 웹 통계에 적합하고, Analytics Engine은 Worker에서 직접 쓰는 사용자 정의 이벤트와 시계열 분석에 적합합니다.
Astro 합류 | 인수 사실과 경쟁 구도
2026년 1월 16일 Cloudflare는 Astro 웹 프레임워크를 만든 The Astro Technology Company가 Cloudflare에 합류한다고 발표했습니다. Cloudflare 공식 글은 Astro를 빠른 콘텐츠 중심 웹사이트를 만드는 프레임워크로 설명하고, Cloudflare의 개발자 문서, 웹사이트, 랜딩 페이지, 블로그 같은 콘텐츠 영역에서도 Astro를 사용한다고 밝힙니다.
공식 발표에서 확인되는 것은 Astro 팀이 Cloudflare에 합류했다는 사실과 Astro가 오픈소스·MIT 라이선스·플랫폼 중립성을 유지한다는 점입니다. 거래 금액, 지분 구조, 세부 인수 조건은 공개되지 않았으므로 본문에서도 이를 추정하지 않는 편이 정확합니다.
이 인수가 중요한 이유는 프레임워크와 인프라의 궁합 때문입니다. Astro는 기본적으로 HTML을 많이 만들고 필요한 부분만 island로 하이드레이션합니다. Cloudflare는 전 세계 네트워크에서 정적 자산과 Worker 코드를 가까운 곳에서 실행합니다. 그래서 "글과 소개 페이지는 정적으로 빠르게, 문의와 관리자 기능만 동적으로"라는 이 글의 전략과 잘 맞습니다.
Cloudflare는 신규 프로젝트에 Workers Static Assets를 권장하고 있으며, Astro의 Cloudflare 어댑터도 Astro 6 흐름에서 Cloudflare 런타임과 바인딩 접근을 더 직접적으로 다룹니다. Astro 6의 새 개발 서버는 Vite Environments API를 활용해 로컬 dev 서버가 배포 런타임과 같은 API를 쓰도록 만드는 방향입니다. 즉 로컬에서 workerd, D1, KV, Durable Objects 같은 Cloudflare 문맥을 더 가깝게 재현할 수 있습니다.
경쟁 구도도 단순한 Astro 대 Next.js로 보면 좁습니다. 데이터 중심 React 앱은 Next.js와 React Router 계열이 강하고, 콘텐츠 중심 정적 사이트는 Hugo·Eleventy·Astro가 경쟁하며, island 철학으로는 Fresh·Qwik 같은 선택지도 있습니다. Cloudflare가 Hono 같은 도구도 후원하고 여러 프레임워크 어댑터를 제공한다는 점을 보면, Astro 합류는 전체 프레임워크 락인이라기보다 콘텐츠 중심 사이트의 기본 경로를 확보한 사건에 가깝습니다.
실전 해석
Next.js + Vercel이 React 앱의 빠른 배포 경로라면, Astro + Cloudflare는 콘텐츠 중심 사이트와 작은 풀스택 기능을 싸고 빠르게 공개하는 경로로 이해하면 쉽습니다.
- 콘텐츠가 중심이면 Astro의 정적 HTML과 island 구조가 유리하다.
- Cloudflare 바인딩을 쓰면 코드에서 env.DB, env.MEDIA처럼 리소스를 명확히 호출할 수 있다.
- Astro 합류가 플랫폼 중립성을 없앤다는 뜻은 아니지만, Cloudflare에서 가장 먼저 매끄러운 경로가 생길 가능성은 크다.
- 바이브 코딩에서는 단순한 파일 구조와 빠른 로컬 피드백이 중요하므로 Astro는 좋은 출발점이 된다.
Astro가 잘 맞는 이유
페이지 대부분을 빠른 HTML로 만들고 필요한 섬(island)만 React/Vue/Svelte 등으로 하이드레이션합니다. 콘텐츠 중심 사이트에 과한 클라이언트 자바스크립트를 줄일 수 있습니다.
Cloudflare와 맞물리는 지점
@astrojs/cloudflare 어댑터와 Workers Static Assets 흐름을 쓰면 정적 파일, SSR, API, 바인딩을 Cloudflare 런타임에 맞춰 배포할 수 있습니다.
AI 코딩에 유리한 지점
Astro는 파일 구조와 페이지 단위가 비교적 명확합니다. AI에게 "이 페이지, 이 컴포넌트, 이 D1 테이블만 수정"처럼 범위를 작게 줄 수 있습니다.
오해하면 안 되는 지점
Astro 합류 발표가 모든 사이트를 Cloudflare로 옮겨야 한다는 뜻은 아닙니다. 다만 콘텐츠 중심 웹에서 Cloudflare + Astro가 더 자연스러운 기본 경로가 된다는 의미가 큽니다.
용어·공식 문서 | 최신 절차를 확인하는 기준
Cloudflare 서비스와 Wrangler 명령은 계속 업데이트됩니다. 그래서 이 글의 명령은 실전 흐름을 이해하기 위한 기준으로 보고, 실제 실행 전에는 공식 문서와 현재 프로젝트의 package.json, wrangler 설정을 함께 확인해야 합니다.
좋은 바이브 코딩은 AI에게 모든 결정을 넘기는 일이 아닙니다. 좋은 질문으로 작업을 작게 나누고, 민감한 권한은 사람이 잡고, 반복 구현과 검증을 AI에게 맡기는 협업 방식입니다. 그렇게 하면 개인 홈페이지든 포트폴리오든 작은 매장 사이트든 훨씬 빠르게 실제 공개까지 갈 수 있습니다.
- 공식 문서 링크를 프롬프트에 함께 주고 현재 명령을 확인시킨다.
- AI가 제안한 명령은 로컬 프로젝트 스크립트와 충돌하지 않는지 본다.
- 민감한 값은 끝까지 프롬프트 밖에 둔다.
- 작게 배포하고 실제 사용자 반응을 보며 다음 기능을 정한다.
Binding
Cloudflare 리소스를 Worker/Pages Function 코드의 env 이름으로 연결하는 약속입니다. 예: env.DB, env.MEDIA.
V8 Isolate
Chrome V8 엔진 안에서 메모리와 전역 객체를 분리해 코드를 실행하는 격리 단위입니다. VM이나 컨테이너보다 시작 비용이 작아 Workers의 빠른 콜드 스타트에 유리합니다.
D1
Cloudflare의 서버리스 SQL 데이터베이스입니다. SQLite 계열이며 rows read/write 기준으로 사용량을 봅니다.
Turso
libSQL/SQLite 계열의 외부 데이터베이스 서비스입니다. Cloudflare 네이티브 바인딩은 아니지만 D1과 함께 쓰면 누적 로그·통계 데이터를 분리하는 보완 DB가 될 수 있습니다.
R2
Cloudflare의 오브젝트 저장소입니다. 이미지, 첨부파일, 다운로드 파일에 적합하고 인터넷 egress가 무료입니다.
KV
자주 읽고 가끔 바뀌는 key-value 저장소입니다. 공지, 기능 플래그, 캐시성 설정값에 맞습니다.
Workers
전 세계 Cloudflare 네트워크에서 실행되는 서버리스 함수입니다. API, 웹훅, 백그라운드 작업에 사용합니다.
Pages Functions
Cloudflare Pages 프로젝트 안에서 라우트 가까이에 두는 서버 함수입니다. 문의 폼 같은 기능에 편합니다.
Wrangler
Cloudflare 리소스 생성, 바인딩 설정, 로컬 개발, 배포를 터미널에서 다루는 CLI입니다.
Secret
API 키처럼 코드 저장소에 넣으면 안 되는 값입니다. 로컬 env나 Cloudflare secrets로 관리합니다.
Rows read/write
D1에서 쿼리가 읽거나 쓴 행 수입니다. 인덱스가 없으면 반환 행이 적어도 읽은 행 수가 커질 수 있습니다.
Class A/B operations
R2 작업 과금 단위입니다. 업로드·수정·목록 조회 계열은 Class A, 다운로드·HEAD 같은 읽기 계열은 Class B로 보는 식입니다.
Egress
서비스에서 사용자나 외부 인터넷으로 나가는 데이터 전송량입니다. 비용 비교에서 자주 갈리는 항목입니다.
Eventually Consistent
쓰기 직후 모든 지역에서 즉시 최신 값을 보는 것이 아니라 일정 시간 안에 전파되어 최종적으로 같은 값에 수렴하는 일관성 모델입니다. KV 설계에서 특히 중요합니다.
Strong Consistency
쓰기 직후 이어지는 읽기가 최신 값을 본다는 보장입니다. D1, Durable Objects, R2의 객체 단위 동작을 이해할 때 기준이 됩니다.
CPU time
Worker나 Function이 실제 계산에 쓴 시간입니다. 외부 API 대기 시간과 과금 방식이 플랫폼마다 다릅니다.
Smart Placement
Worker를 무조건 사용자와 가까운 엣지에서 실행하지 않고, 연결하는 DB나 외부 API와 가까운 위치로 자동 배치해 왕복 지연을 줄이는 기능입니다.
Islands Architecture
페이지 대부분은 정적 HTML로 두고, 상호작용이 필요한 부분만 독립된 섬처럼 클라이언트 JS로 하이드레이션하는 Astro의 핵심 렌더링 철학입니다.
Vite Environments API
개발 서버와 빌드 도구가 코드 실행 런타임을 환경 단위로 다루게 해 주는 Vite의 추상화입니다. Astro 6가 Cloudflare 런타임과 로컬 개발 차이를 줄이는 기반입니다.
Static Assets
Worker와 함께 HTML, CSS, 이미지 같은 정적 파일을 배포하는 Cloudflare의 현재 권장 정적/풀스택 배포 흐름입니다.
Durable Objects
전 세계에서 특정 ID 하나로 모이는 상태 저장 Worker입니다. 채팅방, 협업 문서, 분산 락처럼 조정이 필요한 기능에 씁니다.
Queues
사용자 요청 안에서 바로 끝내기 어려운 메일, 이미지 처리, 외부 API 재시도를 뒤로 넘기는 비동기 작업 큐입니다.
Hyperdrive
Workers에서 외부 Postgres/MySQL 계열 DB로 연결할 때 지연과 연결 관리를 줄이기 위한 Cloudflare 서비스입니다.
workerd
Cloudflare Workers 런타임의 오픈소스 엔진입니다. 로컬 개발과 실제 배포 런타임 차이를 줄이는 흐름에서 자주 등장합니다.
D1 한계 | 로컬·원격·GUI·수집 비용
D1은 Cloudflare Workers와 가장 자연스럽게 붙는 SQL DB이지만, "내 PC의 SQLite 파일처럼 계속 열어 보고 원격과 자동 동기화되는 DB"라고 생각하면 금방 막힙니다. Wrangler 로컬 개발의 D1은 production 원격 D1과 분리된 로컬 전용 상태이고, 원격 운영 데이터에 접근하려면 의도적으로 remote 흐름을 써야 합니다.
공식 문서도 로컬 개발 세션이 production 데이터를 기본으로 보지 않는다고 설명합니다. 그래서 바이브 코딩으로 작업할 때는 AI에게 "D1 명령은 항상 `--local` 또는 `--remote`를 명시하라"고 지시하는 편이 안전합니다. 같은 database_name을 쓰더라도 로컬과 원격은 내용물이 다를 수 있습니다.
로컬과 원격 사이의 이동도 "동기화"라기보다 export/import 스냅샷에 가깝습니다. 원격을 SQL 파일로 내보내고 로컬에 적용하거나, 로컬 덤프를 원격에 적용할 수는 있지만, 양쪽에서 동시에 바뀐 값을 자동으로 충돌 해결해 주지는 않습니다. 운영 DB에 적용할 때는 백업, dry-run, 적용 범위 확인이 먼저입니다.
또 하나의 현실적인 불편은 원격 D1을 표준 SQLite GUI처럼 바로 열기 어렵다는 점입니다. Cloudflare 대시보드 콘솔, Wrangler 명령, HTTP API, 별도 프록시나 커뮤니티 도구를 써야 합니다. 로컬 `.wrangler` 아래의 SQLite 파일을 GUI로 볼 수는 있지만, 그것은 운영 DB가 아니라 로컬 개발 상태입니다.
상시 수집·크롤링·방문 로그처럼 행이 계속 쌓이는 워크로드도 D1 단독으로 밀어 넣기 전에 멈춰 봐야 합니다. D1은 rows read/write 단위로 비용과 무료 한도가 움직이고, DB당 10GB 한계도 있습니다. 문의·예약·사이트 메타처럼 작고 중요한 데이터에는 좋지만, 원시 로그와 장기 통계는 Turso, Analytics Engine, R2 아카이브 같은 별도 경로가 더 안전할 때가 많습니다.
D1을 버리라는 뜻은 아닙니다
D1은 Workers와 가까운 핵심 운영 데이터에 아주 좋습니다. 다만 로컬에서 계속 들여다보는 수집 DB, 큰 로그 저장소, 표준 GUI 중심 운영 DB 역할까지 한 번에 맡기려 하면 Cloudflare의 장점보다 마찰이 먼저 커집니다.
- `wrangler dev`에서 보이는 D1 데이터와 production D1 데이터는 같은 것으로 취급하지 않는다.
- AI에게 D1 명령을 맡길 때는 `--local`, `--remote`, 대상 DB 이름, 적용 파일을 먼저 말하게 한다.
- 원격 D1에 `--file`을 적용하기 전에는 현재 스키마와 백업 파일을 확인한다.
- 방문 로그, 이벤트, 통계 원천 데이터처럼 행이 계속 늘어나는 데이터는 처음부터 D1 바깥 분담을 검토한다.
| 한계 지점 | 무엇이 문제인가 | 운영 팁 |
|---|---|---|
| 로컬과 원격 분리 | `wrangler dev`의 D1은 로컬 전용 환경에서 동작합니다. production 원격 D1 데이터에 자동으로 붙지 않으므로 테스트 데이터와 운영 데이터가 다릅니다. | 명령에는 `--local` 또는 `--remote`를 명시하고, preview/production DB 이름과 바인딩을 표로 관리합니다. |
| 수동 덤프 이동 | D1은 로컬과 원격을 자동 양방향 동기화하는 제품이 아닙니다. 공식 흐름은 `wrangler d1 export`로 SQL 파일을 만들고 `d1 execute --file`로 적용하는 방식입니다. | 충돌 해결, 증분 동기화, 운영 중 머지는 별도 설계가 필요합니다. 큰 데이터 이동은 사전에 dry-run과 백업을 둡니다. |
| 원격 GUI 한계 | 원격 D1은 일반 SQLite 파일처럼 DBeaver, TablePlus, DataGrip에 바로 여는 구조가 아닙니다. 대시보드 콘솔, Wrangler, HTTP API, 커뮤니티 도구를 조합합니다. | 로컬 `.wrangler` SQLite 파일을 열 때도 그것이 운영 DB가 아니라 로컬 상태라는 점을 문서에 적어 둡니다. |
| 행 단위 과금 | D1은 rows read/write 기준으로 사용량을 봅니다. 로그·크롤링·통계처럼 INSERT가 계속 쌓이는 워크로드는 무료 일 한도와 유료 쓰기 비용을 빨리 만나기 쉽습니다. | 인덱스, 집계 테이블, KV 캐시, Analytics Engine, Turso 분리 같은 절감 장치를 초기에 둡니다. |
| 쓰기 위치와 지연 | D1은 primary database instance가 있고, read replication은 읽기 지연을 줄이는 보조 기능입니다. 쓰기 요청은 primary로 가므로 수집 위치와 DB 위치가 멀면 지연이 누적될 수 있습니다. | 쓰기 많은 데이터는 위치 힌트, batch, 큐, 외부 수집 DB 분리까지 함께 검토합니다. |
| DB당 10GB 한계 | Cloudflare 공식 D1 한계는 Paid 기준 DB당 10GB입니다. 콘텐츠 메타데이터에는 충분해도 raw 로그와 장기 통계에는 빠르게 좁아질 수 있습니다. | 테넌트/기능별 DB 분리, R2 아카이브, Turso/외부 DB 분리, 보관 기간 정책을 정합니다. |
# 로컬 D1에 명시적으로 실행
npx wrangler d1 execute my_site_db --local --command "SELECT COUNT(*) FROM inquiries;"
# 원격 D1에 명시적으로 실행
npx wrangler d1 execute my_site_db --remote --command "SELECT COUNT(*) FROM inquiries;"
# 원격 D1을 SQL 덤프로 내보내기
npx wrangler d1 export my_site_db --remote --output=backup.sql
# 로컬 D1에 덤프 적용하기
npx wrangler d1 execute my_site_db --local --file=backup.sqlTurso 동기화 | 데탑 수집기와 Workers 연결
Turso는 D1의 모든 대체재라기보다 D1이 불편한 지점을 보완하는 SQLite/libSQL 계열 선택지로 이해하면 쉽습니다. 특히 로컬 데스크톱에서 상시 수집기를 돌리고, 그 데이터를 GUI로 확인하면서, 사이트의 Workers API에서도 같은 원격 DB를 읽어야 하는 경우에 빛납니다.
Turso 임베디드 레플리카는 로컬 파일과 원격 primary를 연결합니다. 읽기는 로컬 파일에서 처리되고, 기본 쓰기는 원격 primary로 전송된 뒤 성공하면 로컬 파일에 반영됩니다. 그래서 내가 방금 쓴 값은 바로 읽을 수 있고, 다른 PC나 Workers가 쓴 값은 `client.sync()` 또는 `syncInterval`을 통해 로컬로 가져옵니다.
이 구조 덕분에 데탑 수집기는 빠르게 로컬 DB를 읽고, 원격 Turso에는 사이트에서 볼 수 있는 최신 운영 데이터가 쌓입니다. 다만 Turso 문서는 embedded replicas를 기존 libSQL 기반 기능으로 설명하면서, 새 sync 프로젝트에는 Turso Sync를 검토하라고 안내합니다. 따라서 새 프로젝트에서는 공식 문서의 현재 권장 경로를 함께 확인해야 합니다.
Cloudflare Workers에서는 임베디드 레플리카를 그대로 쓸 수 없습니다. Workers는 지속 파일 시스템이 없기 때문입니다. 사이트 측 코드는 `@libsql/client/web`로 Turso 원격 URL에 연결하고, `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`은 Wrangler secret으로 넣습니다. 이 차이를 모르면 로컬 수집기 코드를 Worker에 그대로 붙였다가 런타임에서 깨질 수 있습니다.
운영 분담은 단순하게 잡는 것이 좋습니다. D1에는 문의, 예약, 앱 카탈로그, 사이트 설정처럼 Worker와 가까워야 하는 핵심 데이터를 둡니다. Turso에는 방문 로그, 이벤트, 크롤링 결과, 원천 통계처럼 로컬 분석과 누적 행 증가가 중요한 데이터를 둡니다. R2는 파일, KV는 캐시와 설정입니다.
AI에게 줄 한 줄 지시
“D1은 사이트 핵심 데이터, Turso는 누적 로그·통계와 로컬 수집 데이터로 분리하고, Workers에서는 `@libsql/client/web`, 데탑 수집기에서는 임베디드 레플리카를 쓰는 예제로 작성해 줘.”
- 로컬 수집기와 Worker 사이트 API의 Turso 클라이언트 코드는 다르게 쓴다.
- 로컬 DB 파일을 GUI로 열어야 하면 sync 중인 원본 대신 복사본을 열어 데이터 손상 위험을 줄인다.
- 대량 INSERT는 batch나 transaction으로 묶고, syncInterval은 지나치게 짧게 잡지 않는다.
- 민감한 방문 로그나 사용자 데이터는 수집 목적, 보관 기간, 익명화 기준을 먼저 정한다.
| 동작 지점 | 의미 | 주의할 점 |
|---|---|---|
| 로컬 파일 + 원격 primary | 임베디드 레플리카는 `file:./local.db` 같은 로컬 파일을 읽기용 복제본으로 두고, `syncUrl`의 Turso Cloud DB와 연결합니다. | 데탑 수집기, VPS, 모바일 앱처럼 지속 파일 시스템이 있는 환경에 맞습니다. |
| 읽기 | 읽기는 항상 로컬 파일에서 처리됩니다. 네트워크 왕복 없이 빠르게 대시보드·분석·로컬 GUI 확인을 할 수 있습니다. | 로컬 파일이 최신이라고 가정하지 말고, 다른 클라이언트 변경분은 sync 주기에 따라 들어온다고 봅니다. |
| 쓰기 | 기본 쓰기는 원격 primary로 보내지고 성공 후 로컬 복제본에 반영됩니다. 그래서 자신이 방금 쓴 값은 바로 읽을 수 있습니다. | `offline: true`는 로컬 우선 쓰기 시나리오용이므로 충돌과 동기화 정책을 따로 설계합니다. |
| 동기화 목적 | `client.sync()`나 `syncInterval`은 다른 PC, Workers, 서버가 쓴 변경분을 내 로컬 복제본으로 가져오기 위한 장치입니다. | 쓰기 전용 수집기라면 sync 빈도를 낮추고, 운영 화면을 함께 본다면 시작 시와 일정 주기로 sync합니다. |
| 주의사항 | Turso 문서는 sync 중 로컬 DB 파일을 직접 열지 말라고 경고합니다. 또한 page/frame 단위 복제라 작은 변경도 4KB 단위 전송으로 잡힐 수 있습니다. | GUI 열람은 앱을 멈추거나 스냅샷 복사본으로 보고, 대량 쓰기는 batch/transaction으로 묶습니다. |
| Workers 연결 | Cloudflare Workers에는 지속 파일 시스템이 없으므로 임베디드 레플리카가 아니라 HTTP/web 클라이언트로 연결합니다. | `@libsql/client/web`을 쓰고 `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`은 Wrangler secret으로 넣습니다. |
데탑 상시 수집기
로컬 PC나 사무실 미니 서버에서 크롤링·통계 수집기를 계속 켜 둘 때 Turso 임베디드 레플리카가 편합니다. 로컬 파일을 빠르게 읽고, 원격 primary와 동기화해 사이트에서도 같은 데이터를 볼 수 있습니다.
Workers 사이트 API
사이트 방문자가 보는 API는 Workers에서 `@libsql/client/web`로 Turso에 연결합니다. 이때 URL과 토큰은 코드에 쓰지 않고 Cloudflare secret으로 분리합니다.
GUI 확인
로컬 `local-replica.db`는 SQLite 파일이라 DB Browser for SQLite, DBeaver, TablePlus 같은 도구로 볼 수 있습니다. 다만 sync 중 직접 열면 손상 위험이 있으므로 복사본을 열거나 수집기를 잠시 멈춥니다.
D1과 함께 쓰는 기준
사이트 핵심 데이터는 D1에 두고, 행이 빠르게 늘거나 로컬 열람이 중요한 로그·이벤트·통계는 Turso에 둡니다. 이 분담표를 AI에게 먼저 주면 불필요한 D1 rows 폭증을 줄일 수 있습니다.
turso auth signup
turso auth login
turso db locations
turso db create cdb-events
turso db show cdb-events --url
turso db tokens create cdb-events
turso db shell cdb-eventsimport { createClient } from "@libsql/client";
import "dotenv/config";
const db = createClient({
url: "file:./local-replica.db",
syncUrl: process.env.TURSO_DATABASE_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
syncInterval: 60,
});
await db.sync();
async function collectOnce() {
const item = await crawl();
await db.execute({
sql: "INSERT INTO events (kind, payload, created_at) VALUES (?, ?, ?)",
args: [item.kind, JSON.stringify(item), new Date().toISOString()],
});
}import { createClient } from "@libsql/client/web";
export default {
async fetch(request, env) {
const db = createClient({
url: env.TURSO_DATABASE_URL,
authToken: env.TURSO_AUTH_TOKEN,
});
const result = await db.execute(
"SELECT kind, created_at FROM events ORDER BY created_at DESC LIMIT 10"
);
return Response.json(result.rows);
},
};npx wrangler secret put TURSO_DATABASE_URL
npx wrangler secret put TURSO_AUTH_TOKEN