Astro + Cloudflare Pages 블로그 스택 분석 | Vercel·Netlify

이 글의 핵심

Astro + Cloudflare Pages 블로그 스택의 실전 장단점을 정리합니다. 속도·비용·개발 경험·SEO·확장성을 Next.js + Vercel, Hugo + Netlify, WordPress와 비교하고, Workers 런타임·KV/D1/R2·Astro 어댑터·프로덕션 엣지 배포까지 심화 분석합니다.

들어가며

기술 블로그를 어떤 스택으로 만들지는 취향 문제만이 아닙니다. 페이지 속도, 호스팅 비용, 유지보수 부담, 검색 노출, 나중에 붙일 동적 기능의 난이도가 모두 스택에 따라 달라지기 때문입니다. 이 글은 Astro + Cloudflare Pages로 블로그를 운영하면서 드러난 장단점을 정리하고, Next.js + Vercel, Hugo + Netlify, WordPress, Ghost와 비교해 어떤 상황에서 다른 스택이 더 나은지 판단하는 기준을 제시합니다. Astro 블로그 구축 방법은 Astro로 기술 블로그 만들기에서, Cloudflare Pages 배포는 Cloudflare Pages 배포를 참고하세요.


Astro + Cloudflare Pages 장점

1-1. 속도: 기본 JS 없음 + 글로벌 CDN

Astro는 기본적으로 클라이언트 JavaScript를 보내지 않습니다. 빌드 결과는 HTML과 CSS이고, 인터랙션이 필요한 컴포넌트에만 client:load·client:visible 같은 지시어를 붙여 아일랜드로 하이드레이션합니다. 그래서 첫 화면을 그리기 전에 내려받고 실행해야 할 스크립트가 거의 없고, 모바일 Lighthouse 점수도 높게 나오기 쉽습니다.

TTFB는 HTML이 사용자와 가까운 PoP의 엣지 캐시에서 바로 나갈 때 가장 짧아집니다. 다만 HTML이 실제로 엣지 캐시에 올라가는지는 캐시 규칙 설정에 따라 다르므로, 응답의 cf-cache-status 헤더로 HIT가 나오는지 확인해야 합니다. DYNAMIC이 계속 보인다면 정적 파일이라도 매번 캐시를 거치지 않고 서빙되고 있다는 뜻입니다.

비교하면, Next.js는 페이지를 정적으로 내보내더라도 React 런타임과 하이드레이션 코드가 함께 실려 초기 JS 번들이 커지기 쉽습니다. WordPress는 요청마다 PHP가 템플릿과 플러그인을 실행하므로, 페이지 캐시 플러그인이나 리버스 프록시 캐시 없이는 TTFB가 길어집니다.

1-2. 비용: 정적 자산 대역폭 무료

항목Cloudflare Pages (Free)Vercel (Hobby)Netlify (Free, 구 요금제)
대역폭정적 자산 무제한월 100GB월 100GB
빌드월 500회사용량 한도 있음월 300분
상업적 이용가능비상업용만 허용가능

표의 수치는 각 서비스의 무료 플랜 기준이며, 요금제는 자주 바뀝니다(Netlify는 2025년에 신규 계정을 크레딧 기반 요금제로 바꿨습니다). 결정하기 전에 반드시 공식 요금 페이지를 확인하세요. 핵심 차이는 Cloudflare Pages가 정적 자산 전송량에 과금하지 않는다는 점입니다. 트래픽이 갑자기 몰려도 정적 페이지만 서빙한다면 청구서가 늘지 않습니다. 반면 Pages Functions 호출은 Workers 요청으로 집계되어 무료 플랜의 일일 요청 한도를 공유하므로, 조회수 API처럼 페이지마다 함수를 부르는 기능을 붙이면 그 부분은 따로 계산해야 합니다. Vercel Hobby 플랜은 비상업적 용도로 제한되므로, 광고를 붙이는 블로그라면 약관상 Pro 플랜이 필요할 수 있습니다.

1-3. 보안: 서버 코드가 없음

