Post

GitHub Pages에서 Cloudflare Pages로 블로그를 옮긴 이유와 과정

GitHub Pages로 운영하던 개인 블로그를 Cloudflare Pages로 옮기면서 소스 저장소는 private로 바꾸고, 배포 결과물만 공개하기까지의 이유와 진행 과정을 정리했다.

GitHub Pages에서 Cloudflare Pages로 블로그를 옮긴 이유와 과정

GitHub Pages로 운영하던 이 블로그를 Cloudflare Pages로 옮겼다.

주소도 바뀌었다.

  • 기존 주소: https://kerogrammer.github.io
  • 새 주소: https://kerogrammer.pages.dev

겉으로 보기에는 단순히 호스팅 위치만 바꾼 것처럼 보이지만, 내 입장에서는 꽤 중요한 운영 방식의 변화였다. 핵심은 이것이다.

블로그 소스는 계속 GitHub에서 관리하되, 저장소는 private로 돌리고, 실제 배포된 결과물만 Cloudflare Pages에 공개한다.

GitHub Pages에서 Cloudflare Pages로 이전하는 장면 소스 저장소와 공개 사이트를 분리하고 싶었다.

왜 GitHub Pages에서 옮겼나

GitHub Pages는 정말 편하다. 저장소 이름을 username.github.io로 만들고, Jekyll 블로그를 올리면 거의 바로 웹사이트가 된다. 나도 그 편리함 때문에 지금까지 GitHub Pages를 잘 써왔다.

그런데 블로그를 계속 운영하다 보니 한 가지가 걸렸다.

소스 저장소가 public이어야 한다는 점이다.

물론 공개 블로그니까 최종 HTML, CSS, 이미지, 글은 누구나 보는 것이 맞다. 하지만 저장소에는 최종 결과물 말고도 운영 과정의 흔적이 남는다. 예를 들면 이런 것들이다.

  • 글 초안과 작성 중인 파일
  • 자동화 워크플로우
  • 블로그 운영 규칙과 실험 흔적
  • 아직 정리되지 않은 작업 파일
  • 배포 전 구조와 내부 관리 방식

블로그를 공개하는 것과, 블로그를 만드는 과정 전체를 공개하는 것은 조금 다르다.

나는 글은 공개하고 싶지만, 운영 과정과 소스 관리 방식까지 항상 공개해야 한다고 생각하지는 않는다. 그래서 이번에 방향을 바꿨다.

목표

이번 이전의 목표는 분명했다.

  1. 소스 관리는 계속 GitHub에서 한다.
  2. GitHub 저장소는 private로 바꾼다.
  3. Cloudflare Pages가 private 저장소를 읽어서 빌드한다.
  4. 방문자는 Cloudflare에 배포된 정적 결과물만 본다.
  5. 검색엔진에는 새 주소와 sitemap을 다시 알려준다.

정리하면, GitHub는 작업 공간이고 Cloudflare Pages는 공개 무대가 되는 구조다.

Cloudflare Pages 프로젝트 만들기

Cloudflare에서 Pages 프로젝트 이름은 kerogrammer로 만들었다. 그래서 최종 주소는 아래처럼 정해졌다.

1
https://kerogrammer.pages.dev

이 블로그는 Jekyll 기반이라 Cloudflare Pages의 빌드 설정은 이렇게 잡았다.

1
2
3
4
Production branch: main
Framework preset: Jekyll
Build command: bundle exec jekyll build
Build output directory: _site

환경변수는 아래처럼 넣었다.

1
2
3
JEKYLL_ENV=production
RUBY_VERSION=3.4.8
BUNDLE_WITHOUT=development:test

처음에는 jekyll build를 쓸지 bundle exec jekyll build를 쓸지 고민했다. Cloudflare 안내에서는 jekyll build가 추천처럼 보이기도 했지만, 이 저장소는 GemfileGemfile.lock으로 Jekyll과 테마 버전을 관리하고 있다.

그래서 저장소에 잠긴 gem 조합을 그대로 쓰도록 bundle exec jekyll build를 선택했다.

중간에 만난 빌드 오류

한 번에 끝나지는 않았다.

처음 배포에서는 Ruby 설치와 gem 설치까지는 잘 됐는데, 실제 Jekyll 빌드에서 html-proofer 관련 오류가 났다.

원인은 간단했다.

Cloudflare가 의존성을 설치할 때 developmenttest 그룹을 제외했는데, bundle exec jekyll build 실행 시점에서는 그 제외 설정을 제대로 이어받지 못했다. html-proofer는 배포용이 아니라 테스트용 gem인데, Bundler가 Gemfile.lock을 보면서 이 gem을 찾다가 실패한 것이다.

