【2026년판】 Cloudflare Workers 입문 | 제작한 앱을 공개하는 방법
요약
본 글은 AI로 제작한 앱을 Cloudflare Workers를 통해 배포하고 공개하는 방법을 안내합니다. 서버리스 환경인 Workers는 전 세계 데이터센터에서 코드를 구동하며, SPA나 API 서버 등 다양한 유형의 앱을 `npx wrangler deploy` 명령어로 쉽게 배포할 수 있습니다.
핵심 포인트
- Cloudflare Workers는 전 세계 300개 도시 이상에서 코드를 구동하는 서버리스 환경입니다.
- SPA/정적 사이트는 `npx wrangler deploy`로 한 번에 공개가 가능합니다.
- Next.js와 같은 복잡한 앱은 별도의 배포 패턴(vnext)을 사용해야 합니다.
- 무료 플랜의 경우, 상한 초과 시 과금 없이 에러만 반환됩니다.
서론
AI와 함께 앱을 만드는 사람이 늘어나면서, '만들었는데 어디에 공개해야 할지?' 고민하는 사람도 많으실 겁니다. 이 글에서는 그러한 공개처로서 Cloudflare Workers에 올리는 방법을 앱 종류별로 정리했습니다. SPA나 주요 프레임워크라면, npx wrangler deploy를 단 한 번 실행하는 것만으로 공개할 수 있습니다.
Cloudflare Workers란?
Cloudflare의 전 세계 300개 도시 이상의 데이터센터에서 코드를 구동할 수 있는 서버리스(serverless) 실행 환경입니다. 정적 파일부터 API, SSR까지 한곳에 모아두고 사용자 가까이에서 응답합니다. 2025년 4월부터는 Cloudflare Pages가 아닌 Workers로 시작하는 것이 권장되며, 신기능도 Workers에 집중되고 있습니다.
요금 (2026년 10월 기준)
| Free (무료) | Paid (월 $5~) | |
|---|---|
| 요청 수 | 일일 1억 회까지 | 월 1,000만 회 포함 (초과 시 100만 회당 $0.30) |
| ... |
- 정적 파일은 무료/무제한이므로, SPA나 정적 사이트라면 실질적으로 무료입니다. CPU 시간에는 데이터베이스나 외부 API의 응답 대기 시간이 포함되지 않습니다.
- 무료 플랜은 상한을 초과해도 과금이 되지 않으며, 에러(Error 1027)가 반환될 뿐입니다 (매일 일본 시간 오전 9시에 리셋).
먼저 5분 만에 Hello World 만들기
첫 배포를 위해 필요한 로그인과 서브도메인 등록을 Hello World로 완료해 봅시다.
준비물: Cloudflare 계정 (가입 페이지에서 무료 생성) 및 Node.js 24 이상 (필자의 권장)
npm create cloudflare@latest -- my-first-worker --category=hello-world --type=hello-world --lang=ts --git --agents --no-deploy
dcd my-first-worker
npm run dev # http://localhost:8787에 Hello World!가 표시됩니다.
함께 만들 수 있는 AGENTS.md는 AI 코딩 도구에 최신 Cloudflare 문서를 참조하도록 하는 파일입니다. 확인이 되면 로그인하여 배포합니다.
npx wrangler login
npm run deploy
처음에는 workers.dev의 서브도메인을 묻습니다. 계정에 단 하나만 만들 이름으로, 모든 Worker의 URL(<Worker명>.<서브도메인>.workers.dev)에 사용됩니다. 영문 소문자・숫자・하이픈으로 지정합니다 (점은 불가. 예: yamada-dev).
표시된 URL이 열리면 공개가 완료입니다. 등록 직후에는 열리는 데 몇 분이 걸릴 수 있습니다.
자신의 앱을 올리기
앱 종류에 따라 진행할 경로를 선택합니다. 모든 방법은 프로젝트 파일을 수정하므로, 먼저 Git으로 커밋해 두는 것이 좋습니다.
| 앱 | 진행 경로 | |
|---|---|
| Vite (React 등)의 SPA, Astro, SvelteKit, Nuxt, 정적 사이트 등 | 패턴1: npx wrangler deploy |
| Next.js | 패턴2: vnext (npx wrangler deploy는 사용하지 않음) |
| Hono・Express 등의 API 서버 | 패턴3: 설정 파일을 하나 작성하기 |
패턴1: SPA 및 주요 프레임워크
프로젝트 폴더에서 실행합니다.
npx wrangler@latest deploy # 자동 설정을 위해서는 Wrangler 4.68.0 이상이 필요합니다.
Wrangler (Cloudflare의 CLI)가 판별한 설정이 표시되므로, 맞다면 Do you want to modify these settings?에 N, Proceed with setup?에 Y라고 답합니다. 설정 파일 작성부터 배포까지 자동으로 진행됩니다.
Vite의 SPA의 경우, Cloudflare의 Vite 플러그인 추가, deploy 스크립트 추가 및 preview
의 대체(npm run build && wrangler dev), .gitignore에 .wrangler 등을 추가하고, wrangler.jsonc를 자동 생성했습니다.
생성된 wrangler.jsonc의 "not_found_handling": "single-page-application" 덕분에 /about 등을 직접 열어도 index.html이 반환되어 리로드 시 404 에러가 발생하지 않습니다. 출력 경로(dist)를 지정하지 않은 이유는 빌드 시 Vite 플러그인이 생성하는 dist/wrangler.json 파일이 배포에 사용되기 때문입니다.
다음부터는 npm run deploy로 업데이트하고, npm run preview로 Workers와 동일한 환경에서 로컬 확인을 할 수 있습니다.
패턴 2: Next.js
Cloudflare가 권장하는 것은 Next.js를 Vite 위에서 구동하는 vinext입니다. 이는 2026년 9월 28일에 1.0 버전이 공개되어 프로덕션 환경에서 사용할 수 있는 단계가 되었습니다. 다만 Cache Components에 대한 지원은 아직 제한적이므로, vinext check로 호환성을 확인한 후 사용하는 것이 좋습니다. 다음 절차를 통해 배포할 수 있었습니다.
npx vinext check # 호환성 체크
npm install react@latest react-dom@latest # 의존성 오류 예방
npx vinext init --platform=cloudflare --cdn-cache=workers-cache --data-cache=none --image-optimization=cloudflare-images
...
- React 업데이트:
create-next-app은 React의 버전을 고정하기 때문에,vinext init이npm error ERESOLVE로 멈추는 경우가 있습니다. 중간까지 수정되므로 Git으로 되돌려 다시 시도했습니다. - init 옵션: 캐시를 Workers Cache로 사용하면 추가적인 신청 없이 작동합니다. 초기값인 Response Store는 R2 활성화가 필요하며, 캐시가 없으면
No such module "_next/static/__vinext_cacheability_manifest.js"오류와 함께 시작되지 않습니다. 다만, 캐시를 활성화할 경우 정적 파일에 대한 요청도 과금(무료 플랜은 일일 10만 회 한도) 대상이 됩니다. - Tailwind: Next.js 16.4의 초기 템플릿은 Tailwind를 Turbopack을 통해 로드하기 때문에, vinext에서는 스타일이 적용되지 않습니다 (
vinext check에서turbopack — rules (loaders) are ignored가 나타나는 것이 신호입니다).vite.config.ts에서@tailwindcss/vite를 import하고,plugins의 맨 앞에tailwindcss()를 추가해야 합니다. - cf 로그인:
deploy:vinext는 새로운 CLI인 "cf"(2026년 9월부터 베타)로 배포합니다 (공식 가이드의npx @vinext/cloudflare deploy와 동일한 처리입니다). 로그인 상태는npx cf auth whoami로 확인할 수 있으며, 배포 직후 약 1분 동안은 503 에러가 반환될 수도 있습니다. - 설정 파일: cf 형식의
cloudflare.config.ts를 사용하므로, 이 이후의wrangler.jsonc예시와는 작성 방식이 다릅니다 (cf는 Wrangler의 후속 예정이지만, 당분간은 Wrangler로도 괜찮습니다).
패턴 3: API 서버 (Hono・Express)
API 서버는 자동 설정 대상이 아니므로, wrangler.jsonc를 하나 작성해야 합니다.
Hono는 Node.js용 serve()와 @hono/node-server의 import 구문을 제거하고, export default app으로 변경하기만 하면 됩니다.
import { Hono } from "hono";
const app = new Hono();
app.get("/api/hello", (c) => c.json({ message: "Hello from Hono!" }));
...
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-api",
...
새로 만들 경우 먼저 실행: mkdir my-api && cd my-api && npm init -y && npm install hono
npm install -D wrangler
npx wrangler dev # http://localhost:8787/api/hello 에서 확인
...
## Express의 경우
새로 만드는 것이라면 Hono를 추천하지만 (작성자 측정 기준, Hono는 약 58KB · 시작 2ms, Express는 약 1.15MB · 시작 37ms), 기존에 사용하던 Express 앱도 `httpServerHandler`를 이용하면 거의 그대로 작동합니다.
import express from "express";
import { httpServerHandler } from "cloudflare:node";
const app = express();
...
`npm install express`를 실행한 후, `wrangler.jsonc`의 `"main"`을 `"src/index.js"`로, `"name"`을 다른 이름 (예: `"my-express"`)으로 변경해야 합니다. 같은 이름을 유지하면 Hono Worker가 덮어쓰여집니다. `compatibility_date`가 2026-08-04 이후라면 필요한 Node.js 호환 기능은 처음부터 활성화됩니다.
## 배포 환경에서 필요한 것들
### 환경 변수와 시크릿 (Environment Variables and Secrets)
| 종류 | 위치 | 코드에서의 읽는 방법 |
|---|---|---|
| 공개해도 되는 설정값 | `wrangler.jsonc`의 `vars` | `env.이름` (Hono라면 `c.env.이름`) |
| 비밀 값 (API 키 등) | 로컬: `.dev.vars` 파일 / 배포 환경: `npx wrangler secret put 이름` | 위와 동일 |
### 커스텀 도메인 (Custom Domain)
- 대시보드에서 커스텀 도메인을 Cloudflare에 추가합니다.
- 표시된 네임서버를 도메인을 구매한 서비스에 설정합니다.
- 도메인이 활성화(Active)되면, Worker에 Custom Domain을 추가합니다.
3은 대시보드의 **Workers & Pages → 대상 Worker → Settings → Domains & Routes → Add → Custom Domain**에서 하거나, `wrangler.jsonc`에서 설정할 수 있습니다. DNS 레코드와 SSL 인증서는 자동으로 준비됩니다.
"routes": [
{ "pattern": "app.example.com", "custom_domain": true }
]
CNAME 레코드가 이미 존재하는 호스트명에는 추가할 수 없으므로, 먼저 삭제해야 합니다. 또한 완전 일치(exact match) 방식이므로, `example.com`만으로는 `www.example.com`에 도달하지 못합니다 (www도 추가하거나 리다이렉트를 설정해야 함).
### 데이터베이스 (Database)
| 원하는 작업 | 사용할 것 |
|---|---|
| 새로운 데이터베이스를 준비하고 싶을 때 | D1 (SQLite 기반) |
| 기존의 PostgreSQL / MySQL을 계속 사용하고 싶을 때 | Hyperdrive (기존 DB에 빠르게 연결 가능) |
| 설정값이나 캐시를 저장하고 싶을 때 | Workers KV |
| 이미지나 파일을 저장하고 싶을 때 | R2 |
기존 PostgreSQL이 있다면, 연결 문자열(connection string)로부터 Hyperdrive를 생성합니다.
npx wrangler hyperdrive create my-db --connection-string="postgres://user:password@host:5432/dbname"
표시된 ID를 `wrangler.jsonc`의 `hyperdrive`에 추가합니다.
에 추가하면, `env.HYPERDRIVE.connectionString`을 `pg`와 같은 드라이버에 전달하여 연결할 수 있습니다.
## 자주 발생하는 오류 지점
###
`Error 1102`가 나타나는 경우
무료 플랜에서 CPU 시간(무료 플랜은 요청당 10ms) 또는 메모리(128MB) 제한을 초과했을 때 발생하는 오류입니다. 공식 문서에서는 SSR이 보통 10~20ms 정도 사용되므로, Next.js와 같은 SSR 앱은 유료 플랜(월 $5~)도 고려해 보세요.
###
`This Worker requires compatibility date "..."`가 나타나는 경우
`compatibility_date`가 현재 런타임이 지원하는 날짜보다 최신입니다. 오류에 표시된 날짜로 수정하거나, Wrangler 등을 최신 버전으로 업데이트하세요.
### 로컬에서는 작동하지만 운영 환경에서만 작동하지 않는 경우
흔한 원인은 운영 환경 시크릿 등록 누락(`npx wrangler secret put`)이나 데이터베이스 등의 미설정입니다. `npx wrangler tail`로 운영 환경 로그를 실시간으로 보면 원인을 찾을 수 있습니다.
### 설치 스크립트 경고가 나타나는 경우
npm 11의 새로운 버전에서 나오는 `npm warn install-scripts ... not yet covered by allowScripts`는 경고일 뿐이며, 스크립트는 실행됩니다(npm 12에서는 `... blocked`라고 표시되며 실행되지 않습니다). 필자의 환경에서는 둘 다 작동에 영향을 주지 않으며, 허용하려면 `npm approve-scripts esbuild workerd`를 실행합니다.
### Node.js 전용 라이브러리가 작동하지 않는 경우
`compatibility_date`가 2026-08-04 이전인 프로젝트에서는 `wrangler.jsonc`에 `"compatibility_flags": ["nodejs_compat"]`를 추가해야 합니다 (이후 날짜라면 처음부터 유효합니다).
### Cloudflare Pages나 Vercel에서 마이그레이션하고 싶은 경우
공식 마이그레이션 가이드가 있습니다(Pages에서 마이그레이션 / Vercel에서 마이그레이션).
## 요약
- SPA나 주요 프레임워크는 `npx wrangler deploy` 한 번으로 공개할 수 있습니다 - Next.js는 vinext. React, 캐시, Tailwind, cf 로그인에 주의하세요.
- API 서버는 `wrangler.jsonc`를 하나 작성하면 작동합니다 - 운영 환경에서는 환경 변수, 커스텀 도메인, 데이터베이스를 설정해야 합니다.
다음 편에서는 Hono와 D1을 사용하여 데이터를 저장할 수 있는 게시판을 처음부터 만들 것입니다.
## 참고 링크 (Cloudflare 공식)
### Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기