はいさい!。ブログをはてなブログから Hugo + Github Pages に移行したので備忘録もかねて色々書いていきます。

移行のモチベーション

はてなブログに大きな不満があったわけじゃないんですが、移行した主な理由は以下です。

  • 有料プラン(月額 980 円)がもったいない気がしてきた
    • 独自ドメインを使いたかったんですが、現在の更新頻度だともったいなく感じた
    • 実際には 1 年コースでの契約だったので、月 703 円ぐらいでした
  • 編集画面が全体的にもっさりしている
    • 前提として、はてなブログの編集画面はリッチな機能いくつもあるし、ブラウザから使うのでしょうがない気もします
    • Hugo の様にローカルのエディタでマークダウンファイルを編集できるフットワークの軽さには劣る印象

移行先の選定

Wordpress + 適当な安いホスティングみたいな組み合わせに戻ろうかなとも思ったんですが、最終的には以下の様な理由で Hugo (+ Github Pages )にしました。

  • 静的サイトジェネレーターが軽快でよさそうだった
  • ホスティング先の選択肢が自由度高そうだった
    • GithubPages をはじめ無料プランでホスティングできる所も結構ある
  • 記事がマークダウンファイルで管理できて便利
    • ローカルでの編集も楽だし、 Hugo から移行する事になっても元データがマークダウンなので何かと都合がよさそう
    • VS Code とかで編集できるのは控えめにいって神

静的サイトジェネレーター自体は Hugo 以外にもたくさんの選択肢がありますが、個人的に Golang を勉強していきたかったという気持ちがあった(勉強したとは言っていない)のと、比較的情報がネットに落ちてた点を加味し Hugo を選択しました。

ちなみに、 Hugo でサイトを生成するだけなら Golang の知識は特に入りません。(強いて言えば環境設定と Git の知識があれば捗ると思いますが、なくてもググりながらでなんとかなると思います。)フレームワークって偉大(小並感)。

ホスティング先の選定

静的ページをホスティングできればいいので選択肢は色々とありますが、無料でそれなりの容量( 1 GB)と通信量( 10 GB)が使えるので Github Pages にしました。( 2022/5/4 時点の情報です。制限の詳細は「 Limits on use of GitHub Pages 」を確認してください。)

このブログの PV 数的にこれらのリミットを超過する事はないと思われますが、万が一超過したら他のサービスへの移行を検討する必要がありそうです。

諦めた事

当然、諦めた点もあって、この辺は自分の必要な機能に応じて選ぶ形になるのかなと思いました。

  • 記事や画像等のコンテンツの管理( CMS )機能
    • 特に画像を多く使う人は自前でディレクトリやパスを管理するのは結構大変だと思います
  • リッチコンテンツを取り扱う補助機能等
    • Amazon の商品リンクとかを(見た目も良い感じに)簡単に挿入できたりとか、その手の機能は使えません
    • hugo でも実現できるかもしれないけど初心者なのでよく分かりません => shortcodes で対応できそうでした(参考)
  • 記事の移行
    • 手作業で内容を移して、画像もアップロードしなおすetc…とか考えるとちょっと面倒な気がした
    • いまや週間で 50 PV みたいなレベルのアクセス数なので移行しなくても誰も困らない気がした

色々手間が増える部分もありますが、今回は昔ほど画像を沢山つかうモチベもないかなという気がしたので、画像は imgur にアップロードしてリンクする形で対応する事にしました。(ホスティング先の転送量を節約する観点でも有りかもしれません。とはいえ imgur がサービス終了するみたいな事になると困るわけですが、とりあえず、今は気にしないでおきます。)

Hugo でサイトを作成する

前置きが長くなりましたが、構築時の手順を備忘録もかねてメモ書き。基本的には Hugo 公式の quick-start に準拠していますが、はまった所を中心にメモ。

Hugo でのサイトの作成

以下のコマンドでディレクトリが作成されて必要なファイルが配置されます。 -f yml を指定すると設定ファイルを yaml にできます。

hugo new site ディレクトリ名 -f yml

テーマの追加

今回はシンプルそうなデザインだったのと更新が盛んに見えたので PaperMod を使いました。テーマの更新に追従できる様に、 git submodule を使用します。

git init
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

(自分の)リポジトリを clone してきた時に submodule はくっついて来ないので以下を打つといいらしいです。

# submodule 付きのリポジトリを clone した時
$ git submodule update --init --recursive

submodule (今回であればテーマファイル)をアップデートする時は以下

git submodule update --remote --merge

テーマ毎に設定が必要な場合がありますが、ここでは省略。( PaperMod を使用する場合にはこちらを参照してください。)

コンテンツの追加 & テンプレートの作成