정적 사이트는 요청을 처리하는 서버 측 코드와 데이터베이스가 없으므로 공격 표면이 작습니다. PHP나 DB 취약점, 오래된 플러그인을 통한 침입 같은 WordPress의 대표적인 사고 유형이 구조적으로 생기지 않고, 대규모 트래픽 공격은 Cloudflare 네트워크가 앞단에서 흡수합니다. 다만 공격 표면이 0이 되는 것은 아닙니다. 빌드에 쓰는 npm 의존성, CI 비밀값, 나중에 추가한 Functions 코드는 여전히 관리 대상입니다. WordPress는 코어·플러그인·테마 보안 업데이트를 계속 따라가야 하고, 플러그인 하나의 SQL 인젝션이나 XSS가 사이트 전체의 위험이 됩니다.

1-4. 개발자 경험: Git + 마크다운

글 작성 흐름은 로컬에서 마크다운을 쓰고, 커밋해서 푸시하면 자동으로 빌드·배포되고, 브랜치마다 프리뷰 URL이 생기는 구조입니다. 글이 코드와 같은 저장소에 있으므로 변경 이력은 Git 히스토리에 남고, 다른 사람의 검토는 PR로 받을 수 있으며, 잘못 배포했을 때는 이전 커밋으로 되돌리거나 대시보드에서 이전 배포로 롤백하면 됩니다. 반면 WordPress는 글이 DB에 있어서 리비전 기능은 있지만 사이트 전체를 특정 시점으로 되돌리려면 DB 백업과 복원이 필요합니다.

1-5. 확장성: Pages Functions + D1/KV/R2

Cloudflare Pages는 Workers 기반의 Functions로 서버 로직을 엣지에서 실행할 수 있습니다. 조회수 API는 D1(SQLite)에, 간단한 캐시나 플래그는 KV에, 이미지 원본은 R2에 두는 식으로 정적 사이트에 필요한 만큼만 동적 기능을 붙일 수 있습니다. 예를 들어 조회수를 올리고 현재 값을 돌려주는 함수는 다음과 같습니다.

// functions/api/views.js
export async function onRequest(context) {
  const slug = new URL(context.request.url).searchParams.get('slug');
  if (!slug) {
    return new Response('slug is required', { status: 400 });
  }

  // 행이 없으면 1로 만들고, 있으면 1 증가시킨 뒤 새 값을 돌려받음
  const row = await context.env.DB
    .prepare(
      `INSERT INTO views (slug, count) VALUES (?, 1)
       ON CONFLICT(slug) DO UPDATE SET count = count + 1
       RETURNING count`
    )
    .bind(slug)
    .first();

  return Response.json({ views: row.count });
}

UPDATE ... WHERE slug = ?만 쓰면 처음 조회되는 글은 행이 없어서 아무것도 갱신되지 않고, 이어지는 SELECT가 null을 돌려줘 result.count에서 예외가 납니다. 위처럼 UPSERT와 RETURNING을 쓰면 쿼리 한 번으로 생성·증가·조회가 끝납니다. 이 함수를 쓰려면 views 테이블의 slug에 기본 키나 UNIQUE 제약이 있어야 하고, 프로젝트 설정에서 D1 데이터베이스를 DB라는 이름으로 바인딩해야 합니다.


단점과 트레이드오프

2-1. 비개발자 편집이 어려움

WordPress는 웹 에디터로 누구나 글을 쓸 수 있지만, Astro는 마크다운과 Git을 알아야 합니다. Contentful·Strapi·Sanity 같은 헤드리스 CMS를 연동하거나, TinaCMS·Decap CMS(구 Netlify CMS)처럼 Git 저장소에 직접 커밋해 주는 CMS를 붙이면 편집 화면을 제공할 수 있습니다. Notion을 원고 저장소로 쓰고 빌드 시 API로 가져오는 방법도 있습니다. 어느 쪽이든 구성 요소가 하나 늘어나므로 설정과 유지보수 부담이 생기고, 호스팅형 CMS는 무료 플랜의 사용자 수나 API 호출 제한을 확인해야 합니다.

2-2. 플러그인 생태계가 작음

WordPress 공식 디렉터리에는 5만 개가 넘는 플러그인이 있어 SEO(Yoast SEO), 폼(Contact Form 7), 분석 도구를 클릭 몇 번으로 붙일 수 있습니다. Astro에서는 메타 태그는 레이아웃 컴포넌트에 직접 작성하고, 폼은 Functions나 외부 폼 서비스로 처리하며, 분석 스크립트도 직접 넣어야 합니다. 사이트맵·RSS·MDX처럼 공식 통합(@astrojs/sitemap, @astrojs/rss, @astrojs/mdx)이 있는 기능도 있지만, 대부분은 초기 설정에 시간이 듭니다. 대신 쓰지 않는 기능이 페이지에 끼어들지 않아 결과물이 가볍게 유지됩니다.

