HugoのRender Hooksを利用してブロックの表現を拡張する

当ブログはHugoで構築していて、Markdownを使って記述しています。テーマを簡単に作れるので、自作テーマで好みに合わせてカスタマイズできるのが気に入っています。

しかしHugoが解釈できるMarkdownで表現可能な書式には限界があります。 そのためか、Markdownの一部表記からHTMLへの変換内容を自分で定義できるRender Hooksという機能が用意されています。

Hugo v0.93.0からはcodeblockのhookが追加され、以下の4種類のhooksを定義できるようになりました。

  • image
  • link
  • heading
  • codeblock

今回はnoteという名前でcodeblockのhookを作成し、注釈を記載するためのブロックを表現できるようにします。

記述例

```note
このように左に注釈の種類を示すアイコンを、右に注釈文を表示するようにします。
```

表示例

情報
このように左に注釈の種類を示すアイコンを、右に注釈文を表示するようにします。

Render Hooksの作成

HugoのMarkdown Render Hooksマニュアルによると、layouts/_default/markup/フォルダに規則に従った名前のファイルを作れば良いようです。

自作のテーマに追加するので、テーマ側のフォルダにrender-codeblock-note.htmlを作成してみました。

アイコンはMaterial Design IconsからSVG形式のアイコンを使用させていただきました。

render-codeblock-note.html

<div class="note-block">
  {{- $type := default "info" .Attributes.type -}}
  <div class="icon">
    {{- if eq $type "info" }}
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="icon-info">
      <title>情報</title>
      <path d="M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z" />
    </svg>
    {{- else if eq $type "warning" }}
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="icon-warning">
      <title>警告</title>
      <path d="M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z" />
    </svg>
    {{- else if eq $type "errata" }}
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="icon-errata">
      <title>訂正</title>
      <path d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12H20A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4V2M18.78,3C18.61,3 18.43,3.07 18.3,3.2L17.08,4.41L19.58,6.91L20.8,5.7C21.06,5.44 21.06,5 20.8,4.75L19.25,3.2C19.12,3.07 18.95,3 18.78,3M16.37,5.12L9,12.5V15H11.5L18.87,7.62L16.37,5.12Z" />
    </svg>
    {{ end -}}
  </div>
  <div class="note">{{- .Inner | markdownify }}</div>
</div>

css抜粋

.note-block {
  display: table;
  margin: 0 5px;;
}

.note-block .icon {
  display: table-cell;
  vertical-align: middle;
  border-right: 1px solid gray;
  margin: 0 16px 0 0;
}

.note-block .icon svg {
  padding: 8px;
  width: 48px;
  height: 48px;
}

.note-block .icon .icon-info {
  fill: steelblue;
}

.note-block .icon .icon-warning {
  fill: goldenrod;
}

.note-block .icon .icon-errata {
  fill: dimgray;
}

.note-block .note {
  display: table-cell;
  vertical-align: middle;
  padding: 0 0 0 16px;
}

.note-block .note p {
  margin: 8px 0;
}

アイコンの使い分け

ブロックにattributeを渡すことができるので、アイコンの使い分けはtypeという名前のattribute経由で指定できるようにしてみました。

type指定を省略するとinfoとして扱うようにします。

attribute指定例

```note {type=info}
```

{type=info}表示例

情報
情報です。

{type=warning}表示例

警告
警告文です。

{type=errata}表示例

訂正
訂正文です。

作ってみての所感

ブロックの使い方として正しいのかは置いておいて、markdown側の表記が比較的シンプルに済んだので習作の割に使い勝手良い物になりました。

hook側の定義が泥臭いように感じていて、もっと良い書き方がありそうに思うのですが、まずはこのまま使ってみて良い方法を見つけたら改良したいですね。

他にも、CLIのコマンドと出力結果をもっと見やすくできないかと常々考えていたので、Render Hooksを上手く利用して理想通りの表示ができるようにしたいです。

サーバーソフトウェア更新 3

自宅サーバーでは、当ブログ以外にもプライベートで使用するソフトウェアをいくつか稼働させていました。それぞれの移行手段について纏めてみました。

Wordpress

当ブログ公開用に運用。ただし全然使いこなせていないしコードを載せるには標準のエディタは使いにくく、以前からMarkdownあたりで書ける別のソフトウェアに乗り換えようと考えていました。

たまたま知ったHugoが良さそうだったので、デザインをちょっと寄せたテーマを自作してWordpressから移行してみました。内容は直接移行する手段がないため、WordpressでエクスポートしたXMLを個別のファイルに分割するスクリプトを書き、手作業で調整しました。1