Hugo では archetypes/ 配下のテンプレートを使って記事を作成できるみたいでした。(参考

ブログ用途であれば、基本的には同じテンプレートでかまわないので archetypes/default.md を以下の様に編集しました。毎回入力するものがあればお好みで足しておくと良いと思います。

---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
categories: ["Others"]
tags: ["","",""]
Authors: "ぽっちゃす"

# Default slug
slug: {{ .Name }}

# If need cover image
#cover:
#    image: "<image path/url>" # image path/url
#    alt: "<alt text>" # alt text
#    caption: "<text>" # display caption under cover
#    relative: false # when using page bundles set this to true
#    hidden: true # only hide on current single page
---

<!--more-->

これで、 hugo new すれば、上記が入力済みの状態でマークダウンファイルが作成されます。(配置されたディレクトリに準拠したパス(上記であればexample.com/posts/記事名/)でアクセスする事になる点に注意。)

URL 自体は上記のままでもいいんですが、管理する事を考えると同じディレクトリに全ての記事を追加していくのは厳しい気がしたので、今回は年別のディレクトリに配置していく事にしました。この辺は更新頻度やコンテンツ量に応じて変更すればよいと思います。

hugo new post/YYYY/m-d-title.md

毎回手入力は面倒なので、以下の shell スクリプトを作成しておきました。

#!/usr/bin/zsh
cd ディレクトリ名
slug="$1" #引数
file_name="posts/$(date +"%Y/%m-%d")-${slug}.md"
hugo new "$file_name" --editor code
hugo -D server

これで、以下のコマンドで同じ規則に基づいたファイル名で新規ページが作成され、作成されたページを VS codeで開く & ローカルサーバが起動します。(シェルスクリプトは一つ上のディレクトリに配置してます。)

source ../new_post.sh タイトル

静的ページの発行

ページを追加したあとは、カレントディレクトリで hugo コマンドを打つことで静的ファイルが出力される(デフォルトでは public ディレクトリが作成される)ので、これをホスティング先にルートディレクトリとして配置する事でサイトを公開できます。

hugo

Github Pages にデプロイする

先述の通り、生成されたファイルをホスティング先で公開すれば良いわけですが、毎回、ページの発行 & デプロイをするのは面倒なので、以下の様な構成にしました。

  1. プライベートリポジトリで作業用のファイル( Hugo に必要なファイル)を管理
  2. プライベートリポジトリに push されたら、 Github Actions を実行しページを発行する
  3. 発行されたページを公開用のリポジトリに push する

1 つのリポジトリでで公開することも可能ではありますが、( 無料プランだと Github Pages はパブリックリポジトリでしか使えないので)リポジトリを参照されると下書き( draft )のページも見える可能性がある為、(ブログ目的であれば)作業用と公開用のリポジトリは分けたほうがいい様に思えました。

無料プランのアカウントの場合、パブリックリポジトリでのみ Github Pages が利用できる( 2022/5/4 時点)ので、公開用のリポジトリは必然的にパブリックリポジトリを使うことになります。

変更履歴とかが丸見えになるのも気持ち的に微妙だった & お世話になるサービスへのお布施もかねて pro プランにしましたが、月額 $4 に値下げされたとはいえ、サイトにアクセスした時に見えるものと同じソースが観覧できるだけなので特に拘りがなければ無料プランで良い気がします。

以下、作業用と公開用のリポジトリを作成した前提で進めます。

プライベートリポジトリに push する

( Hugo で生成した)カレントディレクトリをリポジトリに push します。

git add .
git commit -m "first commit"
git remote add origin https://github.com/pottyasu/your-private-repository-name.git
git push -u origin main

Github Actions のワークフローを追加する

作業用ディレクトリの .github/workflows/gh-pages.yml を追加する事でワークフローを追加できます。以下を参考に作成しました。

ワークフローをを実行するリポジトリとは別のリポジトリにデプロイを実施する場合には、予めリポジトリの操作権限を与えたデプロイキーか個人用アクセストークを設定しておく必要がありるので注意。今回は個人用アクセストークを作成して指定しておいた。

完成した gh-pages.yml は以下の通り。

name: GitHub Pages

on:
  push:
    branches:
      - main  # Set a branch to deploy

jobs:
  deploy:
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'
          # extended: true

      - name: Build
        run: hugo --gc --minify --cleanDestinationDir

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          personal_token: ${{ secrets.ACTIONS_DEPLOY_KEY }}
          external_repository: username/username.github.io
          publish_branch: main
          publish_dir: ./public
          cname: 独自ドメインを使う場合

hugo コマンドのオプションには --gc (ビルド後の不要なキャッシュファイルの削除)と --minify ( html ファイル等の圧縮)、 --cleanDestinationDir (基となる .md ファイルが削除されてる場合、 public フォルダから消してくれる)を指定した。そもそも毎回ビルドして静的ファイルのみをデプロイするアクションなので指定がなくても問題ない様な気はするが、一応、、指定しておく事にした。

リモートリポジトリに push する

これでローカルで記事を作成した後(コミットした後)に push するだけで、ワークフローが実行され生成された静的ファイルがデプロイされる。

git add.
git commit -m "commit message"
git push -u origin main

ちなみに、 VS Code ならコマンドラインからじゃなくても git の操作が可能で結構便利でした。(参考

Github Actions のビルド時間

とりあえず、現時点ではワークフローの実行時間は 20 秒前後でした。ページ数が増えていくと実行時間伸びる可能性がありますが、個人サイトであれば無料枠( 2000 分)を超過する事はあんまりない気がしますね。

おわり

とりあええずこれで一通りサイトとしてみれる所まで完了です。 GW 中に終わって良かった。

ローカルのエディタで記事を書いてリポジトリに push するだけでデプロイされるのは想像の数倍体験が良かったので満足です。

一方で、あくまでマークダウンファイルをもとに静的サイトを出力するだけなので細かい機能はテーマ側の実装に依存しています。例えば、 Twitter カードやグーグルアナリティクス ID の挿入とかは対応しているテーマを導入するか自前でやる必要があります。テーマに依存する前提だと、やっぱりメジャーな wordpress とかに比べると選択肢は少ない気がしました。将来的には自前でテーマ作れるといんですが、またの機会の宿題にしておきます。