마지막 수정:

Astro와 Cloudflare Pages로 정적 블로그를 시작하는 이유


개인 블로그를 여러 개 운영하려면 서버를 직접 관리하는 방식이 부담이 될 수 있습니다. 저는 첫 번째 블로그를 Astro와 Cloudflare Pages 조합으로 시작했습니다.

이 선택은 “최신 기술을 써보고 싶어서”라기보다, 장기적으로 반복 가능한 구조가 필요했기 때문입니다. 글은 Markdown으로 관리하고, 배포는 GitHub push와 Cloudflare Pages에 맡기는 방식입니다.

실제 구성

이 글을 업데이트한 시점의 구성은 아래와 같습니다.

프로젝트: daejin-lab-blog
프레임워크: Astro
콘텐츠: Markdown
저장소: GitHub private repo
배포: Cloudflare Pages
공개 주소: https://daejin-lab-blog.pages.dev
빌드 명령: npm run build
출력 폴더: dist
Node 버전: 22 계열

현재는 커스텀 도메인을 바로 붙이지 않고 pages.dev 주소로 Search Console까지 연결했습니다. 도메인 이름을 확정하기 전에 canonical과 sitemap을 바꾸면 나중에 더 헷갈릴 수 있어서입니다.

좋았던 점

정적 블로그는 구조가 단순합니다.

서버 관리가 거의 없다.
HTML을 미리 만들어 CDN에서 제공한다.
Markdown 파일로 글을 관리할 수 있다.
GitHub 이력으로 변경사항이 남는다.
Cloudflare Pages 무료 범위에서 시작할 수 있다.

개인 프로젝트에서는 이 단순함이 중요했습니다. 글을 쓰는 것보다 배포와 유지보수에 시간이 빨려 들어가면 오래 운영하기 어렵습니다.

실제로 불편했던 점

장점만 있지는 않았습니다. 초반에 막힌 부분은 대부분 글 작성이 아니라 주변 설정이었습니다.

Cloudflare에서 Workers와 Pages 화면을 헷갈림
GitHub HTTPS 인증이 자동화 세션에서 막힘
Search Console sitemap이 처음에 다른 도메인을 가리킴
Astro site 설정과 robots.txt 주소를 다시 맞춤

특히 sitemap 문제는 예상보다 오래 봤습니다. 처음에는 파일이 없는 줄 알았지만, 실제 원인은 URL 기준값이었습니다.

기존 후보: https://daejinlab.com/sitemap-index.xml
현재 기준: https://daejin-lab-blog.pages.dev/sitemap.xml

Search Console 속성은 pages.dev로 등록했는데 sitemap 안쪽 주소가 다른 도메인을 가리키면 문제가 생깁니다. 정적 블로그는 서버가 없어도 이런 기준값은 직접 맞춰야 합니다.

확인한 명령어

배포 전에는 로컬에서 먼저 빌드합니다.

npm run build

그리고 sitemap 파일도 확인합니다.

dist/sitemap.xml
dist/sitemap-index.xml
dist/sitemap-0.xml

최근 빌드에서는 47개 페이지가 생성됐고, 공개 /sitemap.xml 기준 URL 47개가 확인됐습니다. 이 정도를 본 뒤에야 Search Console 화면의 지연인지, 사이트 파일 문제인지 나눠볼 수 있었습니다.

이번 배포 흐름에서 다시 확인한 것

실제로 운영하면서 가장 자주 확인한 것은 화려한 기능이 아니라 아래 항목이었습니다.

npm run build

이번 기준으로는 Astro 정적 빌드에서 47개 페이지가 생성되는지 확인했고, 공개 주소는 pages.dev 기준으로 유지했습니다. OG 이미지와 대표 글 이미지를 추가할 때도 sitemap이나 robots 파일은 건드리지 않았습니다. 검색 등록 문제가 남아 있는 상태에서는 URL 기준을 흔드는 변경을 최소화하는 편이 안전하다고 판단했습니다.

또 하나 배운 점은 배포와 발행을 분리해야 한다는 것입니다. 로컬에서 빌드가 성공해도, GitHub push와 Cloudflare 반영은 별도 단계입니다. 그래서 다음 작업부터는 로컬 수정 → 빌드 확인 → 커밋 → 승인 후 push → 공개 URL 확인 순서로 고정하려고 합니다.

이 배포 흐름은 Cloudflare Pages 배포 후 꼭 확인하는 체크리스트robots.txt와 canonical을 점검하며 확인한 색인 기본 조건에서 계속 이어서 점검합니다. Search Console 쪽 대기 기준은 사이트맵이 정상인데 Search Console은 실패할 때 다음에 한 일에 따로 남겼습니다.

WordPress 대신 이 구조를 고른 이유

WordPress는 관리자 화면과 플러그인이 강점입니다. 반대로 여러 블로그를 작게 실험하려는 입장에서는 업데이트, 보안, 플러그인 관리가 부담이 될 수 있습니다.

Astro 방식은 글 작성과 배포 흐름을 직접 만들어야 하지만, 한 번 구조를 잡으면 복제하기 쉽습니다. Daejin Lab을 1호 블로그로 만든 이유도 여기에 있습니다. 나중에 2호, 3호 블로그를 만들 때 같은 운영 구조를 가져갈 수 있는지 보려는 실험입니다.

다음에 볼 것

다음 단계는 커스텀 도메인 확정 전까지 pages.dev 기준을 흔들지 않는 것입니다. 도메인을 붙이는 순간에는 아래를 한 번에 다시 맞춰야 합니다.

astro.config.mjs의 site 값
robots.txt의 sitemap 주소
Search Console 속성
canonical URL
외부 링크와 RSS 주소

정적 블로그는 가볍지만, URL 기준값 하나를 잘못 잡으면 검색엔진 등록 단계에서 시간을 많이 씁니다. 이 부분은 다음 블로그를 만들 때 가장 먼저 체크할 항목으로 남겨둘 생각입니다.