지노소프트 블로그의 호스팅을 GitHub Pages에서 Cloudflare Pages로 변경했다. https://blog.jinosoft.com/과 /posts/<slug>/는 유지하고, GitHub 소스 저장소만 Private으로 전환했다.
Cloudflare의 pages.dev에서 빌드와 화면 표시를 먼저 확인한 뒤 운영 도메인을 전환했다. 첫 배포가 필요하다면 Cloudflare Pages의 GitHub 연동과 Hugo 빌드 설정을 먼저 진행한다.
1. 이전 대상과 변경 순서#
| 항목 | 이전 전 | 이전 후 |
|---|---|---|
| 소스 저장소 | GitHub jinosoft/jinosoft-blog, Public | 같은 저장소, Private |
| 빌드·배포 | GitHub Actions | Cloudflare Pages Git 연동 |
| 웹 호스팅 | GitHub Pages | Cloudflare Pages |
| 운영 주소 | https://blog.jinosoft.com/ | 변경 없음 |
| 글 URL | /posts/<slug>/ | 변경 없음 |
| DNS 관리 | 카페24 | 카페24 유지 |
새 배포 확인 → 도메인 등록 → DNS 전환 → HTTPS·기존 경로 검증 → 기존 배포 중단 → 저장소 비공개 → 재배포 검증 순서로 진행한다.
GitHub Free에서 먼저 저장소를 Private으로 바꾸면 기존 GitHub Pages가 게시 중단될 수 있다. 따라서 운영 도메인이 새 호스팅에서 정상 응답하는 것을 확인하기 전에는 저장소 공개 범위를 변경하지 않는다. GitHub 공개 범위 변경 시 영향
2. baseURL과 글 경로 유지#
Hugo 설정은 기존 값을 유지했다.
baseURL = "https://blog.jinosoft.com/"
[permalinks]
posts = "/posts/:slug/"호스팅을 바꾸더라도 도메인·slug·경로를 유지하면 독자가 사용하는 기존 URL을 그대로 제공할 수 있다. 이 사례에서는 GitHub 저장소 이름이나 글 디렉터리 이름도 변경하지 않았다.
pages.dev는 새 배포의 검증 주소로 사용했다. 운영 주소를 임시 주소로 교체하거나 모든 기존 URL을 새 도메인으로 바꾸는 작업이 아니다.
3. Cloudflare Pages에 커스텀 도메인 등록#
Cloudflare의 jinosoft-blog 프로젝트에서 Custom domains → Set up a custom domain을 선택하고 blog.jinosoft.com을 입력한다.
이 사례의 blog.jinosoft.com은 서브도메인이다. 외부 DNS를 유지하고 CNAME으로 Pages에 연결할 수 있으므로, jinosoft.com 전체 네임서버를 옮기지 않았다. 루트 도메인인 jinosoft.com 자체를 Pages에 연결하는 경우와는 조건이 다르다. Cloudflare 서브도메인 연결 안내
도메인을 등록하면 필요한 CNAME 값이 표시된다.
Pages에 도메인을 등록한 뒤 DNS를 변경한다. DNS에 CNAME만 추가하고 Pages 프로젝트에 도메인을 연결하지 않으면 정상 서비스되지 않을 수 있다.
4. 카페24에서 CNAME 대상 변경#
카페24의 도메인관리 → DNS 관리 → 별칭(CNAME) 관리에서 기존 blog.jinosoft.com 레코드를 수정했다.
| 레코드 | 이름 | 기존 대상 | 변경 대상 |
|---|---|---|---|
| CNAME | blog.jinosoft.com | jinosoft.github.io | jinosoft-blog.pages.dev |
대상에는 https://나 / 경로를 넣지 않는다. 동일한 호스트에 CNAME을 중복 추가하지 말고 기존 대상을 수정한다. 홈페이지·메일 등 다른 DNS 레코드는 변경하지 않는다.
캡처의 입력란은 가로 폭이 좁아 값의 앞부분이 보이지 않는다. 입력해야 할 전체 값은 **jinosoft-blog.pages.dev**다.
DNS를 변경한 뒤 Cloudflare에서 Check DNS records를 실행한다. 처음에는 Inactive (Requires DNS setup)로 표시될 수 있다. DNS 캐시와 도메인 검증·인증서 준비 상태가 모두 같은 시점에 갱신되는 것은 아니므로, CNAME이 반영됐다는 이유만으로 HTTPS까지 완료됐다고 판단하지 않는다.
5. Active·HTTPS·기존 URL 검증#
도메인 상태가 Active, SSL enabled로 전환된 것을 확인했다.
이후 운영 주소를 직접 열어 홈과 기존 글·이미지가 표시되는지 확인한다. 이번 전환 후에는 홈, Docker 글 두 편과 이미지, 사이트맵, robots.txt, 파비콘의 HTTPS 요청이 모두 200으로 응답했고, 응답 헤더의 서버는 Cloudflare로 확인됐다.
확인할 경로는 다음과 같다.
| 대상 | 확인 경로 또는 항목 |
|---|---|
| 홈 | / |
| 기존 글 | /posts/docker-volume-data-persistence/ |
| 이미지·CSS | 글 이미지와 사이트 레이아웃 정상 표시 |
| 사이트맵 | /sitemap.xml, 내부 URL이 운영 도메인인지 확인 |
| 크롤러 안내 | /robots.txt, 사이트맵 주소와 크롤링 차단 여부 |
| 파비콘 | /favicon.ico |
| 표준 URL | HTML의 canonical이 기존 운영 URL인지 확인 |
WSL에서 응답을 직접 확인하려면 다음 명령을 사용할 수 있다.
curl -I https://blog.jinosoft.com/
curl -I https://blog.jinosoft.com/posts/docker-volume-data-persistence/
curl -I https://blog.jinosoft.com/sitemap.xml인증서 오류가 나면 -k로 무시하지 말고 도메인 활성화와 HTTPS 구성을 먼저 확인한다.
도메인과 경로가 동일하므로 Search Console의 주소 변경 도구로 새 도메인 이전을 신청하는 상황은 아니다. 기존 속성과 사이트맵 URL은 유지하되, 전환 이후에도 크롤링·색인 오류가 발생하지 않는지 확인한다. 호스팅 변경 자체가 검색 순위 유지나 상승을 보장하지는 않는다. Google의 URL 변경 없는 호스팅 이전 안내
6. GitHub Pages 자동 배포와 기존 게시 중단#
운영 주소의 Cloudflare 응답을 확인한 뒤 GitHub의 기존 배포를 정리했다. 일반적인 운영 이전에서는 DNS 캐시 유효기간과 기존 호스팅의 접근 기록도 확인하고, 이전 호스팅으로 향하는 요청이 남아 있지 않은지 검토한 뒤 중단한다. 새 호스팅에서 한 번 접속됐다는 사실만으로 모든 이용자의 DNS 전환이 끝났다고 판단하지 않는다.
먼저 저장소의 Actions → Deploy Hugo site to Pages → ⋯ → Disable workflow를 선택한다. GitHub Actions 전체가 아니라 기존 Pages 배포 워크플로만 비활성화한다.
다음으로 Settings → Pages → Unpublish site를 실행한다.
워크플로 비활성화는 이후 자동 배포를 막는 작업, Unpublish는 기존 배포를 내리는 작업이다. 둘은 다르다. Unpublish만 실행하고 워크플로를 계속 활성화해 두면 이후 배포로 다시 게시될 수 있다. 소스 저장소와 커밋을 삭제하는 작업은 아니다. GitHub 게시 중단 안내
여기서 중단하는 것은 GitHub Pages로 보내는 배포다. Cloudflare Pages는 GitHub App 연동으로 push를 감지하므로, 기존 Actions 워크플로를 꺼도 Cloudflare의 자동 배포는 계속 사용할 수 있다.
이 시점에는 DNS가 이미 Cloudflare를 가리켜야 한다. 기존 GitHub 주소를 가리키는 DNS를 남긴 채 게시부터 중단하지 않는다.
7. 저장소를 Private으로 전환#
GitHub 저장소의 Settings → General → Danger Zone → Change repository visibility → Change to private로 이동한다. 대상이 jinosoft/jinosoft-blog인지 확인하고, 변경 영향 안내를 읽은 뒤 진행한다.
완료 후 저장소에 Private 표시가 나타났다.
이 전환은 GitHub 원본 저장소 접근을 제한한다. Cloudflare에서 공개하는 글·이미지는 계속 공개된다. 기존 공개 fork는 Private으로 바뀌지 않고, 이미 받은 clone도 회수되지 않는다. 비공개 전환을 공개 이력이나 유출 정보의 완전 삭제 방법으로 사용해서는 안 된다.
Cloudflare의 GitHub App에는 이 저장소 접근 권한이 유지되어야 한다. 권한을 해제하면 기존 사이트는 보이더라도 다음 빌드에서 저장소를 복제하지 못할 수 있다.
8. Private 저장소에서 재배포 검증#
Private 전환 후 기존 사이트가 열린다는 것만으로는 검증이 끝나지 않는다. Cloudflare는 이미 생성된 정적 파일을 제공할 수 있으므로, 새 빌드가 비공개 저장소를 읽을 수 있는지도 확인해야 한다.
Cloudflare Pages의 Deployments → Retry deployment를 실행하고 저장소 복제·빌드·배포 결과를 확인했다.
Private 전환 후 재배포도 success로 완료됐다. 소스는 같은 GitHub 저장소에서 관리하고, 이후 운영 브랜치 push에 따른 빌드·배포는 Cloudflare가 담당한다.
이번 Retry deployment는 비공개 저장소 접근을 확인하기 위한 수동 재시도였다. 이후에는 자동 배포가 활성화된 main에 새 커밋을 push하면 Cloudflare가 빌드하고, 성공한 결과를 blog.jinosoft.com에 반영한다. 매번 Retry를 누르거나 DNS를 다시 설정할 필요는 없다. push 이후 자동 배포 흐름
새 호스팅과 기본 pages.dev 주소는 모두 접근될 수 있다. 운영 URL을 canonical과 사이트맵에 유지하고, 기본 도메인 접근을 운영 도메인으로 리다이렉트할지는 별도로 검토한다. 이번 캡처에는 pages.dev 리다이렉트 설정 과정은 포함하지 않았다. 기본 도메인 접근 관리
마무리#
기존 도메인과 글 경로를 유지한 채 Cloudflare Pages로 호스팅을 전환하고, GitHub 저장소를 Private으로 변경했다. 마지막 재배포 성공으로 비공개 저장소에서도 다음 배포를 생성할 수 있는 상태까지 확인했다.
이전의 핵심은 저장소부터 비공개로 바꾸는 것이 아니라, 새 호스팅 검증과 DNS 전환을 마친 뒤 기존 배포·저장소 설정을 정리하는 순서다.
서비스 선택 이유는 GitHub Pages와 Cloudflare Pages 비교, 새 배포 구성은 Cloudflare Pages Hugo 배포 가이드에서 확인할 수 있다.