GitHub Actions + Cloudflare Pages 자동 배포 — Astro 블로그 CI/CD
📚 1인 인프라 구축기 시리즈 (5편)
Astro 블로그를 GitHub Actions와 Cloudflare Pages로 자동 배포하면서 만난 삽질들. Wrangler v3 설정부터 pnpm 캐시, Secrets 관리, 배포 실패 디버깅까지 실전 트러블슈팅.
💡 Tip. 바쁜 현대인들을 위한 본문 요약
- GitHub Actions + Cloudflare Pages 조합으로
git push만 하면 빌드→배포가 자동으로 돌아간다- Cloudflare Pages의 자체 빌드보다 GitHub Actions에서 빌드 후 Wrangler로 배포하는 게 빠르고 제어가 쉽다
pnpm/action-setup과actions/setup-node의 cache 옵션을 세팅해야 빌드 시간이 반으로 줄어든다- Secrets(
CLOUDFLARE_API_TOKEN,CLOUDFLARE_ACCOUNT_ID)는 Repository Secrets에 넣고 workflow에서 참조한다- 빌드 환경변수(
PUBLIC_GA_ID등)도 Secrets로 관리하면 로컬.env와 CI 환경이 분리된다
블로그를 WordPress에서 Astro로 옮겼다.
로컬에서 pnpm build하고 수동으로 올리면 되긴 한다.
근데 그걸 매번 하고 싶진 않다.
🔧 환경
📌 증상: 수동 배포의 고통

블로그에 글 하나 올리려면:
pnpm build # 빌드
# dist/ 폴더를 어딘가에 업로드...
Cloudflare Pages 대시보드에서 직접 업로드할 수도 있다. 하지만 매번 빌드하고 드래그앤드롭하는 건 2026년에 할 짓이 아니다.
게다가 Cloudflare Pages의 자체 빌드 기능은 있지만:
- 빌드 환경 커스터마이징이 제한적이다
pnpm버전을 정확히 지정하기 까다롭다- 빌드 로그가 GitHub Actions에 비해 빈약하다
결론: GitHub Actions에서 빌드하고, Wrangler로 결과물만 던지자.
📌 원인 분석: 뭐가 필요한가

자동 배포 파이프라인에 필요한 것:
- GitHub Actions workflow —
main브랜치 push 시 트리거 - pnpm + Node.js 세팅 — 의존성 설치와 빌드
- Cloudflare API Token — Pages 배포 권한
- Wrangler CLI —
pages deploy명령
📌 해결: 단계별 구축

