aimake.log
인프라

Cloudflare Pages 무료 배포 — 명령 한 줄로 내 도메인에 올리기 (만들기 06)

지난 편에서 워드프레스를 폴더 하나로 내보내는 것까지 했습니다. 이제 그 폴더를 인터넷에 올릴 차례입니다 — Cloudflare Pages 무료 배포입니다. Cloudflare Pages가 뭔가요? Cloudflare Pages는 정적 파일 폴더를 받아서 전 세계 서버에 복사해두고,…

2026.07.31 11 MIN
세 줄 요약

Cloudflare Pages는 정적 파일 폴더를 통째로 받아 전 세계에 뿌려주는 무료 호스팅입니다. 명령 한 줄이면 배포가 끝납니다.

무료 한도는 배포당 파일 2만 개, 파일 하나당 25MiB입니다. 이 블로그는 2,441개로 12%를 씁니다.

배포는 쉽지만 그 뒤가 함정입니다 — HTML은 엣지에 캐시되지 않고, www는 자동으로 안 붙고, pages.dev 주소도 같이 공개됩니다.

지난 편에서 워드프레스를 폴더 하나로 내보내는 것까지 했습니다. 이제 그 폴더를 인터넷에 올릴 차례입니다 — Cloudflare Pages 무료 배포입니다.

Cloudflare Pages가 뭔가요?

Cloudflare Pages는 정적 파일 폴더를 받아서 전 세계 서버에 복사해두고, 방문자에게 가장 가까운 곳에서 내보내주는 서비스입니다. 서버를 빌리는 게 아니라 파일을 맡기는 쪽에 가깝습니다.

핵심은 무료 범위가 개인 블로그엔 과할 만큼 넓다는 점입니다.

항목 무료 플랜 한도 이 블로그
배포당 파일 수 20,000개 2,441개 (12%)
파일 하나 크기 25MiB 최대 3.8MB
커스텀 도메인 프로젝트당 100개 1개
월 빌드 횟수 500회 (Git 연동 빌드에만 해당) 해당 없음

마지막 행을 짚고 넘어가겠습니다. 월 500회 빌드 한도는 Git 저장소를 연결해 Cloudflare가 대신 빌드해줄 때 쓰는 숫자입니다. 이 글처럼 이미 만들어진 폴더를 직접 올리는 방식(Direct Upload)은 Cloudflare가 빌드를 돌릴 게 없어서 이 한도를 쓰지 않습니다. 배포 횟수를 세고 있을 필요가 없다는 뜻입니다.

파일 2만 개는 넉넉해 보이지만 워드프레스는 생각보다 파일을 많이 뱉습니다. 다만 그 대부분이 글 수와 무관한 고정분입니다. 2,441개 중 1,826개(75%)가 워드프레스 코어 자산(wp-includes)이고, 글 한 편이 늘 때 실제로 추가되는 건 40개 남짓입니다. 지난 편을 쓸 때 2,391개였던 게 글 두 편이 더해지자 2,441개가 됐습니다. 글이 100편이 돼도 7천 개 언저리라 한도는 한참 남습니다.

Cloudflare Pages 배포 흐름내 맥build 폴더2,441 files · 93MB지난 편의 결과물Cloudflare Pages전 세계 엣지에 복사배포마다 고유 주소 보관되돌리기 가능방문자가장 가까운 엣지에서이미지·CSS는 캐시됨HTML은 매번 원본까지wrangler바뀐 것만무료 한도파일 20,000개개당 25MiB월 500빌드도메인 100개이 블로그는 파일 2,441개 — 한도의 12%
build 폴더를 올리면 Cloudflare가 엣지로 복사한다 — 무료 한도의 12%만 쓰고 있다

배포는 정말 한 줄인가요?

네. 폴더와 프로젝트 이름만 있으면 됩니다.

npx -y wrangler pages deploy build --project-name=aimakelog --branch=main

wrangler는 Cloudflare의 공식 CLI입니다. 처음 쓸 때 npx -y wrangler login으로 브라우저 로그인을 한 번 하면, 이후로는 계정 인증이 유지됩니다.

wrangler pages deploy 실행 결과 화면: 이미 올라간 파일은 건너뛰고 0.52초 만에 배포가 끝났으며, 이어서 없는 주소가 404를 돌려주고 HTML 응답 헤더의 cf-cache-status가 DYNAMIC으로 나온다
실제 실행 화면 — 이미 올라간 파일은 건너뛰고 바뀐 것만 올린다

주목할 부분은 “Uploaded 0 files (2416 already uploaded)” 입니다. 매번 수천 개를 통째로 올리는 게 아니라 바뀐 파일만 올립니다. 글 한 편을 새로 넣은 직전 배포에서는 44개만 올라갔고, 그마저 1.5초에 끝났습니다.

