Jekyll에서 Hugo로 마이그레이션... 아니면

발행: (2026년 2월 19일 오후 06:02 GMT+9)
11 분 소요
원문: Dev.to

Source: Dev.to

Migrating from Jekyll to Hugo… or not의 표지 이미지

Context

나는 이 블로그를 WordPress에서 시작했다. 몇 년이 지난 뒤, 나는 Jekyll로 마이그레이션하기를 결정했다. 지금까지 Jekyll에 만족하고 있다. Ruby 기반이며, 나는 Ruby 개발자는 아니지만 몇 개의 플러그인을 만들 수 있었다.

코드베이스는 GitLab에 호스팅하고 있으며, GitLab CI를 사용하고 있다. 그리고 Renovate를 설정해 gem이 오래되면 PR을 생성하도록 했다. 이렇게 하면 매번 기술 부채를 갚게 되고, 시간이 지나면서 부채가 쌓이지 않는다. 지난 주에 3.4에서 4.0으로 부모 Ruby Docker 이미지 업데이트를 요청하는 PR을 받았다.

Jekyll이 Ruby 4를 지원하는지 확인해 보았다. 지원하지 않으며, 오픈 이슈가 존재한다. 하지만 문제는 Jekyll뿐만이 아니다: Gemfile에 있는 gem들의 버전도 Ruby 4와 호환되지 않는다.

더구나, Jekyll 프로젝트의 전반적인 상태를 살펴보았다. 마지막 커밋은 몇 주 전 CI 봇에 의해 이루어진 것이었다. 이제는 대안을 찾아볼 때가 된 것 같았다.

Hugo

Jekyll과 마찬가지로, Hugo는 정적 사이트 생성기입니다.

Hugo는 가장 인기 있는 오픈‑소스 정적 사이트 생성기 중 하나입니다. 놀라운 속도와 유연성을 갖춘 Hugo는 웹사이트 구축을 다시 즐겁게 만들어 줍니다.

Jekyll과 달리, Hugo는 Go를 기반으로 합니다. 자신을 “놀라울 정도로 빠르다”고 내세웁니다. 케이크 위에 아이싱을 얹듯, codebase는 Jekyll보다 훨씬 활발히 업데이트됩니다. 저는 Go 팬은 아니지만, Hugo가 좋은 마이그레이션 대상이라고 판단했습니다.

Jekyll → Hugo

Jekyll에서 Hugo로 마이그레이션하는 것은 파레토 법칙을 따릅니다.

콘텐츠 마이그레이션

Hugo는 다음과 같은 주요 폴더를 제공합니다:

FolderPurpose
content처리해야 할 콘텐츠
static그대로 복사되는 리소스
layouts템플릿
data데이터 소스

전체 목록은 full list를 참고하세요.

Jekyll은 posts(날짜가 있는)와 pages(날짜가 없는)를 구분합니다. Posts는 블로그의 기반이며, pages는 안정적이고 사이트 구조를 담당합니다. Hugo는 이러한 구분을 하지 않습니다.

Jekyll 폴더와 Hugo 폴더 매핑:

JekyllHugo
_postscontent/posts
_pages/.mdcontent/posts/.md
_datadata
_layoutslayouts
assetsstatic

매핑만으로는 부족할 때

Jekyll은 plugins을 제공합니다. 플러그인은 여러 카테고리로 나뉩니다:

  • Generators – 사이트에 추가 콘텐츠를 생성
  • Converters – 마크업 언어를 다른 형식으로 변환
  • Commandsjekyll 실행 파일에 서브커맨드를 추가
  • Tags – 커스텀 Liquid 태그 생성
  • Filters – 커스텀 Liquid 필터 생성
  • Hooks – 빌드 프로세스를 세밀하게 제어

Jekyll에서는 generators, tags, filters, hooks를 사용합니다. 일부는 기존 gem(예: Twitter plugin)을 통해 사용하고, 나머지는 직접 필요에 맞게 개발했습니다.

Tags → Shortcodes

Jekyll 태그는 Hugo의 shortcodes로 변환됩니다:

Shortcode는 마크업 안에서 호출되는 템플릿으로, 任意 개수의 인자를 받을 수 있습니다. 비디오, 이미지, 소셜 미디어 임베드와 같은 요소를 콘텐츠에 삽입할 때 모든 콘텐츠 형식과 함께 사용할 수 있습니다.

shortcode는 임베디드, 커스텀, 인라인의 세 가지 유형이 있습니다. Hugo는 풍부한 기본 shortcode 컬렉션을 제공하며, 직접 만든 shortcode도 사용할 수 있습니다.

Generators → 직접적인 대응 없음

