한 줄 요약(ChatGPT)
Hugo로 만든 정적 사이트를 Cloudflare Pages에 올리고, 꼭 필요한 기능만 작은 서버리스 함수로 붙였다. 서버에서 PHP나 DB가 상시로 돌아가지 않으니 관리할 게 거의 없고, 비용은 도메인 값 말고는 0원이다.
전체 구조
[글쓰기] /admin (Decap CMS)
│ GitHub 로그인 → 글을 GitHub 저장소에 커밋
▼
[저장소] GitHub (비공개)
│ push 할 때마다 자동 빌드
▼
[빌드·호스팅] Cloudflare Pages ── Hugo로 HTML 생성 → 전 세계 CDN
│
├─ Pages Functions (/api/*)
│ ├─ GitHub 로그인 중계 (글쓰기용)
│ ├─ 이미지 업로드 → Cloudflare R2
│ └─ 방문 수 집계 → Cloudflare KV
│
├─ 이미지 Cloudflare R2 (별도 이미지 도메인)
└─ 댓글 Waline ── Vercel(서버) + Neon(PostgreSQL)
사이트: Hugo + 직접 만든 테마
Hugo: 마크다운 글을 미리 HTML로 만들어 두는 정적 사이트 생성기. 빌드가 몇 초면 끝난다.
테마: 처음엔 PaperMod를 쓰다가 지금은 직접 만든
dorulog테마를 쓴다. 왼쪽 메뉴·가운데 카드·오른쪽 사이드바로 된 3단 카드 레이아웃이다.- 다크 모드, 읽기 진행 막대, 목차(읽는 위치 강조), 코드 복사 버튼, 이미지 크게 보기
- 글 주소는 날짜 없이
/글-제목/형태
글꼴: Pretendard
검색: Hugo가 빌드할 때 글 목록을 JSON(
/index.json)으로 뽑아 두고, 브라우저에서 바로 검색한다. 검색 서버가 따로 없다.
배포: Cloudflare Pages
GitHub 저장소에 push 하면 Cloudflare Pages가 Hugo로 빌드해서 바로 배포한다. 정적 파일은 Cloudflare CDN으로 나가서 어디서 접속해도 빠르다.
정적 사이트만으로 안 되는 일은 Pages Functions(저장소의 functions/ 폴더)로 처리한다. 필요할 때만 잠깐 실행되는 서버리스 함수라 상시로 돌아가는 서버가 없다.
| 경로 | 하는 일 |
|---|---|
/api/auth, /api/callback | 글쓰기 화면의 GitHub 로그인 중계 |
/api/r2-upload | 글쓰기 화면에서 올린 이미지를 R2에 저장 (내 GitHub 계정만 허용) |
/api/views | 오늘·전체 방문 수 (KV에 저장, 같은 브라우저는 하루 한 번) |
/ui | 댓글 관리 화면을 블로그 주소로 열어 줌 |
글쓰기: Decap CMS
/admin으로 들어가면 Decap CMS가 뜬다. 왼쪽에 마크다운으로 쓰고 오른쪽에 블로그와 똑같은 모양의 미리보기가 나온다. 저장하면 GitHub 저장소에 커밋되고, 그대로 자동 배포까지 이어진다.
여기에 몇 가지를 직접 붙였다.
- 이미지 업로드: 브라우저에서 jpg·png를 webp(긴 변 2000px)로 바꾼 뒤 R2에 올린다. 용량이 확 줄어든다.
- 헤더 이미지·썸네일 고르기: 본문에 넣은 이미지 중에서 눌러서 고른다. 비워 두면 본문 첫 이미지가 썸네일이 된다.
- 주소 자동 생성: 처음 저장할 때 제목으로 주소를 만들고, 나중에 제목을 바꿔도 주소는 그대로 둔다.
- 댓글 관리 버튼: 글쓰기 화면 안에서 댓글 관리 화면을 바로 연다.
이미지: Cloudflare R2
이미지는 저장소에 넣지 않고 Cloudflare R2에 따로 저장해서 별도 이미지 도메인으로 보여 준다. 저장소가 무거워지지 않고, 한 번 올린 이미지는 1년 동안 캐시된다. R2는 밖으로 나가는 트래픽 요금이 없어서 이미지 호스팅에 잘 맞는다.
댓글: Waline
처음엔 GitHub Discussions 기반의 giscus를 썼는데, GitHub 계정이 있어야만 댓글을 달 수 있어서 로그인 없이 익명으로도 쓸 수 있는 Waline으로 바꿨다.
- 서버: Vercel (무료 플랜)
- DB: Neon PostgreSQL (무료 플랜)
- 닉네임·이메일은 모두 선택이라 비우면 ‘익명’으로 남는다.
- 블로그 색과 다크 모드에 맞춰 댓글창 색을 바꿨다.
무료 서버는 한동안 요청이 없으면 잠들어서 첫 로딩이 1~2초 느려질 수 있다. 그래서 글 페이지가 열리자마자 가벼운 요청을 먼저 보내 미리 깨워 두고, 독자가 스크롤해서 댓글에 닿을 때쯤엔 빨라지게 했다.
그 밖에
- 검색 등록: 네이버 서치어드바이저 등
- 공유·검색 최적화: RSS, 사이트맵, OG 이미지, 구조화 데이터(schema), robots.txt
정리
| 역할 | 사용한 것 | 비용 |
|---|---|---|
| 사이트 생성 | Hugo + 직접 만든 테마 | 무료 |
| 저장소 | GitHub | 무료 |
| 빌드·호스팅·CDN | Cloudflare Pages | 무료 |
| 서버 기능 | Cloudflare Pages Functions | 무료 범위 |
| 이미지 | Cloudflare R2 | 무료 범위 |
| 방문 수 | Cloudflare KV | 무료 범위 |
| 글쓰기 | Decap CMS | 무료 |
| 댓글 | Waline (Vercel + Neon) | 무료 범위 |
서버를 직접 관리하지 않으니 보안 업데이트를 챙길 일도 거의 없고, 글만 쓰면 된다. 워드프레스에서 넘어오면서 바랐던 게 딱 이거였다.
댓글