해결은 BUNDLE_WITHOUT 환경변수를 명시하는 것이었다.

1
BUNDLE_WITHOUT=development:test

이 값을 넣고 다시 배포하니 Jekyll 빌드가 정상적으로 진행됐다.

Cloudflare Pages 이전 과정 다이어그램 실제로는 몇 번 되돌아가며 설정을 고쳤지만, 큰 흐름은 이렇다.

블로그 설정도 새 주소로 변경

Cloudflare Pages 배포가 된 것만으로 끝은 아니었다.

Jekyll 블로그 안에는 사이트의 공식 URL이 들어간다. 이 값은 canonical URL, sitemap, feed, SEO 메타데이터에 영향을 준다. 그래서 _config.ymlurl 값을 새 주소로 바꿨다.

1
url: 'https://kerogrammer.pages.dev'

README 안에 있던 블로그 링크도 새 주소로 바꿨다.

그리고 기존 GitHub Pages 배포 워크플로우는 더 이상 필요하지 않으므로 비활성화했다. Cloudflare Pages가 GitHub 저장소를 보고 직접 빌드하기 때문에, GitHub Actions에서 Pages 배포를 또 할 이유가 없어졌다.

SEO는 다시 등록했다

주소가 바뀌면 검색엔진에도 새 주소를 알려야 한다.

Google Search Console에서는 처음에 도메인 소유권 확인 화면이 나왔다. 그런데 kerogrammer.pages.dev는 내가 직접 소유한 루트 도메인이 아니다. Cloudflare가 제공하는 pages.dev의 하위 주소라서 DNS TXT 레코드를 직접 넣을 수 없다.

그래서 도메인 속성이 아니라 URL 접두어 속성으로 등록했다.

1
https://kerogrammer.pages.dev/

Google Analytics 연결로 소유권 확인이 완료됐고, 그 다음 sitemap을 제출했다.

1
https://kerogrammer.pages.dev/sitemap.xml

robots.txt도 확인했다.

1
https://kerogrammer.pages.dev/robots.txt

둘 다 정상적으로 열렸으니, 검색엔진이 새 주소를 읽어갈 기본 준비는 끝난 셈이다.

GitHub 저장소를 private로 바꾸다

마지막으로 GitHub 저장소를 private로 바꿨다.

이후 https://kerogrammer.github.io/에 접속해보니 404가 나왔다. GitHub Pages 쪽 공개 사이트는 내려갔고, 저장소 소스도 더 이상 외부에서 볼 수 없는 상태가 됐다.

이제 방문자가 보는 블로그는 Cloudflare Pages에 배포된 결과물이다. 반면 글을 작성하고, 이미지를 추가하고, 설정을 고치는 실제 작업 공간은 private GitHub 저장소 안에 남는다.

내가 원했던 구조가 정확히 이거였다.

옮겨보니 느낀 점

이번 이전은 거창한 인프라 작업은 아니었다. 하지만 개인 블로그 운영 방식에서는 꽤 의미 있는 변화였다.

GitHub Pages는 시작하기 좋고 단순하다. 특히 공개 저장소 기반의 기술 블로그라면 여전히 좋은 선택이다.

다만 시간이 지나면서 블로그가 단순한 결과물 저장소가 아니라, 글쓰기 실험과 자동화, 운영 규칙이 섞인 작업 공간이 되기 시작했다. 그러면 소스 저장소 전체를 public으로 유지하는 것이 조금 부담스러워질 수 있다.

Cloudflare Pages로 옮기면서 이 경계가 정리됐다.

  • 공개할 것: 완성된 블로그
  • 숨길 것: 작업 과정과 소스 저장소
  • 계속 유지할 것: GitHub 기반 소스 관리
  • 새로 맡길 것: Cloudflare Pages 배포

결국 이번 이전은 호스팅 서비스를 바꾼 일이기도 하지만, 더 정확히는 블로그의 공개 범위를 다시 정한 일이었다.

앞으로도 글은 계속 공개하되, 만드는 과정은 조금 더 편하게 다룰 수 있을 것 같다.

ENGAGEMENT METRICS

이 포스팅이 가치 있었나요?

여러분의 평가는 콘텐츠의 품질을 결정하는
가장 핵심적인 데이터가 됩니다.

▲ 유익한 정보예요 ▼ 보완이 필요해요

실시간 익명 데이터로 수집되어 블로그 운영에 반영됩니다.

This post is licensed under CC BY 4.0 by the author.