2-3. 페이지가 많을 때의 빌드 시간

SSG는 모든 페이지를 빌드 시점에 렌더링하므로 빌드 시간이 페이지 수에 비례해 늘어납니다. 글이 천 개 단위로 쌓이고 페이지마다 OG 이미지 생성, 코드 하이라이팅, 다이어그램 렌더링 같은 작업이 붙으면 빌드가 수 분 단위로 길어지고, 메모리 부족으로 Node 힙 크기를 늘려야 하는 경우도 생깁니다. Hugo는 Go로 작성된 단일 바이너리라 같은 규모에서 빌드가 훨씬 빠른 편이지만, 컴포넌트 기반 작성이나 MDX의 유연성은 Astro 쪽이 큽니다.

시간을 줄이는 방법으로는 build.concurrency 옵션으로 페이지 렌더링을 병렬화하고, OG 이미지처럼 비싼 산출물은 원본이 바뀐 글만 다시 만들도록 캐시하는 것이 있습니다. Astro 5의 Content Layer는 콘텐츠 데이터를 .astro/data-store.json에 캐시해 변경되지 않은 항목의 처리를 건너뛰지만, 페이지 HTML 자체는 매번 다시 렌더링하므로 완전한 증분 빌드는 아닙니다.

2-4. 실시간 기능은 직접 붙여야 함

정적 사이트에는 댓글·조회수·검색 같은 기능이 기본으로 없습니다. 댓글은 GitHub Discussions를 쓰는 Giscus나 Utterances로, 조회수는 앞의 Functions + D1 예제처럼, 검색은 빌드 시 정적 인덱스를 만드는 Pagefind나 Algolia 같은 외부 서비스로 해결하는 경우가 많습니다. WordPress는 DB 기반이라 이런 기능이 기본으로 들어 있습니다.


다른 스택과 비교

3-1. Next.js + Vercel

항목Astro + Cloudflare PagesNext.js + Vercel
클라이언트 JS필요한 아일랜드만React 런타임 + 하이드레이션
무료 플랜 대역폭정적 자산 무제한월 100GB
서버 렌더링Workers 런타임(Web API 중심)ISR, 서버 컴포넌트, Node 런타임
전제 지식HTML·마크다운 위주React 필수

콘텐츠가 대부분 정적이고 인터랙션이 적다면 Astro가 맞습니다. 빌드 시점에 HTML이 완성되므로 CDN 캐시 효율이 좋고, React를 모르는 사람도 마크다운만으로 글을 쓸 수 있습니다. 반대로 대시보드나 인터랙티브 UI 비중이 크거나, ISR(Incremental Static Regeneration)로 일부 페이지만 주기적으로 다시 생성하고 싶거나, React 생태계의 라이브러리를 적극 활용해야 한다면 Next.js + Vercel이 개발 경험 면에서 매끄럽습니다.

3-2. Hugo + Netlify

항목Astro + Cloudflare PagesHugo + Netlify
빌드 속도페이지가 많아지면 느려짐대규모에서도 빠른 편
컴포넌트React·Vue·Svelte 등 사용 가능Go 템플릿과 shortcode
학습 부담JavaScript 생태계 지식Go 템플릿 문법

수천에서 수만 페이지 규모의 문서 사이트처럼 빌드 속도가 가장 중요하고 템플릿이 단순하다면 Hugo가 유리합니다. MDX로 인터랙티브 예제를 넣거나 기존 React·Vue 컴포넌트를 재사용하고 싶고, 팀이 JavaScript 생태계에 익숙하다면 Astro가 맞습니다.

3-3. WordPress

항목Astro + Cloudflare PagesWordPress
서빙 방식미리 만든 정적 HTML요청마다 PHP·DB 렌더링(캐시로 보완)
호스팅 비용무료 플랜으로 시작 가능서버 또는 관리형 호스팅 비용
보안 관리빌드 의존성 위주코어·플러그인·테마 업데이트 필수
편집마크다운·Git웹 에디터
기능 추가직접 구현플러그인

