본문으로 건너뛰기

"Hugo" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

Hugo 7사이트, Docusaurus 통합

· 약 2분

Hugo PaperMod 블로그 구축에서 시작한 블로그를 Hugo에서 Docusaurus로 마이그레이션했어요. 원래 한 도메인에서 블로그 2개와 문서 노트 5개, 모두 Hugo 사이트 7개를 따로 돌렸는데 영역마다 빌드와 설정을 챙기는 일이 점점 무거워졌어요.

Docusaurus 소개

Docusaurus는 Meta가 만든 React 기반 오픈소스 정적 사이트 생성기입니다. 코드는 facebook/docusaurus에 공개되어 있습니다. 일반 블로그보다 버전 관리, 사이드바, 문서 탐색 같은 문서 사이트 기능에 초점을 맞춥니다. docs 플러그인을 여러 인스턴스로 구성할 수 있어 한 사이트 안에서도 문서 영역별 경로와 사이드바를 독립적으로 운영합니다. 블로그 플러그인 역시 여러 개를 띄울 수 있으므로 성격이 다른 블로그를 분리하기 좋습니다. Mermaid, 로컬 검색 플러그인, 다크 모드까지 문서 사이트에 필요한 기능을 생태계 안에서 함께 구성할 수 있습니다.

Docusaurus 공식 사이트

후보와 선택 기준

첫 번째 후보는 Hugo를 유지하고 Hextra 단일 사이트로 합치는 방식이었습니다. 기존 도구를 그대로 쓰므로 마이그레이션 비용은 가장 적지만, 문서 중심 테마라 블로그 2개의 레이아웃을 나누어 살리기에는 아쉬웠습니다.

Docusaurus는 독립된 문서 영역 여러 개와 블로그 여러 개를 공식 플러그인의 다중 인스턴스로 구성할 수 있습니다. 문서 노트 5개와 블로그 2개라는 저의 구조에 이 방식이 정확히 맞았습니다.

Astro Starlight도 빠르고 깔끔한 문서 도구였지만 기본 구조는 단일 문서 사이트에 가깝고, 블로그에는 서드파티 플러그인이 필요했습니다. 결국 새 기술의 화려함보다 지금 가진 영역을 무리 없이 한 프로젝트에 담을 수 있는지를 기준으로 Docusaurus를 골랐습니다.

힘들었던 점

첫 번째는 자동 변환의 사각지대였습니다. 변환 작업이 커밋된 파일을 기준으로 진행되면서 커밋하지 않은 글 11개가 결과에서 빠졌고, 배포 후 운영에서 404로 드러났습니다. 전체 변환을 다시 돌리면 이미 손본 글까지 덮을 수 있어 변환 스크립트에 증분 모드를 추가하고 누락된 글만 복구했습니다.

두 번째는 구 URL 보존이었습니다. 기존 주소 1,100여 개를 새 경로로 보내는 301 map을 만들었는데, URL 인코딩된 한글 태그 주소가 긴 key가 되면서 Nginx의 map_hash_bucket_size 기본값을 넘겼습니다. 설정 자체는 정상이었지만 reload가 실패했고, bucket 크기를 늘린 뒤에야 기존 주소를 유지한 채 전환할 수 있었습니다.

통합 후 모습

홈은 일곱 영역을 안내하는 카드로 바꿨습니다. 상단 메뉴에서 블로그와 문서 노트를 오갑니다.

통합 후 dbalog.dev 홈

문서 영역은 좌측 사이드바와 우측 목차가 있는 Docusaurus 기본 문서 레이아웃을 그대로 씁니다.

문서 영역 레이아웃 (PostgreSQL 노트)

이제 빌드와 배포가 하나로 줄었어요. 예전 URL의 색인이 새 주소로 안정적으로 재구축되는지는 조금 더 지켜보는 중이에요.

Hugo PaperMod 블로그 구축

· 약 5분

이 글은 Hugo + PaperMod 블로그 세팅 시리즈의 첫 번째 글이에요.

  1. Hugo + PaperMod로 기술 블로그 만들기 ← 현재 글
  2. NCP 서버에 Hugo 블로그 배포하기
  3. 커스텀 도메인 연결과 Let's Encrypt SSL 설정

왜 Hugo인가?

블로그를 시작하면서 WordPress, Gatsby, Next.js 등 여러 옵션을 검토했습니다. 최종적으로 Hugo를 선택한 이유는 다음과 같습니다.

  • Go 기반이라 수천 페이지도 수 초 내에 빠르게 빌드합니다.
  • 정적 HTML 파일만 서빙하면 되므로 Nginx 하나로 간단히 배포합니다.
  • .md 파일로 글을 쓰고 git으로 버전을 관리합니다.
  • PHP, Node.js, 데이터베이스 없이 순수 파일만으로 동작합니다.

테마는 PaperMod를 선택했습니다. GitHub Stars 13k+로 Hugo 테마 중 가장 인기가 많고, 다크모드/검색/SEO가 기본 내장되어 있습니다.

1. Hugo 설치

macOS 기준 Homebrew로 설치합니다.

brew install hugo

설치 확인:

hugo version
# hugo v0.160.0+extended+withdeploy darwin/arm64

extended 버전이 설치되어야 SCSS/SASS 처리가 가능합니다. Homebrew로 설치하면 자동으로 extended 버전이 들어갑니다.

Linux(Rocky/CentOS)에서 설치하려면? Hugo는 Go 바이너리라 패키지 매니저 대신 GitHub Releases에서 직접 다운로드하는 것이 버전 관리에 유리합니다.

2. 새 사이트 생성

mkdir blog && cd blog
hugo new site . --force

--force는 빈 디렉토리가 아니어도 생성을 허용하는 플래그입니다. 실행하면 다음 구조가 만들어집니다.

