Ghost on Kubernetes
このWebページが動いている裏側を紹介

概要
ブログをはじめてみたので,使っているアプリケーションやシステム構成について紹介します.
サーバの構築やデプロイ方法などは今回記載しないのであしからず...
選ばれたのは Ghost でした。
配信する手段はいくつか考えられますが,デザインセンスに欠けるので便利なツールに頼ります.
The best open source blog & newsletter platform
Ghostは公式サイトにあるとおり,オープンソースのWebページ配信プラットフォームです.

CMS (=Contents Management System)である"WordPress"と同じと捉えれば分かりやすいかもしれません.
できること
- テンプレートを使ったデザインのカスタム
- 投稿管理
- 記事の公開スケジュール設定
- ブラウザ上での編集
- タグの管理
WordPressのようなプラグインの概念はなく,機能は非常にシンプルです.
↓ページ全体に関する設定画面."記事公開"という目的を満たすうえでは必要十分.


↓エディター画面.全体的にモダンなデザインで気に入ってます.

Markdown形式で,コードスニペットやメディアまわりも貼れます.
選定理由
- かぶりたくない
- OSS かつ セルフホストできる
- 管理画面含め,モダンなデザインが好き
- あえてあまり使われてなさそうなものを使ってみるほうがおもしろそう
「みんなと被りたくない」といういかにも被りそうな発想からGhostを選んでみました.Ghostに関しての日本語記事はWordPressと比較して圧倒的に少ないです.
システム構成
全体図

概要
Kuberentes上で動かしています.特別なことをしているわけではなく,ごく一般的な構成だと思います.
MySQLはPersistent Volumeをbindして永続化していますが,自家製k8sクラスタなこともあり,ストレージまわりは心配なのでMySQLはバックアップがないと夜しか眠れません.後述.
Oracle Cloud上にある複数のLinux VMを使ってkubeadmで構築しています.k8sクラスタに関しては別記事でまた書きます.
補足
nginxプロキシ
一部,特定のパスで静的ファイルを配信したいケースがあり,それを実現するためnginxを使っています.
通常のパスへはnginxコンテナからghostコンテナへプロキシします.
特定のパスでは静的ファイルを配信します.具体的には,Google AdSenseでのサイトの所有確認のためのタグ配信です.
WordPressであればプラグインでほぼ自動的にAdSenseへのリンクができるようですが,Ghostは対応していません.(2024/11現在.自分が知るかぎり.)
Ghostはヘッダに"Code injection" ができるので試しましたが,うまく認識されなかったので断念.今回のような構成を取りました.

exporterを利用したモニタリング
Pod内は先述したnginxとghostに加えて,"nginx-exporter"コンテナの3つで構成しています.
Kubernetes上にはGrafanaとPrometheusによる監視基盤があるため,これらを使ったメトリクスが収集できるようになっています.
簡単な流れは以下のとおりです.
- nginxの8080番ポートでコネクションなどの情報を出力するように設定.詳細はngx_http_stub_status_moduleをご参照ください.
- nginx-prometheus-exporterコンテナからnginxコンテナに対して取得,さらにPrometheusで収集できる形にしてメトリクスをはき出す.
- KuberentesのService Discoveryを使ってメトリクスを収集
Grafana上では以下のように見えます.もうすこしコネクション数が増えるとうれしい.

Dashboardはofficialで出ているテンプレートを利用しています.
MySQLのバックアップ/リストア
SQLファイル出力による方法で暫定対処しています.
backup
kubectl -n [namespace] exec -it sts/mysql -c mysql -- mysqldump -u [rootユーザ] -p[パスワード] [テーブル名] > ghost_bak.sql
restore
kubectl -n [namespace] exec -it sts/mysql -c mysql -- mysql -u [rootユーザ] -p[パスワード] [テーブル名] < ghost_bak.sql
自動化できておらず,職人による温もりのある手作業です.最悪です.改善の余地しかありません.
Kubernetes上なのか,別のサーバからなのか,はたまた別のところからなのか,Cronかなにかで定期実行しておくのがよさそうです.本対応したらまた記事書きます.
EOP