こんにちは、自称Webエンジニアのナカハシです。
最近イベント用のサイトをHUGOで構築しました。
その際感じたHUGOに関するあれこれと、最近(?)話題のNetlifyをHUGOで利用してみた感想を書いてみたいと思います。
HUGOってなに?
HUGOは、GO言語製の静的サイトジェネレーターです。
とHUGOの紹介をしようと思ったのですが ...
実は、2年以上前にこのブログでHUGO取り上げていたんですね ... 知らなかった 😂 今回の記事とある程度重複しますが、上記の記事もぜひご覧くださいw
私が今回感じたメリットを書いておくと、
- とにかく速い
- ある程度枯れているため、(日本語)情報やエコシステムが豊富
という感じです。個人的にGOはちょっとしか書いたことありませんが、ツールとして使う分にはほとんど困りませんでした。
構築したサイトの要件
さて、今回HUGOで開発したサイトの要件ですが、以下のようなものでした。
- 記事一覧
- 記事内容
- タグ
- タグごとの一覧
- 記事一覧自体を大分類化
- GA
これらは全て、HUGOの標準機能で簡単に実現可能です。
記事一覧のように動的に記事を取得する場合には、Go templateのシンタックスでHTML内に Variables
や Functions
を使って条件を付けて行います。
たとえば、記事を単純に列挙する場合は、
<ul> {{ range .Data.Pages }} <li><a href="{{.Permalink}}">{{.Title}}</a></li> {{ end }} </ul>
と、 {{ }}
に全ページを列挙する Data.pages
を入れます。
これを日付順に並び変えるには、
<ul> {{ range .Data.Pages.ByDate }} <li><a href="{{.Permalink}}">{{.Title}}</a></li> {{ end }} </ul>
と、 ByDate
を追加するだけで実現できます。
サイト内の特定のタグ(例えば game
というタグを持つ記事)を列挙する場合は、
<ul> {{ range .Site.Taxonomies.tags.game }} <li><a href="{{.Permalink}}">{{.Title}}</a></li> {{ end }} </ul>
となります。 Taxonomies.tags
部分がタグ指定を意味するVariablesです。
記事はMarkdownで書くことができ、
--- title: こんなゲーム出るよ!! date: 2018-03-21T00:24:10+09:00 tags: ["game"] --- # こんなゲーム出るよ!! * あんなゲーム * こんなゲーム
といった形で、タイトルやタグなどのメタデータを指定できます。
GA対応ですが、サイト設定全体を行うconfig.ymlというファイルがあるのでここに、
googleAnalytics: UA-xxxxxxxx
と設定し、テンプレートファイル内で
{{ template "_internal/google_analytics_async.html" . }}
唱えればいいだけです。 googleAnalytics
を設定しなければ、GA用タグはビルド内容から外れるだけです。
Hugoは、上記のようにGo templateで書いたHTMLによるレイアウトファイルと、Markdownで書いた記事ファイルを結合し、いい感じにHTMLを出力(ビルド)してくれます。
デプロイ
さて、Hugoが出力したファイルのデプロイですが、今回は歴史的な経緯もあって、AWS S3の静的ウェブサイトホスティング機能で公開することにしました。
手元で記事を編集した後にS3への転送コマンドを叩いてもいいのですが、記事編集を非エンジニアが行う*1というユースケースを考慮し、今回はCircleCIによる自動ビルド~デプロイを行うことにしました。
.circleci/config.yml では、 hugo
コマンド(及びsassやbabelなど)でビルドを実行後するようにし、出力されたHTML群を以下のようなfabfile.pyでデプロイするスクリプトを書きました。
env.src_dir = 'public' env.dist_dir = 'dist_dir' @task def deploy(): _rsync() def _rsync(): local('aws s3 sync --delete --region ap-northeast-1 %(src_dir)s s3://s3_bucket/%(dist_dir)s' % env)
Hugoはビルド結果を public
というディレクトリに出力するので、その内容をS3に出力するよう、 aws s3
コマンドを実行しています。
今回はCloudFrontによるCDN配信も行っていますが、デプロイ時にはキャッシュをクリアするよう、CircleCI内で以下のコマンドを実行しています。
aws configure set preview.cloudfront true aws cloudfront create-invalidation --distribution-id ${CLOUDFRONT_DISTRIBUTION_ID} --paths '/*'
これでめでたく、Git push → Hugoによるビルド → S3へのデプロイができるようになりました。
Netlifyって?
さて、最近静的サイトのホスティングでは、Netlifyを使う例が増えてきているようです。Hugoを使ったサイトの公開を試してみることにしました。
公開
まず、とりあえず公開してみましょう。手順は超簡単でした。
- GitHubにHugoで作ったサイトをpushする(ビルド結果はここに含めなくてよい)
- Netlifyでサイト新規作成し、1.で作ったリポジトリを指定
- 「Deploy site」ボタン押す
なんとこれで終了。ビルド~デプロイにかかる時間は約10秒(CircleCIで実行した場合は2~3分程度かかる)。爆速過ぎます。
※ 私の場合、使ったテーマの問題なのかHugoビルドがうまくいきませんでした。その場合、手元のクライアントでビルドした時と同じHugoのバージョンを環境変数で以下のように設定するといいようです。
HUGO_VERSION=0.37.1
HTTPS
HTTPSも超簡単です。
- ドメインとる(今回は freenom で取ってみました)
- DNSにNetlifyのサーバーを指定(freenom の場合は、ドメイン管理画面内で行えました)
- Netlifyの管理画面内の「SSL/TLS certificate」に周辺設定を行う(ドメイン確認や証明書配置など、段階に応じてボタンが変わるので、それを押していくだけ)
たったこれだけで、HTTP → HTTPSの転送も含めたHTTPSによるサイト公開ができました。
証明書は、Netlifyが自動的にLet’s Encryptを使って配置してくれます(更新も自動)。証明書の種類にこだわる向きには、持ち込みの証明書にも対応しているようです。
まとめ
単純なコンテンツサイトを構築しようという場合、頑張ってWordPressとか立てるのがあほらしくなるくらい、HugoやNetlifyは便利です。
node_modulesのようなフロントエンドの技術スタックも問題なく使えるので、コーディングの上での制限も少ないといえます。
必要に応じて、バシバシ使っていきましょう。
*1:この場合、GitHub上のエディタで直接記事を作成・マージしてもらう運用にしました。