비개발자가 글을 쓰거나, 회원·댓글·결제 같은 기능을 플러그인으로 빠르게 붙여야 한다면 WordPress가 낫습니다. 코드 예제가 많은 개발자 블로그이고 속도·보안·비용을 우선하며 글을 Git으로 관리하고 싶다면 Astro가 낫습니다. SEO 측면에서는 두 쪽 모두 메타 태그와 사이트맵을 제대로 갖출 수 있으며, 차이는 주로 페이지 속도에서 생깁니다.

3-4. Ghost

Ghost는 Node.js 기반 블로그 플랫폼으로, WordPress보다 가볍고 뉴스레터·유료 구독 기능이 기본으로 들어 있습니다. 직접 호스팅하거나 유료 관리형 서비스(Ghost(Pro))를 쓰는데, 관리형은 구독 비용이 듭니다. 웹 에디터에서 마크다운으로 글을 쓸 수 있고 여러 작성자의 권한 관리도 제공하므로, 뉴스레터·유료 구독 모델을 운영하거나 여러 사람이 함께 쓰는 블로그라면 Ghost가 Astro보다 손이 덜 갑니다. 회원 기능을 Astro에서 직접 구현하려면 인증·결제·이메일 발송을 모두 따로 붙여야 합니다.


엣지 컴퓨팅 심화: Workers 런타임·데이터·Astro 어댑터

스택 비교만으로는 “왜 Cloudflare가 특정 워크로드에 잘 맞으며, 어디서 한계가 오는지”가 드러나지 않습니다. 이 절에서는 Cloudflare Workers 런타임, 전통적 SSR과의 구조적 차이, KV·D1·R2 접근 패턴, Astro Cloudflare 어댑터의 결합 방식, 프로덕션 배포 패턴을 엔지니어링 관점에서 정리합니다.

4-1. Cloudflare Workers 런타임 아키텍처

Workers는 요청마다 새로운 운영체제 프로세스나 컨테이너를 띄우는 모델이 아닙니다. 대표적으로 다음과 같은 특성을 가집니다.

  • V8 기반 격리(isolate): 사용자 코드는 V8 격리 단위로 로드되며, 플랫폼이 정한 CPU 시간·메모리·동시성 제약 안에서 실행됩니다. “항상 켜진 Node 서버”처럼 긴 생명주기를 가정하기 어렵으며, 짧은 HTTP 요청 처리에 최적화된 실행 모델입니다.
  • Web Standards 중심 API: fetch·Request·Response·ReadableStream 등 브라우저와 유사한 API가 기본입니다. Node의 fs·child_process·일부 네이티브 모듈에 의존하는 코드는 그대로 옮기기 어렵으며, 폴리필·재설계·별도 마이크로서비스로 분리하는 편이 안전합니다.
  • compat date·런타임 버전: compatibility_date 등으로 런타임 동작(예: fetch·URL 관련 세부 동작)을 고정할 수 있습니다. 팀 단위로 재현 가능한 배포를 하려면 날짜를 명시하며, 변경 시 회귀 테스트를 두는 것이 좋습니다.
  • I/O와 CPU의 비율: Edge는 지리적으로 가까운 곳에서 응답을 만들어 RTT를 줄이는 데 강점이 있습니다. 반면 대용량 압축·영상 트랜스코딩·장시간 CPU 연산은 플랫폼 한도와 비용 측면에서 부적합할 수 있어, 배치·워크플로(Queue·외부 워커)로 넘기는 설계가 흔합니다.
  • 글로벌 배치와 상태: 코드는 여러 PoP에 걸쳐 배포되지만, 로컬 디스크에 영속 상태를 쌓는 패턴은 맞지 않습니다. 상태는 D1·R2·KV 같은 관리형 스토리지나 원격 API에 두며, Worker는 오케스트레이션·검증·캐시·집계 역할에 집중하는 것이 일반적입니다.

요약하면 Workers는 “가벼운 요청 단위 컴퓨트 + 표준 Web API + 관리형 백엔드 스토리지” 조합으로 이해하는 것이 정확합니다.

4-2. 엣지 컴퓨트 vs 전통적 SSR(리전 고정)

