콘텐츠로 이동

Cloudflare Pages 로 정적 사이트 굴리기

정적 사이트를 Cloudflare Pages 에 올리는 일 자체는 십 분이면 끝납니다. 문제는 그 다음입니다. git push 는 배포의 시작이지 끝이 아닌데, 그걸 모르면 올라가지 않은 것을 올라갔다고 착각하게 됩니다.

이 문서는 위키와 작업일지 두 사이트를 한 저장소에서 올리며 겪은 것을 정리한 것입니다.

한 저장소에 사이트가 여럿일 때

섹션 제목: “한 저장소에 사이트가 여럿일 때”

저장소 하나에 프로젝트가 여럿이면 두 가지를 잡아야 합니다.

설정 값 없으면
Root directory wiki 저장소 루트를 빌드하려다 실패
Build watch paths wiki/* 다른 프로젝트만 고쳐도 매번 다시 빌드

Root directory 는 프로젝트를 만들 때 정합니다. Build watch paths 는 Settings → Builds 에 따로 있고 기본값이 * 라서, 놓치면 옆 프로젝트를 고칠 때마다 이쪽도 빌드가 돕니다. 빌드 시간은 유료 계정에서 한도가 있으니 그냥 낭비입니다.

Node 버전은 프로젝트마다 기본값이 다르고, 오래된 기본값이 걸리면 설치 단계에서 멈춥니다. 루트 디렉터리에 .node-version 을 두면 됩니다.

22.17.0

Astro 7 은 Node 22.12 이상을 요구합니다. 요구 버전은 node_modules/<패키지>/package.json 의 engines 에서 확인하십시오.

같은 Cloudflare 계정의 zone 이면 Custom domains 에서 도메인만 넣으면 CNAME 이 자동으로 생깁니다. 직접 만들지 마십시오.

빌드 결과 폴더(dist/)의 루트에 두면 Pages 가 읽습니다. public/ 에 두면 빌드가 복사해 주므로 그것도 됩니다. 다만 빌드 때 만들어지는 것은 dist/ 에 직접 써야 합니다.

/*
Content-Security-Policy: ...
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
/_astro/*
Cache-Control: public, max-age=31536000, immutable

내용 해시가 파일 이름에 붙는 산출물(/_astro/*, 폰트)만 장기 캐시를 걸어야 합니다. HTML 에 걸면 글을 고쳐도 한참 옛 화면이 나갑니다.

리다이렉트는 이렇게 씁니다.

/ /ko/ 302
/ko/old-path/ https://blog.example.com/posts/new/ 301

목적지에 다른 도메인의 전체 주소를 써도 됩니다. 글을 다른 사이트로 옮길 때 옛 주소를 끊지 않는 방법입니다.

여기가 핵심입니다.

Pages 빌드가 실패해도 이전 버전이 계속 200 을 돌려줍니다. 그래서 주소를 두드려 200 을 세는 것으로는 배포됐는지 알 수 없습니다. 실패한 배포와 성공한 배포가 똑같이 200 입니다.

빌드가 자기 커밋을 결과물에 남기게 하면 대조할 수 있습니다.

// 빌드 뒤에 돈다
const commit = process.env.CF_PAGES_COMMIT_SHA || gitHead()
await writeFile('dist/build-id.txt', commit)

CF_PAGES_COMMIT_SHA 는 Pages 가 빌드 환경에 넣어 주는 값입니다. 그러면 검증은 이렇게 됩니다.

  1. dist/build-id.txt 를 라이브에서 읽는다
  2. 로컬 HEAD 와 같아질 때까지 기다린다
  3. 같아진 뒤에야 경로와 헤더를 확인한다

기다리지 않고 바로 확인하면 옛 버전을 검사하고 통과시킵니다.

200 만 세지 마십시오. 화면이 200 을 주면서 알맹이만 사라지는 고장이 실제로 흔합니다.

  • 경로를 이름으로 확인합니다. 목록을 두고 하나씩 두드립니다. 문서를 늘리면 목록도 같이 늘립니다.
  • 없는 주소가 404 인지 봅니다. 200 을 주면 검색엔진이 빈 페이지를 색인합니다.
  • 소유확인 파일과 색인 키 파일이 살아 있는지 봅니다. 사라져도 화면은 멀쩡하고, 몇 달 뒤 유입이 끊긴 뒤에야 알게 됩니다.
  • 보안 헤더가 실제로 붙는지 봅니다. _headers 가 배포물에 안 들어가면 조용히 사라집니다.
함정 증상 대응
Build watch paths 기본값 남의 폴더 고쳐도 빌드 <폴더>/* 로 좁힘
감시 경로를 좁힌 뒤 검증이 멀쩡한 배포를 실패로 커밋이 아니라 폴더 변경 여부를 봄
DNS 음성 캐시 브라우저만 못 찾음 캐시 비우기, 다른 곳에서 확인
빌드 실패 여전히 200 build-id 대조
원문 grep 검사 안 보이는 문자열에 걸림 있는 것을 셈