内容やテーマは後述のGitLabで管理することにしたので、更新もGitLab CI/CD機能を利用することにしました。

GitLab

GitLabは、かつてGitHubがフリープランでプライベートリポジトリを作成できなかった時代に個人用のリポジトリを管理するために使い始めました。 そのままGitHubとは使い分けながら使い続けています。

今まではOmnibus版をインストールしていましたが、幸い開発元によるDockerイメージが公開されている2ので、活用することにします。

データの移行については、公式ドキュメントのBack up and restore GitLabに沿って今までのサーバーでバックアップを作成、コンテナにバックアップデータを入れたディレクトリをマウントしてリストア実施でできました。

GitLabそのものの制約としてリストア先のGitLabのバージョンはバックアップ取得時点のものと一致していなければなりません。DockerHubに各バージョンがタグ付きで公開されていますので、リストアを実施するときはきちんとタグを指定してコンテナを起動するのが間違いないでしょう。

リストア完了後、タグ指定を新しいバージョンに変更するかlatestにしてしまえば、コンテナ起動時にデータのマイグレーションが実行されます。

FreshRSS

かつてはGoogle Readerを使っていて、Feedlyに流れ着くもWeb UIが合わずセルフホスティングの安心感に惹かれたのも相まってFreshRSSに落ち着きました。

私が重視しているのはデスクトップとスマートフォンで既読フラグとブックマークが共有できること、そしてスマートフォンで使用しているReederが連携できることでした。FreshRSSを知ったきっかけもReederのバージョンアップで新たな対応サービスとして追加されたことです。

こちらも開発元によるDockerイメージが公開されているので、今まで直接インストールしていた環境からデータを移行させました。と言っても設定ファイル以外の実データはデータベースの中なので実質データベースのダンプとリストアに終始することになりました。

ownCloud

Web UIでファイル管理できるし、簡単な世代バックアップも付いているしそれ以上の込み入ったことはしないのでとNextCloudがフォークされた後もそのまま使い続けていたのですが流石に限界3だったので、この機会にNextCloudに移行することにしました。

NextCloudはDockerによる公式イメージを使用しました。ownCloudからの移行も公式ページにMigration guideがあり、この文書に沿って作業すれば良いです。

ただし、私が作業した時(2023/3頃)にはマイグレーションスクリプトのownCloudバージョン判定が正しく機能せず、使用中のownCloud 10.10に対応した移行先のNextCloudバージョン選定に失敗していたため一筋縄ではいきませんでした。 現在(2023/5/5)はドキュメントが整備され、Migrating from ownCloudにownCloud 10.11.xからの移行について書かれているので、私が作業した時から状況が改善されたようです。

Mattermost

2022年9月からSlackのフリープランの内容が変更されたことから、セルフホスティングのMattermostに移行していました。

時期的には既に今回のコンテナ化を見据えていたので、最初からコンテナで稼働させています。ですのでデータの移行もコンテナにマウントしているディレクトリをコピーするだけでした。

なお、Slackからの移行についてはMattermost側でmmetlというツールが用意されているのですが、一部のデータが変換されず欠落してしまったので移行ツールを自作しました。

移行ツールはGitHubにてmmconverterという名称で公開しています。


  1. 良くも悪くも、元々の投稿数が少なくコード以外の書式設定が少なかったからできたことです。 ↩︎

  2. どうやらOmnibus版をそのままコンテナに押し込めたようで、GitLab本体とデータベースが同一のコンテナで稼働するなかなか強引な作りですが、更新頻度が高いのは安心材料です。 ↩︎

  3. 移行後に知ったのですが、ownCloud自体もownCloud Infinite Scaleとして作り直されていました。 ↩︎

サーバーソフトウェア更新 2

VMで稼働させていたサービスをコンテナに置き換えることに決定したので、次は新環境のソフトウェア選定です。

コンテナの稼働に特化したOSとなればFedora CoreOSやProxmox Virtual Environmentなどが存在しますが、今回は私が扱いに慣れているAlpine Linuxを使うことにしました。

コンテナ技術絡みでは、Alpine Linuxはコンテナイメージを軽量に作成できるベースイメージとして広まったように思います。この軽量という特徴はコンテナを動かす基盤として使用するにも都合が良いと考えられます。

なお、Alpine Linuxは軽量にするために他のディストリビューションとは標準Cライブラリや標準コマンドの非互換があり、稼働させるソフトウェアによっては相性が悪い場合があります。これはコンテナイメージのベースとして使用する際は場合によって無視できない要因ですが、コンテナを動かすだけであれば問題になることはないでしょう。