관점엣지(Workers/Pages Functions)전통적 SSR(리전 고정 VPS·매니지드 컨테이너)
지연사용자와 가까운 PoP에서 실행 → TTFB·핸드셰이크 비용 감소에 유리오리진 리전이 멀면 RTT 누적. 다만 DB와 같은 AZ에 붙이면 쿼리 지연은 안정적
일관성전 세계에 퍼진 실행 단위 → 캐시·복제 지연을 염두에 둔 설계 필요단일 리전 DB에 가까우면 강한 일관성을 얻기 쉬움
연결 풀서버리스형 실행 모델에서는 DB 커넥션 풀링이 까다로울 수 있음(플랫폼·드라이버·Hyperdrive 등 아키텍처로 보완)장기 프로세스에서 풀·세션 관리가 익숙한 패턴
실행 한도CPU 시간·메모리 등 상한이 명확인스턴스 스펙으로 확장 가능하나 운영·비용 부담
API 호환Web API 중심Node 생태계·파일 시스템·서브프로세스 활용 용이

블로그 관점에서의 실무적 결론은 다음과 같습니다. 본문 HTML은 SSG로 빌드해 CDN에 올리고, 동적 기능(조회수·폼·인증 훅)만 Worker에서 처리하면 엣지의 강점과 단순한 운영을 동시에 가져가기 쉽습니다. 반면 복잡한 권한·실시간 협업·무거운 서버 사이드 렌더링 파이프라인은 리전 고정 풀스택이나 별도 BFF가 더 잘 맞는 경우가 많습니다.

4-3. KV·D1·R2 데이터 접근 패턴

Cloudflare의 스토리지 계층은 역할이 뚜렷히 다릅니다. 같은 “서버리스 DB”처럼 섞어 부르기 쉬우나, 일관성 모델·지연·비용이 달라 설계를 갈라야 합니다.

Workers KV

  • 키·값 저장에 특화된 최종 일관성(eventual consistency) 저장소입니다. 쓴 값이 다른 지역의 읽기에 반영되기까지 최대 수십 초(공식 문서 기준 보통 60초 이내)가 걸릴 수 있으므로, 강한 일관성이 필요한 카운터나 장부형 데이터에는 맞지 않습니다.
  • 읽기 빈도가 높으며, 약간의 지연이 허용되는 데이터(Feature flag, 세션 토큰, 집계 캐시, CDN 친화적 메타데이터)에 잘 맞습니다.
  • 쓰기는 단일 키 단위로 단순하게 유지하고 읽기는 캐시로 취급합니다. 원본 데이터는 D1이나 외부 DB에 두고 KV에는 파생 데이터만 두는 패턴이 안전합니다.

D1 (SQLite)

  • 관계형·SQL·트랜잭션이 필요할 때 선택합니다. 블로그의 조회수·좋아요·간단한 댓글 메타처럼 소규모 강한 일관성이 필요한 데이터에 적합합니다.
  • 마이그레이션은 빌드·배포 파이프라인에 묶고, API 레이어에서는 prepared statement로 SQL 인젝션을 막으며 정해진 쿼리만 노출합니다.
  • 대규모 OLTP·초저지연 글로벌 단일 복제를 기대하면 설계가 빠듯할 수 있어, 접근 빈도·데이터 크기를 모니터링하며 아키텍처를 재평가해야 합니다.

R2 (S3 호환 오브젝트 스토리지)

  • 이미지·첨부·백업·정적 자산 원본에 적합합니다. HTML 페이지 전부를 R2에서 직접 조합하기보다는 빌드 산출물은 Pages, 원본 미디어는 R2로 나누는 경우가 많습니다.
  • 업로드는 서명 URL이나 전용 업로드 Worker로 받고, 공개 읽기는 커스텀 도메인이나 퍼블릭 버킷 설정으로 열며, 변환 작업은 별도 Worker나 Queue로 분리합니다.

세 가지를 함께 쓰는 계층화 예시는 다음과 같습니다.

  1. SSG HTML·자산 → Pages CDN (캐시 히트율 최대화)
  2. 동적 API → Worker + D1(트랜잭션) + KV(캐시/속도)
  3. 대용량 파일 → R2 + 필요 시 캐시 헤더·이미지 리사이즈 전략

이렇게 나누면 비용·일관성·운영 난이도의 균형을 맞추기 쉽습니다.

4-4. Astro ↔ Cloudflare 어댑터 통합 메커니즘