1단계: Cloudflare API Token 발급
Cloudflare 대시보드 → My Profile → API Tokens → Create Token
필요한 권한:
- Cloudflare Pages — Edit
- Account — Read (Account ID 조회용)
⚠️ Zone 권한이 아니라 Account 레벨 Pages 권한이다. Zone DNS 토큰과 혼동하지 말 것.
발급받은 토큰과 Account ID를 GitHub Repository Settings → Secrets and variables → Actions에 등록:
| Secret 이름 | 값 |
|---|---|
CLOUDFLARE_API_TOKEN | Pages 배포용 API 토큰 |
CLOUDFLARE_ACCOUNT_ID | Cloudflare 계정 ID |
PUBLIC_GA_ID | Google Analytics 측정 ID (빌드 시 주입) |
2단계: Cloudflare Pages 프로젝트 생성
대시보드에서 Pages 프로젝트를 먼저 만든다:
- 프로젝트 이름:
jongmolee-blog(이후 Wrangler에서 참조) - 프로덕션 브랜치:
main - 빌드 설정: 건너뛴다 (GitHub Actions에서 빌드할 거니까)
커스텀 도메인 연결:
jongmolee.com→ Pages 프로젝트에 Custom Domain 추가- Cloudflare가 자동으로 DNS CNAME을 잡아준다
3단계: GitHub Actions Workflow 작성
.github/workflows/deploy.yml:
name: Deploy to Cloudflare Pages
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
env:
PUBLIC_GA_ID: ${{ secrets.PUBLIC_GA_ID }}
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy dist --project-name jongmolee-blog --branch main
핵심 포인트:
pnpm/action-setup@v4: pnpm을 먼저 설치해야 actions/setup-node의 cache: pnpm이 동작한다. 순서를 바꾸면 캐시가 안 잡힌다.
--frozen-lockfile: lockfile과 package.json이 어긋나면 CI에서 바로 에러를 터뜨린다. 로컬에서 pnpm install 후 lockfile 커밋하는 습관이 필수.
permissions: deployments: write가 있어야 GitHub Deployments 탭에 배포 상태가 기록된다.
cloudflare/wrangler-action@v3: Wrangler를 직접 설치할 필요 없이 Action이 알아서 해준다. command에 pages deploy를 넣으면 끝.
📌 삽질 로그
삽질 1: cache: pnpm이 안 먹힌다
Error: Could not determine pnpm store directory
원인: actions/setup-node보다 pnpm/action-setup이 먼저 와야 한다. pnpm이 설치되지 않은 상태에서 cache를 잡으려 하면 store 경로를 못 찾는다.
해결: 위 workflow처럼 pnpm/action-setup → actions/setup-node 순서를 지킨다.
삽질 2: 빌드는 되는데 페이지가 안 뜬다
Wrangler가 성공했다고 뜨는데 실제 URL에 접속하면 404.
원인: --project-name이 Cloudflare Pages 대시보드의 프로젝트 이름과 정확히 일치해야 한다. 대소문자, 하이픈 하나라도 다르면 새 프로젝트가 생기거나 404가 뜬다.
해결: 대시보드에서 프로젝트 이름을 복사해서 붙여넣기.
삽질 3: 환경변수가 빌드에 안 들어간다
Astro에서 import.meta.env.PUBLIC_GA_ID가 undefined.
원인: Cloudflare Pages의 환경변수 설정에 넣어봤자, 우리는 Pages 자체 빌드를 안 쓰고 있다. GitHub Actions에서 빌드하니까 GitHub Secrets에서 env로 넘겨야 한다.
해결: workflow의 pnpm build 스텝에 env를 명시적으로 지정.
- run: pnpm build
env:
PUBLIC_GA_ID: ${{ secrets.PUBLIC_GA_ID }}
삽질 4: Wrangler 버전 충돌
Error: Unknown argument: pages
원인: wrangler-action@v2가 Wrangler 2.x를 설치하는데, pages deploy는 Wrangler 3.x 기능이다.
해결: cloudflare/wrangler-action@v3을 쓴다. v3 Action이 Wrangler 3.x를 설치해준다.
📌 예방: 이런 패턴을 쓰자

CI 전 로컬 검증 체크리스트
pnpm install --frozen-lockfile # lockfile 정합성 확인
pnpm build # 빌드 에러 사전 차단
이 두 명령이 로컬에서 통과하면 CI에서도 통과한다.
배포 상태 모니터링
GitHub → Actions 탭에서 배포 이력 확인 가능. 실패하면 이메일 알림이 온다.
Cloudflare Pages 대시보드 → Deployments에서도 배포 이력과 롤백이 가능하다.
Preview 배포 (보너스)
main이 아닌 브랜치에서도 배포하고 싶다면:
on:
push:
branches: [main]
pull_request:
branches: [main]
PR을 올리면 Cloudflare Pages가 Preview URL을 자동 생성한다. 프로덕션 반영 전에 미리 확인 가능.
📌 정리

| 항목 | 내용 |
|---|---|
| 구성 | GitHub Actions → pnpm build → Wrangler pages deploy → Cloudflare Pages |
| 비용 | 전부 무료 (GitHub Actions Free Tier + Cloudflare Pages Free) |
| 빌드 시간 | 캐시 적용 후 약 40~60초 |
| 핵심 삽질 | pnpm/action-setup 순서, project-name 정확히 일치, 환경변수는 GitHub Secrets에서 |
| 예방 | 로컬에서 --frozen-lockfile + build 통과 확인 후 push |
git push origin main — 이 한 줄이면 블로그가 올라간다. 수동 배포는 이제 역사 속으로.
📚 1인 인프라 구축기 시리즈 (5편)
- 1. Oracle ARM + Docker로 WordPress 4사이트 운영하기
- 2. Cloudflare Full Strict SSL + Nginx 리버스 프록시 삽질 총정리
- 3. CouchDB + Obsidian LiveSync로 메모 동기화 구축하기
- 4. Umami 셀프호스팅 — Docker 설치부터 AdBlock 우회까지
- 5. GitHub Actions + Cloudflare Pages 자동 배포 — Astro 블로그 CI/CD