サイバーディフェンス研究所 アドベントカレンダー 2022 の 1 日目です。 突然のアドベントカレンダー企画に馳せ参じてくれた同僚各位に感謝しつつ、最後まではりきって続けていきたいと思います。 1 日目となる今日は、数ヶ月前に七夕リリースをキメた当ブログの技術的舞台裏をつづっていきたいと思います。
サイバーディフェンスのコーポレートブログ『DARK MATTER』をリニューアルしました。
— サイバーディフェンス研究所|脆弱性診断・ペネトレーションテスト・フォレンジック・脅威インテリジェンス (@cyberdefense_jp) July 7, 2022
圧倒的に読みやすくなっているはず!これからぐんぐん更新頻度を上げていきたい、つもりの、気分でいます!
引き続きご愛顧のほど宜しくお願いいたします。https://t.co/D1jiVOJGWP
移行のきっかけ
当ブログは 2016 年 5 月に産声を上げてから 6 年間、はてなブログを利用して情報発信を続けてきました。 この間、記事のレビュー段階で「この記事、はてなブログの利用規約に反してるかも。修正しなきゃ。」とか「利用規約に反するから書けない。。」という声が届くことがありました。
管理人的には移行するのもとても面倒だしはてなブログは使いやすくてサポートもよかったのでやや渋々ではありましたが、プランのアップグレードはせずに静的サイトジェネレーターを使ったコンテンツホスティング形式に移行することにしました。
移行にあたってお世話になったサイトの URL をペタペタ貼りながら、どのようにサイトを移行したかについてご説明します。
Hugo について
Hugo は人気のある静的サイトジェネレーターです。 Markdown などで書いた記事を HTML 出力します。 CMS のような使いやすさには欠けますが、アカウント管理や脆弱性対応などでほとんど悩まなくて済むというセキュリティ上のメリットがあります。
テーマを使ってサクッとサイトを作ることもできます。 当ブログのオーナー、広報担当と 3 人で結構な時間を使って Hugo Themes からサイトのベースとなるテーマを選定しました。 機能性もさることながら、3 人が圧倒的に読みやすいと感じた Stack を使わせて頂くことにしました。
テーマを使ってとりあえず動くところまでなら Quick Start あたり見ながら手を動かすとすぐですが、テーマをカスタマイズしたくなってくるとそれなりにドキュメントを読み込むことが必要になります。 はてなブログで便利に使っていたパーツなども再現しようとするとなおさらです。
- Hugo のドキュメント
- Stack テーマのドキュメント
- コードを読むとドキュメントに書いてない機能が見つかることも😅
Hugo の静的 HTML 生成は Go 言語の template パッケージに大きく依存していて、テーマのコードを読み書きしたり、新たな機能を追加しようと思った場合は Go template の理解が欠かせない感じです。 私は都度検索してやっていましたが、Hugo の Templates というページ にまとまっているように見えます。
Hugo には表現力に乏しい Markdown を補強する Shortcodes があります。 Shortcodes をさらに機能拡張したくなった時は Hugo の Shortcodes 実装 を参考にすると便利でした。
コンテンツホスティング
Hugo で生成した HTML ファイルのホスティングには Cloudflare Pages を利用しています。 既に有償プランを契約済だったということもありますが、圧倒的な制限の少なさが決め手でした。
Cloudflare Pages へのコンテンツのデプロイ方法はいくつかありますが、複数人での記事の制作やレビューがしやすくなるよう考えた結果、社内の GitLab サーバーから GitLab CI/CD でアップロードする方式にしました。 Cloudflare Pages のみに権限を絞ったトークンを発行し、wrangler というツールでデプロイします。
手順をさらっと書くと次のようになります。
- 社内 GitLab に Hugo のコンテンツ用リポジトリを作成
- Markdown で記事を作成し、記事本文や画像をリポジトリにアップロード
- マージリクエストを作成
- (自動)GitLab CI/CD および GitLab Pages でレビュー用の Hugo サイトを社内にデプロイ
- GitLab のマージリクエストのレビュー 機能を使ってレビュー、修正
- 記事が完成したらマージ
- (自動)再び GitLab CI/CD のパワーで Cloudflare Pages の本番サイトへデプロイ
複数人のレビューがしやすくなったという点だけが、機能的にはてなブログを上回れたかもしれません。。 あとは静的コンテンツ化したため表示速度は圧倒的に早くなったかと思います。
GitLab
さらっと書いてしまったので GitLab に馴染みのない方にはわかりにくかったかもしれません。 GitHub と似たようなリポジトリ管理やバージョン管理、自動化、静的ウェブページのホスティング、チャット連携などなど万能感あふれるソフトウェアです。 弊社では GitLab Enterprise Edition サーバーを社内で運用しており、ブログ制作のワークフローにガッツリ組み込むことにしました。
Git という単語が出てくるとプログラミングをイメージしがちかもしれませんが、GitLab はドキュメントの作成・管理にも大変便利です。 利用するだけなら Git を覚えなくてもなんとかなる場面も多く、ブログ制作は GitLab をブラウザで操作だけで完結するフローにしました。
ブログ制作のマニュアルも GitLab リポジトリに作成しており、GitLab CI/CD で静的ウェブページ化、GitLab Pages で公開しています。
記事データの移行
これは非常に骨が折れました。
はてなブログで記事を書く際、3 つの記法(見たまま、はてな記法、Markdown)が用意されていますが、弊社では 3 つとも使用していました。
そして、記事データの取得方法は 2 つありました(他にもあるかも?)。 MT(Movable Type)形式のブログデータとして書き出す方法と、Atom Publishing Protocol(AtomPub)で取得する方法です。 MT 形式で得られる記事本文のデータは、記法によらず HTML でした。 AtomPub だと HTML 変換前/後の両方のデータが得られました。
HTML を Hugo 用の Markdown テキストに変換するか、3 つの記法で書かれた記事を Hugo 用の Markdown テキストに変換するか、非常に悩ましい問題です。 HTML をそのまま Hugo に使うこともできますが、はてなのブログパーツや画像を使い続けてしまうことになったり、はてな独自のスタイルなどが残ってしまったりと問題が多いためこの方法は除外しました。 幸いなことに、どちらの方法も先人が "道" を残してくれていました。
- hatena-blog-to-hugo: はてなブログのMTファイルを静的Web生成ツールHugo用データに変換
- はてなブログの記事を Hugo に移行するツールを作ってみた
MT 形式と AtomPub 両方のデータを組み合わせないと欠けた情報が存在することがわかったので、後者のツールをベースに両方のデータを使用するようにしました。
追加したコードなどを元のツールに還元したかったのですが、、 if(title == "特別な置換が必要な記事のタイトル"){ アレをコレに置換 }
のようなコードが散乱してしまったりなんだりと、このまま使い捨てるしかないコードになってしまいました。
他にもお世話になったライブラリと、最後は目視でレビューしてくれた方々に感謝しながらこの話題は終了します。
- https://github.com/JohannesKaufmann/html-to-markdown
- https://github.com/otiai10/opengraph
- https://github.com/saintfish/chardet
- https://github.com/soh335/mtexport
カード型リンク
はてなブログでは "ブログカード" と呼ばれる、あのきれいなカード型のリンクです。
カード型リンクを再現する良い方法はないかと模索したところ、Hugoでビルド時にデータ処理した話 -カード型リンク編-というありがたい記事がありました。 こちらを参考に GitLab CI/CD のタイミングで OGP の Data Templates を作成する Go の小さなプログラムを作成し、Hugo のビルド時にカード型リンクを作成する Shortcode を用意する形にしました。
なんだか日本の偉大な先人が多いですね 🎉
Twitter カード
SNS 投稿時のきれいな画像生成機能も欲しくなって探したところ、こちらでも日本っぽい方が!
Hugo って日本で大流行してたりするんでしょうか? tcardgen ありがたく使わせて頂きました🙇
ブログカードのデザインは、社内インタビュー記事で華々しいデビューを飾ったメディアクリエイター兼ブログ編集者兼広報担当兼..兼..兼.. の Keishi Tsuboi さんにお願いしました。
半透明の画像を重ね合わせる機能を追加したり、文字数が多くてはみ出す時はフォントサイズを自動調整する機能を追加してみたり。 過去に絵文字入りタイトルの記事を書いたせいで絵文字対応する羽目になるというブーメラン芸も披露しました🪃。
- Goでカラー絵文字を使って画像を合成する
- GoMoji: Go で絵文字を便利に扱うパッケージ
- The Go image package: アルファブレンディングの参考になった記事
うまく描画できる絵文字とできない絵文字が出てきて、絵文字には variation selectorという仕組みがあるという学びもありました。
大急ぎで作ったため、元々のツールにあったレイアウトを定義する機能を削除して、弊社用固定テンプレートのみ処理するようにしてしまいました。 ちゃんと汎用的に作るのって難しいですね。。
こちらも GitLab CI/CD に組み込んで自動的に画像生成し、好きなものを選択できるようにしました。
出来上がった画像を折りたたんで並べておきます(クリックで表示)⚗️🧪🪃
おわりに
ぱっと思い当たった移行作業の思い出は以上になります。 デザイナー兼デザイナーの Keishi Tsuboi さんに細かな色使いやレイアウトなど指導してもらったり直接修正してもらったりしつつ、公開までに 104 の Issue を消化しました。
インターネットのいろいろなパワーを借りながら、なかなかいい感じのブログ移行が出来たのではないかと思っています。 いろいろこだわってしまったせいか、移行するのに 1 ヶ月近くの時間をかけてしまいました。 ほとんどリンク集のような記事になってしまいましたが、少しでも誰かの役に立つ情報として還元できていれば幸いです。
最後に、6 年間お世話になったはてなブログに感謝申し上げます。