@astrojs/cloudflare는 “Astro 빌드 산출물을 Cloudflare 런타임이 이해하는 형태로 포장”하는 역할을 합니다. 개념적으로 다음 층으로 나눌 수 있습니다.

  1. 빌드 타임: Astro는 페이지·엔드포인트·하이브리드 모드에 따라 정적 자원과 서버 엔트리를 생성합니다. Cloudflare 대상 빌드에서는 Workers/Pages Functions 환경에서 동작 가능한 번들을 지향합니다.
  2. 런타임 어댑터: Node 전용 API 대신 Web 표준 요청/응답을 사용하는 경로로 연결합니다. 개발자는 Astro.locals·미들웨어·서버 엔드포인트에서 Request/Response 모델을 다루게 됩니다.
  3. 배포 산출물: Pages에 올라가는 패키지는 정적 파일과 함수 번들의 조합입니다. 라우팅은 Cloudflare 쪽 규칙(예: Functions 디렉터리·_routes.json 등)과 맞물려 어떤 URL이 Worker로 가고 어떤 URL이 순수 정적 파일로 가는지가 결정됩니다.
  4. 바인딩: wrangler.toml 또는 대시보드에서 D1·KV·R2·시크릿을 Worker에 연결하면, 런타임에서 env 객체로 주입됩니다. Astro 쪽에서는 서버 코드에서만 안전하게 참조하도록 구조화하는 것이 중요합니다(클라이언트 번들 유출 방지).

“로컬에서는 Node, 프로덕션은 Workers”라는 이중성이 생기기 쉬우므로, 가능하면 Web API에 맞춘 유틸을 공유하며, 환경 의존 코드는 어댑터 경계에 모읍니다.

4-5. 프로덕션 엣지 배포 패턴

운영 품질은 코드만으로 결정되지 않고 배포·비밀·캐시·관측의 합입니다.

  • 프리뷰·프로덕션 분리: Git 브랜치별 프리뷰 URL로 UI·API 변경을 검증한 뒤 메인에 합류합니다. 동적 API가 있다면 프리뷰 전용 D1/KV를 어떻게 둘지(공유 vs 격리) 팀 규칙이 필요합니다.
  • 시크릿 관리: API 키·서명 시크릿은 저장소에 넣지 않고 Cloudflare Secrets 또는 CI의 안전한 주입 경로를 사용합니다. 로테이션 절차를 문서화합니다.
  • 캐시 헤더: 정적 자산은 Cache-Control으로 장기 캐시 + 파일명 해시, HTML은 짧은 TTL 또는 no-cache 등 콘텐츠 성격에 맞게 분리합니다. “전부 max-age=1년” 같은 실수가 SEO·배포 가시성을 해칠 수 있습니다.
  • 관측: Workers 로그·요청 메트릭을 통해 p95 지연·에러율을 본 뒤, D1 쿼리 비용·KV 읽기가 병목인지 판별합니다.
  • 마이그레이션·릴리스: D1 스키마 변경은 하위 호환 마이그레이션을 전제로, 배포 순서(expand → migrate → contract)를 지키면 다운타임을 줄일 수 있습니다.
  • 한도와 폴백: Worker 시간 초과·스로틀링이 발생하면 캐시 응답·정적 폴백·큐 적재 등 우아한 실패 전략을 준비합니다.

이 절의 내용은 “Astro + Pages가 단순 정적 호스팅이 아니라, 엣지 런타임·스토리지·어댑터가 맞물린 플랫폼”이라는 점을 이해하는 데 목적이 있습니다. 스택을 선택할 때 기능을 “만들 수 있나”뿐 아니라 “운영 가능한가”를 함께 보시길 권합니다.


실전 운영에서 드러나는 점

5-1. 운영하면서 체감되는 장점

가장 큰 장점은 배포 후 서버를 신경 쓸 일이 거의 없다는 것입니다. 정적 HTML이라 트래픽이 갑자기 몰려도 애플리케이션 서버가 죽는 상황이 없고, 정적 자산 전송에는 과금이 없으므로 비용도 예측하기 쉽습니다. WordPress라면 트래픽이 늘 때 서버 사양이나 캐시 구성을 다시 봐야 합니다.

글을 Git으로 관리하는 것도 실제로 편합니다. 초안은 브랜치에 두고, 큰 수정은 PR 프리뷰로 확인한 뒤 합치며, 잘못 고친 글은 git revert로 되돌립니다. 여러 글에 걸친 일괄 수정도 스크립트로 처리하고 diff로 검토할 수 있습니다.

코드 예제가 많은 블로그라면 MDX도 장점입니다. @astrojs/mdx와 UI 프레임워크 통합(예: @astrojs/react)을 설치하면 글 안에 컴포넌트를 넣을 수 있습니다.

import CodePlayground from '../components/CodePlayground.jsx';