배포마다 71114403.aimakelog.pages.dev 같은 고유 주소가 생깁니다. 이전 배포가 그대로 살아 있다는 뜻이라, 뭔가 잘못되면 대시보드에서 이전 배포로 되돌릴 수 있습니다.

내 도메인은 어떻게 붙이나요?

Cloudflare에서 도메인을 샀다면(이 블로그는 Cloudflare Registrar) 대시보드에서 Pages 프로젝트에 커스텀 도메인을 추가하는 것으로 끝납니다. DNS 레코드와 SSL 인증서가 자동으로 붙습니다.

붙고 나면 DNS가 이렇게 보입니다. CNAME이 아니라 A 레코드입니다.

$ dig +short aimakelog.app
104.21.19.12
172.67.184.111

이유가 둘 겹쳐 있습니다. 하나는 루트 도메인(aimakelog.app)에는 원래 CNAME을 쓸 수 없다는 DNS 규칙이라, Cloudflare가 CNAME을 조회 시점에 펴서 A처럼 응답한다는 것(CNAME 플래트닝). 다른 하나는 이 레코드가 Cloudflare 프록시를 거치고 있어서, 돌아오는 주소가 내 서버가 아니라 Cloudflare 자기네 IP라는 것입니다. 직접 설정할 건 없지만, DNS를 열어보고 “왜 CNAME이 아니지?” 할 때 알고 있으면 편합니다.

배포 뒤에 알게 되는 함정 4개

터미널 확인 화면: HTML은 cf-cache-status DYNAMIC, 이미지는 REVALIDATED로 나오고, dig 결과는 A 레코드 두 개이며, www 주소는 000을 없는 주소는 404를 돌려준다
함정 네 개의 증거를 한 화면에 — 캐시 차이, A 레코드, www 무응답(추가 전), 404 정상 반환

함정 ① 없는 주소가 200을 돌려준다

가장 조용하고 가장 아픈 함정입니다. 404.html이 없으면 Pages는 없는 주소에 대해 홈 화면을 200으로 내보냅니다.

검색엔진은 이걸 소프트 404로 보고, 오타 주소나 죽은 링크가 전부 색인 후보가 됩니다. build/404.html을 넣으면 Pages가 알아서 그 파일을 404 상태로 내보냅니다. 위 화면의 마지막 줄이 넣고 난 뒤의 결과입니다. 이 파일을 만드는 방법은 지난 편에 적어뒀습니다.

함정 ② HTML은 엣지에 캐시되지 않는다

Cloudflare Pages는 이미지·CSS·JS는 엣지에 캐시하지만 HTML은 기본적으로 캐시하지 않습니다. 위 화면의 첫 두 명령이 그 차이입니다.

# HTML
cache-control: public, max-age=0, must-revalidate
cf-cache-status: DYNAMIC

# 이미지
cache-control: public, max-age=14400, must-revalidate
cf-cache-status: REVALIDATED

DYNAMIC은 “엣지 캐시를 안 탄다”는 뜻입니다. 글을 고쳐 배포하면 즉시 반영되는 게 이 덕분입니다.

그럼 느려지느냐 — 재봤더니 그렇지도 않았습니다. 제 맥에서 다섯 번씩 재보니 첫 바이트까지 걸린 시간이 HTML은 평균 0.55초, 엣지 캐시를 타는 이미지는 0.46초였습니다. 그런데 그중 0.3초가량은 양쪽 모두 연결을 맺는 데(DNS·TCP·TLS) 쓴 시간입니다. 즉 캐시 여부가 만드는 차이는 0.1초 남짓이고, 나머지는 캐시로 줄일 수 없는 몫입니다. 캐시 규칙을 따로 걸어 즉시 반영을 포기할 이유가 크지 않다는 뜻입니다. 개인 블로그라면 기본값 그대로 두는 쪽을 권합니다.

함정 ③ www는 자동으로 붙지 않는다

aimakelog.app을 등록해도 www.aimakelog.app은 따로입니다. 확인해 보면 아예 연결이 안 됩니다 — 위 화면의 000이 그것으로, HTTP 상태 코드조차 못 받았다는 뜻입니다.

주소를 손으로 치는 사람이 www를 습관적으로 붙이는 경우가 있으니, 커스텀 도메인에 www도 추가하고 루트로 리다이렉트를 걸어두는 게 안전합니다. 이 글을 쓴 뒤 실제로 추가했고, 지금은 www로 들어와도 열립니다.

그런데 여기서 함정 안의 함정을 하나 더 만났습니다. 리다이렉트 규칙을 걸 때 경로를 보존하도록 설정하지 않으면 모든 주소가 홈으로 떨어집니다.