パッケージリポジトリに登録されているパッケージは充分な種類があり、パッケージのバージョンについても随時更新されているようです。何はともあれ必要になるDocker CEが(communityリポジトリではありますが)収録されているのは便利です。

もう一つOS選定に関わる要素がデバイスのサポートです。今回のソフトウェア更新は、使用中のRAIDカードがESXiの最新版でサポートされなくなってしまったことがきっかけの一つでした。問題のRAIDカードはLinuxカーネルに含まれているドライバが対応していたため特に手を加えることもなく動作しました。この件についてはLinuxベースであるCoreOSやProxmox VEでも同様に対応しているものと思います。1

また、コンテナを使いますがハードウェアは1台のみ、オーケストレーションもしないと割り切っているので、通常のLinux上で直接コンテナを実行する形態で充分と判断しています。流石に落ちたらそのまま放置という訳にもいきませんので、docker composeで死活監視を含め管理する想定です。


  1. カーネルのバージョンやビルドオプションに依存するでしょうし、各OSについて検証してはいないので正確にはわかりません。 ↩︎

サーバーソフトウェア更新 1

2月から3月にかけて自宅サーバーのソフトウェアを入れ替え、最新化しました。

もともとこの自宅サーバーは2017年4月にハードウェアを新調していました。(参考: 2017年以前のサーバー構成)

主にストレージを入れ替えながら、現在の構成はこのようなものになっています。

  • CPU:
    • Xeon E3-1240L v5
  • Memory:
    • DDR4-2666 32GB ECC
  • Boot Strage:
    • NVMe SSD 512GB
  • Data Storage:
    • RAID Controller: Adaptec RAID 6405E
    • HDD: WD Red Plus 10TB x 2 (RAID 1)

2017年にハードウェアを新調した時点では、前サーバーと同じくVMware ESXiをインストールしていました。 そのままv6.5 Update3まで更新しつつ運用していたところ2022年10月にサポートが終了し、v7.0以降にアップデートする必要が出たのですが…

使用しているRAIDカードがESXi v7.0以降に対応していない1ためアップデートを断念しました。

他にも複数の理由により、サーバーのソフトウェアを見直す時期が来たと判断しました。

  • VMを10台ほど起動していたためメモリの余裕がなく、ここ最近はやりくりに苦労していた
    • 解決のためVMからコンテナへ移行してのメモリ効率向上を計画していた
  • CentOS 7のサポート終了が近づいてきたためそろそろマイグレーションの準備をしなければならない
  • Windows Server 2012 R2のサポート終了が迫っているので、Linuxで代替する準備を始めなければならない

以前より部分的にコンテナ技術を導入・検討していたこともあり、今回はハードウェア構成はそのままに、VM上で稼働しているサービスを全てコンテナに置き換えることにしました。


  1. VMwareが公開している互換性リスト、及びRAIDカードのドライバの対応OSを確認した結果。望み薄そうだったのでダメ元でアップデートを試すことはしませんでした。 ↩︎

サーバの集約

Windows Home Server 2011とMandriva Linux 2010.2と、2台に分かれていた自宅サーバを1台に集約してみた。

以前から計画していたものの、Windows機で使用していたTVチューナカードがネックになっていた。

しかし、VMware vSphere Hypervisor 5.1での成功例がネット上にそれなりの量見かけたので、挑戦してみることにした。

ハードウェアの構成は以下の通り

CPUAMD Opteron 3280
MemoryDDR3-1600 16GB
MotherBoardASUS M5A99X EVO
HDD2TB(Vmware) + 12TB(Data)

以前使用していたハードウェアでは、ハードウェア仮想化に必要となるIOMMUに対応していないため、新しいハードウェアを調達した。

実はCPUを使い回すことは可能なのだが、8コアというスペックと、マザーボードとのセット販売で格安だったため、丸ごと入れ替えている。

ハイパーバイザ上にWindows Home Server 2011とopenSUSE 12.2(Mandriva Linuxから乗り換え)を導入し、環境の移行を行い1ヶ月以上経過したが、おおよそ問題なく稼働している。

ちなみに、Radeon HD 5450を仮想化しゲストOSに割り当ててみたが、設定次第ではハイパーバイザを巻き込んでクラッシュしたり、性能的なメリットが薄かったりと、使い道がなかったためRadeonの仮想化はしないで運用している。

副作用として、Microsoft Technet Subscriptionで提供されているプロダクトのテストにちょうど良い環境が手に入ったので、時間があったときにでも普段触れる機会のないWindows Serverなどを使用してみようと思う。