<CodePlayground client:visible code="console.log('Hello')" />

여기서 client:visible 같은 지시어를 빼면 컴포넌트는 서버에서 HTML로만 렌더링되고 브라우저에서 동작하지 않습니다. Astro에서 “왜 버튼이 안 눌리지” 하는 문제의 상당수가 이 지시어 누락입니다.

5-2. 운영하면서 부딪히는 단점

빌드 시간은 글이 늘수록 체감됩니다. 오타 하나를 고쳐도 전체 사이트를 다시 빌드해야 배포되므로, 수정 확인은 로컬 npm run dev로 하고 배포는 여러 수정을 모아서 하는 편이 낫습니다.

댓글·조회수·검색은 앞에서 본 대로 Giscus, Functions + D1, Pagefind 같은 도구를 직접 조합해야 하고, 비개발자와 함께 쓰려면 Git 기반 CMS를 추가해야 해서 구성 요소가 늘어납니다.

이미지 처리는 Astro 내장 기능을 쓰는지에 따라 달라집니다. src/ 아래에 둔 이미지를 astro:assets의 <Image /> 컴포넌트로 불러오면 빌드 시 크기 조정과 WebP 변환이 자동으로 됩니다. 하지만 public/에 넣은 파일은 손대지 않고 그대로 복사되므로, 마크다운에서 public/ 경로로 이미지를 참조해 왔다면 별도 스크립트로 최적화해야 합니다.

// scripts/optimize-images.mjs
import sharp from 'sharp';

await sharp('public/images/photo.jpg')
  .resize(1200)
  .webp({ quality: 80 })
  .toFile('public/images/photo.webp');

선택 기준

6-1. 질문으로 판단하기

질문예아니오
개발자 혼자 운영하는가?Astro + Cloudflare PagesWordPress·Ghost
인터랙티브 UI가 많은가?Next.js + VercelAstro + Cloudflare Pages
빌드 속도가 최우선인가?HugoAstro
회원·결제·뉴스레터가 필요한가?Ghost·WordPressAstro (필요하면 직접 구현)
트래픽 증가에 따른 비용이 걱정되는가?Cloudflare Pages어느 호스팅이든 무방

6-2. 사이트 유형별 추천

코드 예제가 많은 개인 기술 블로그나 프로젝트 소개를 겸한 포트폴리오에는 Astro + Cloudflare Pages가 잘 맞습니다. 속도, 무료 호스팅, Git 기반 관리, MDX를 모두 활용할 수 있기 때문입니다. 비개발자가 함께 쓰는 팀 블로그라면 웹 에디터와 권한 관리가 있는 Ghost나 WordPress가 낫습니다. 수천 페이지 이상의 문서 사이트는 빌드 속도 때문에 Hugo가 유리하고, 회원·구독과 이메일 연동이 중요한 제품 블로그는 Ghost나 Next.js + Vercel이 맞습니다.


마이그레이션 고려사항

7-1. WordPress → Astro

옮기면 정적 HTML 서빙으로 페이지가 빨라지고 서버 호스팅 비용과 플러그인 보안 업데이트 부담이 사라집니다. 대신 HTML로 저장된 글을 마크다운으로 변환해야 하고, 플러그인이 하던 기능(SEO 메타, 폼, 관련 글 등)을 다시 구현해야 하며, 업로드 이미지 경로도 정리해야 합니다. 변환에는 WordPress 내보내기 XML을 마크다운으로 바꿔 주는 wordpress-export-to-markdown 같은 도구를 쓸 수 있습니다. 기존 URL 구조가 바뀐다면 검색 순위를 지키기 위해 301 리디렉션 목록을 만들어 _redirects에 넣어야 합니다.

7-2. Next.js → Astro

블로그가 대부분 정적 콘텐츠이고 Vercel 대역폭이나 요금제가 부담된다면 고려할 만합니다. 빌드 결과가 단순한 HTML이 되고 클라이언트 JS가 줄어듭니다. 대신 서버 컴포넌트나 클라이언트 상태에 의존하던 React 컴포넌트는 아일랜드로 옮기거나 다시 작성해야 하고, ISR로 주기적으로 갱신하던 페이지는 SSG 재빌드나 Functions 기반 렌더링으로 캐시 전략을 바꿔야 합니다.


다음 단계

스택을 정했다면 구현은 다음 글을 참고하세요.

참고 자료:


같이 보면 좋은 글