www.사이트/글-주소/  →  301  →  https://사이트/     ← 글이 아니라 홈

누가 www 붙은 글 링크를 공유하면 받는 사람은 그 글이 아니라 홈페이지를 보게 됩니다. Cloudflare 리다이렉트 규칙에서 경로 접미사 보존(Preserve path suffix)을 켜면 해결됩니다. 규칙을 만든 뒤에는 루트뿐 아니라 글 주소로도 한 번 눌러보고 어디에 도착하는지 확인하세요.

함정 ④ pages.dev 주소도 같이 공개된다

프로젝트를 만들면 프로젝트명.pages.dev가 자동으로 생기고, 커스텀 도메인을 붙여도 그 주소는 계속 살아 있습니다. 같은 내용이 두 주소로 열린다는 뜻이라 중복 콘텐츠가 걱정됩니다.

다행히 정적 내보내기를 제대로 했다면 방어가 이미 돼 있습니다. pages.dev로 연 페이지의 canonical이 실제 도메인을 가리킵니다.

<link rel="canonical" href="https://aimakelog.app/simply-static-export/">

내보낼 때 주소를 전부 실제 도메인으로 치환했기 때문입니다(지난 편의 Force URL replacements). 사이트맵도 실제 도메인만 가리키고요. 그래도 신경 쓰인다면 대시보드에서 pages.dev 접근을 막을 수 있습니다.

기록해둔 함정이 사라져 있었다

이 글을 쓰면서 겪은 일을 하나 남겨둡니다. 이 블로그의 배포 메모에는 “wrangler가 자동화 환경에서 배포를 거부하니 가짜 터미널을 씌워야 한다”고 적혀 있었습니다. 실제로 그때는 그랬고, 그래서 명령 앞에 script -q /dev/null을 붙여 왔습니다.

그런데 글에 쓰려고 다시 재보니 재현되지 않았습니다. 터미널 없이, 가짜 터미널도 없이 그냥 돌려도 배포가 그대로 됩니다.

$ npx -y wrangler pages deploy build --project-name=aimakelog --branch=main < /dev/null
✨ Success! Uploaded 0 files (2416 already uploaded) (0.49 sec)
✨ Deployment complete!

도구가 그새 고쳐진 것인지, 애초에 원인이 다른 데 있었는지는 이제 알 수 없습니다. 확실한 건 메모에 적힌 함정이 지금은 함정이 아니라는 것뿐입니다.

남에게 전할 만한 교훈은 이겁니다. 도구는 계속 바뀌므로 겪었던 함정도 유통기한이 있습니다. 글에 넣기 전에 한 번 더 재보면, 없어진 문제를 붙들고 있느라 명령이 복잡해지는 걸 막을 수 있습니다.

전체 순서 정리

# ① 처음 한 번만 — 브라우저 로그인
npx -y wrangler login

# ② 배포 (지난 편의 내보내기·404·색인이 끝난 뒤)
npx -y wrangler pages deploy build --project-name=<프로젝트> --branch=main

# ③ 도메인은 대시보드에서 커스텀 도메인 추가 — DNS·인증서 자동

정리

  1. Cloudflare Pages 배포는 명령 한 줄 — 바뀐 파일만 올라가서 글 한 편 추가는 1~2초다
  2. 무료 한도는 파일 2만 개·개당 25MiB. 워드프레스는 코어 자산이 76%라 글이 늘어도 파일은 천천히 는다
  3. 월 500빌드 한도는 Git 연동 빌드 얘기다 — 폴더를 직접 올리는 방식에는 해당하지 않는다
  4. 루트 도메인이 A 레코드로 보이는 건 정상이다 (CNAME 플래트닝 + 프록시)
  5. 404.html이 없으면 없는 주소가 200을 돌려준다 — 색인이 오염되는 조용한 사고다
  6. HTML은 엣지 캐시를 안 탄다. 대신 즉시 반영을 얻었고, 실제 속도 차이는 0.1초 남짓이었다
  7. www와 pages.dev 주소는 방치하면 각각 접속 실패와 중복 노출로 남는다

여기까지가 Cloudflare Pages 무료 배포의 전부입니다. 로컬에서 쓴 글이 인터넷에 올라가는 길이 완성됐습니다. 다음 편은 이 사이트로 애드센스를 신청하기까지 남은 일들입니다.

참고 문서Cloudflare Pages 한도파일 수·용량·빌드 공식 수치Cloudflare Pages 요금제무제한 대역폭·요청 명시Direct Upload폴더를 직접 올리는 배포 방식wrangler 명령 문서pages deploy 옵션 전체
Author

AI로 실제 결과물 만드는 실전 기록

RSS
구독
이어서 읽기
aimake.log AI로 실제 결과물 만드는 실전 기록 소개 개인정보처리방침 RSS