HugoサイトをGitHub Actionsで自動デプロイする設定メモ
May 24, 2026
はじめに #
HugoサイトをGitHub Pagesで公開する際、従来は以下の手順で手動運用していた。
- Markdownを編集
hugoコマンドを実行してdocs/を生成docs/を git commit- git push
この運用をGitHub Actionsによる自動ビルド・自動デプロイに移行したので、その手順とトラブルシューティングをまとめる。
環境 #
- Hugo: v0.152.0+extended (darwin/amd64)
- テーマ: hugo-book(git submodule管理)
- 多言語構成: 日本語(デフォルト)/英語
- リポジトリ: GitHub(masterブランチ)
GitHub Actionsワークフローの設定 #
.github/workflows/hugo.yml を以下の内容で作成する。
name: Deploy Hugo site to GitHub Pages
on:
push:
branches:
- master
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
defaults:
run:
shell: bash
jobs:
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.152.0
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb \
https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Build with Hugo
env:
HUGO_ENVIRONMENT: production
run: |
hugo \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/"
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./public
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
ポイントは以下のとおり。
HUGO_VERSIONは自分の環境に合わせる(hugo versionで確認)- テーマをgit submoduleで管理している場合は
submodules: recursiveが必要 - hugo-bookのようなextended版が必要なテーマには
hugo_extended_を使う
GitHub Pagesの設定変更 #
リポジトリの Settings → Pages → Build and deployment → Source を
“Deploy from a branch” から “GitHub Actions” に変更する。
config.tomlの修正 #
publishDir = "docs" をコメントアウトし、.gitignore に public/ を追加する。
# publishDir = "docs"
public/
トラブルシューティング #
移行作業中にいくつかのエラーが発生した。
1. フロントマターの重複定義 #
エラー:
mapping key "bookCollapseSection" already defined
_index.md のフロントマターに同じキーが2回定義されていた。片方を削除して解決。
2. TOMLとYAMLの混在 #
エラー:
string was used where mapping is expected
--- で囲まれたYAMLフロントマターの中に、TOML形式(= を使う記法)が混在していた。以下のようにYAML形式に統一して解決。
---
title: "記事タイトル"
date: "2022-01-06"
tags:
- "タグ1"
categories:
- "カテゴリ1"
---
同様のファイルを一括検索するには:
grep -rl "^title = " content/
3. docs/以下がビルドされない(404エラー) #
症状: https://example.github.io/docs/krm/01-introduction/ が404になる。
原因その1: content/docs/_index.ja.md と content/docs/_index.en.md が存在しなかった。多言語構成では各セクションに言語別の _index.md が必要。
printf -- '---\ntitle: "Docs"\ndraft: false\n---\n' > content/docs/_index.ja.md
printf -- '---\ntitle: "Docs"\ndraft: false\n---\n' > content/docs/_index.en.md
原因その2: config.toml の defaultContentLanguage の記述位置が間違っていた。
TOMLでは [section] 以降の設定はすべてそのセクションに属する。[languages] セクションの後ろに書いた defaultContentLanguage = "ja" は無視され、デフォルトの en が使われていた。
誤った書き方:
[languages]
[languages.ja]
languageName = "Japanese"
defaultContentLanguage = "ja" # [languages]セクション内として解釈される
正しい書き方:
defaultContentLanguage = "ja" # [languages]より前に書く
defaultContentLanguageInSubdir = false
[languages]
[languages.ja]
languageName = "Japanese"
weight = 1
[languages.en]
languageName = "English"
weight = 2
設定が正しく反映されているかは以下で確認できる:
hugo config | grep -i "defaultcontent"
改善後の運用フロー #
Markdownを編集 → git push → GitHub Actionsが自動ビルド&公開
docs/ ディレクトリをgit管理から外せるため、リポジトリが軽くなる。ビルド履歴もCIログで確認できる。
まとめ #
今回のつまずきポイントは主に2つだった。
- TOMLのセクション仕様:
[section]以降の設定はすべてそのセクションに属するため、グローバル設定は必ずセクションより前に書く必要がある - 多言語構成でのセクションindex:各コンテンツディレクトリに言語別の
_index.mdが必要
どちらもエラーメッセージだけでは原因が見えにくく、設定ファイルの構造を丁寧に確認することで解決できた。