안타깝게도 generators는 Hugo에 직접적인 대응이 없습니다. 저는 뉴스레터와 강연 페이지를 만들기 위해 generators를 개발했었습니다. 해당 generator 플러그인은 데이터를 기반으로 연도별 페이지를 자동으로 생성했습니다. Hugo에서는 연도별 페이지를 직접 하나씩 만들어야 했습니다.

GitLab 빌드 마이그레이션

Jekyll 빌드는 세 단계로 구성됩니다:

  1. Gemfile.lock, Dockerfile, 또는 .gitlab-ci.yml 중 어느 것이 변경되었는지 감지하고, 필요하면 Docker 이미지를 다시 빌드합니다.
  2. Docker 이미지를 사용하여 실제로 사이트를 빌드합니다.
  3. 사이트를 GitLab Pages에 배포합니다.

주요 변경은 명백히 Dockerfile에서 발생합니다. 아래는 참고용 새로운 Hugo 기반 버전입니다:

FROM docker.io/hugomods/hugo:exts

ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk
ENV PATH=$JAVA_HOME/bin:$PATH

WORKDIR /builds/nfrankel/nfrankel.gitlab.io

RUN apk add --no-cache openjdk21-jre graphviz \                                      #1
 && gem install --no-document asciidoctor-diagram asciidoctor-diagram-plantuml rouge #2
  1. PlantUML용 패키지.
  2. Asciidoctor 다이어그램 및 구문 강조를 위한 gem.

이 시점에서 뭔가 수상한 점을 감지했어야 했지만, 작동했으므로 계속 진행했습니다.

The deal breaker

나는 Claude Code와 Copilot CLI의 도움을 받아 마이그레이션을 진행했다. 몇 차례에 걸쳐 일주일 동안, 주로 저녁과 주말에 작업했다. 마이그레이션 중에 회귀를 방지하기 위해 일대일 비교를 정기적으로 요청했다. 내 아이디어는 Jekyll 사이트와 Hugo 사이트를 나란히 구축하고, 둘 다 GitLab Pages에 배포한 뒤 배포된 버전을 비교하여 최종 차이를 찾는 것이었다.

파이프라인을 그렇게 업데이트하고 빌드를 트리거했다:

  • Jekyll build: 2분 조금 넘음.
  • Hugo build: 10분 이상!

믿을 수 없어서 빌드를 다시 트리거했다. 결과는 일관되었다.

Result: Hugo는 내 CI 환경에서 Jekyll보다 현저히 느렸으며, 이것이 마이그레이션을 완료하지 못하게 만든 결정적인 요인이었다.

LDS screenshot

문제를 더 잘 이해하기 위해 로그를 분석했다. 몇 가지 경고 외에는 지연 원인을 설명하는 내용이 없었다.

                  │  EN  
──────────────────┼──────
 Pages            │ 2838 
 Paginator pages  │  253 
 Non-page files   │    5 
 Static files     │ 2817 
 Processed images │    0 
 Aliases          │  105 
 Cleaned          │    0 
Total in 562962 ms

Claude Code에 물어보니 내 포스트에 Asciidoc을 사용한 것이 원인이라고 지적했다. Hugo는 Asciidoc(및 다른 포맷)을 완벽히 지원하지만, Markdown이 아닌 포맷은 외부 엔진에 위임한다. Asciidoc의 경우 그 엔진이 asciidoctor이다. 이 방식은 몇 개의 Asciidoc 문서에서는 잘 작동하지만, 800개가 넘는 문서에서는 그렇지 않다. 나는 이 문제를 처음 겪는 것이 아니라는 것을 금방 알았다: 이 스레드는 5년 동안 이어져 왔다.

실망했다고 말하는 것이 과소평가다. 나는 작업을 브랜치에 남겨두고, 기분이 가라앉으면 나중에 삭제할 예정이다.

결론

마이그레이션 작업을 시작하기 전에, 나는 사전 조사를 통해 작업의 기술적 실현 가능성을 확인했습니다. 문서를 읽고 LLM과 대화하면서 이를 검증했지만, 되돌리기 전에 작업을 진행하면서 시간을 낭비했습니다.

행동 방식과 성능 저하에 대해 굵은 빨간 글씨로 명확히 언급되지 않은 Hugo 문서에 대해 다소 화가 납니다. 그래도 개인 프로젝트라도 그런 문제를 미리 확인하지 않고 많은 시간을 투자하지 않도록 하는 좋은 교훈이 되었습니다.

더 알아보기:

원문은 A Java Geek에 2026년 2월 15일에 게시되었습니다.

0 조회
Back to Blog

관련 글

더 보기 »