blog/
├── archetypes/ # 새 글의 기본 front matter 템플릿
├── content/ # 마크다운 글 저장
├── layouts/ # 테마 오버라이드 템플릿
├── static/ # 정적 파일 (이미지 등)
├── themes/ # 테마 디렉토리
└── hugo.toml # 사이트 설정 파일

3. PaperMod 테마 설치

git submodule로 설치하면 테마 업데이트가 git submodule update 한 줄로 끝납니다.

git init
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
  • --depth=1: 최신 커밋만 가져와서 용량을 줄입니다 (shallow clone)
  • 나중에 테마를 업데이트할 때는 git submodule update --remote --merge를 실행합니다.

4. hugo.toml 설정

이 파일이 블로그의 핵심 설정입니다. 전체 내용을 공유합니다.

baseURL = "https://dbalog.dev/"
title = "dbalog.dev"
paginate = 10
theme = "PaperMod"
languageCode = "ko"
defaultContentLanguage = "ko"
hasCJKLanguage = true

enableRobotsTXT = true
buildDrafts = false

[minify]
disableXML = true
minifyOutput = true

# 검색을 위한 JSON 출력
[outputs]
home = ["HTML", "RSS", "JSON"]

[params]
env = "production"
title = "dbalog.dev"
description = "기술 블로그"
keywords = ["Blog", "Tech", "Development"]
author = "dbalog"
DateFormat = "2006년 1월 2일"
defaultTheme = "auto" # 시스템 다크/라이트 모드를 따름
disableThemeToggle = false

ShowReadingTime = true
ShowCodeCopyButtons = true
ShowPostNavLinks = true
ShowBreadCrumbs = true
ShowWordCount = true
UseHugoToc = true
showtoc = true

[params.homeInfoParams]
Title = "Welcome"
Content = "기술과 개발 이야기를 기록합니다."

[params.fuseOpts]
isCaseSensitive = false
shouldSort = true
location = 0
distance = 1000
threshold = 0.4
minMatchCharLength = 0
limit = 10
keys = ["title", "permalink", "summary", "content"]

# 상단 메뉴
[[menu.main]]
identifier = "posts"
name = "글목록"
url = "/posts/"
weight = 10

[[menu.main]]
identifier = "categories"
name = "카테고리"
url = "/categories/"
weight = 20

[[menu.main]]
identifier = "tags"
name = "태그"
url = "/tags/"
weight = 30

[[menu.main]]
identifier = "search"
name = "검색"
url = "/search/"
weight = 40

[[menu.main]]
identifier = "archives"
name = "아카이브"
url = "/archives/"
weight = 50

# 코드 하이라이팅
[markup]
[markup.highlight]
noClasses = false

주요 설정 해설

설정왜 필요한가
hasCJKLanguagetrue한글 읽기 시간을 글자 수 기반으로 계산
defaultTheme"auto"시스템 설정에 따라 다크/라이트 자동 전환
outputs.home["HTML","RSS","JSON"]JSON을 추가해야 Fuse.js 검색이 동작
ShowCodeCopyButtonstrue코드 블록에 복사 버튼 표시
DateFormat"2006년 1월 2일"Go 레퍼런스 타임을 한국식으로
noClassesfalseChroma 코드 하이라이팅을 CSS 클래스 기반으로

5. 한글 폰트 + AdSense 준비

PaperMod는 layouts/partials/extend_head.html 파일로 <head> 태그를 확장할 수 있습니다.

mkdir -p layouts/partials

layouts/partials/extend_head.html:

{{/* Noto Sans KR 한글 폰트 */}}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Noto Sans KR', sans-serif;
}
</style>

나중에 Google AdSense 승인을 받으면 이 파일에 스크립트를 추가하면 됩니다.

주의: layouts/ 디렉토리에는 .html 파일만 넣어야 합니다. Hugo가 이 디렉토리의 모든 파일을 Go 템플릿으로 파싱하기 때문에, 마크다운 등 다른 파일을 넣으면 빌드 에러가 발생합니다.

6. 특수 페이지 생성

PaperMod의 검색과 아카이브 기능을 위해 전용 페이지를 만듭니다.

content/search.md:

---
title: "검색"
layout: "search"
placeholder: "검색어를 입력하세요"
---

content/archives.md:

---
title: "아카이브"
layout: "archives"
url: "/archives/"
---

layout 값으로 PaperMod 내장 템플릿이 사용됩니다.

7. 첫 번째 포스트 작성

hugo new content posts/hello-world.md

front matter 예시:

---
title: "제목"
date: 2026-04-09
draft: false
tags: ["Hugo", "블로그"]
categories: ["블로그"]
summary: "글 요약"
ShowToc: true
TocOpen: true
---
  • draft: true이면 hugo server -D에서만 보이고 프로덕션 빌드에서 제외됩니다.
  • tagscategories를 지정하면 /tags/, /categories/ 페이지에 자동 집계됩니다.

8. 빌드 및 로컬 확인

# 프로덕션 빌드
hugo --minify

# 로컬 미리보기 (draft 포함)
hugo server -D
# → http://localhost:1313 에서 확인

빌드 결과:

│ KO
──────────────────┼────
Pages │ 23
Paginator pages │ 0
Non-page files │ 0
Static files │ 0
Processed images │ 0
Aliases │ 6

Total in 61 ms

23페이지가 61ms 만에 생성됩니다. public/ 디렉토리에 정적 파일이 만들어지고, 이 파일들을 웹서버로 서빙하면 블로그가 됩니다.

다음 글

다음 글에서는 이 public/ 디렉토리를 NCP(네이버 클라우드) 서버에 배포하는 과정을 다뤄요.

NCP 서버에 Hugo 블로그 배포하기

참고 자료