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

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

왜 Hugo인가?

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

  • 빠른 빌드: Go 기반이라 수천 페이지도 수 초 내에 빌드
  • 단순한 배포: 정적 HTML 파일만 서빙하면 되므로 Nginx 하나로 충분
  • 마크다운 기반: .md 파일로 글을 쓰고 git으로 버전 관리
  • DB 불필요: 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 블로그 배포하기