TPDN Blog
2020-11-23

このサイト(TPDN Blog)の実装 2020年版

2020年11月現在のblog.tpdn.kimブログの実装概要

KEY POINTS
  • いわゆるJamstackベースの現代的な構成を採用し、GitLabを用いてコード管理とCI/CDを行っている
  • 現代的な構成を採用しているが、公開に使っているサーバーは安価に入手できて管理が容易なApacheベースのWebホスティングを使っている
  • 可搬性と自由を求めて極力自前所有にこだわりつつ、楽できる部分は楽している

見た目はほとんど変わっていないが、中身のアーキテクチャを一新したので一度まとめてみることにした。

あくまでも概要なので、すべての詳細を書いているわけではない。

古いブログは何を使用して作られていたか

このブログはもともとLektorというPythonベースのSSGで構成されていた。Gitで記事を管理する、典型的な構成をとっていた。

しかし以下の問題・不安があったのでNode.jsベースのSSGへ移行を決断した

  • 見る感じLektorプロジェクトの方向性が定まっておらず、将来性に不安を感じる
    • これはコードを提供したら治るという性質のものではない
  • Lektorで作ってるといいつつもデプロイフローから何から派手に改造しまくっていた
    • Lektor特有の実装への依存度が低かった
  • 改造時にJavaScript(Node.js)による拡張を多用しており、そもそもPythonへの依存度も低かった
    • じゃあなんでLektorなんて採用したんだよと自己ツッコミしたくなる
  • Lektorは簡易GUI付きのSSGだが、一体構成になっている点が時流から外れていた
    • GUI欲しいならHeadless CMSとSSGを組み合わせるのが今の主流だと思う

コンセプト

なるべく自前で所有する

とにかく他のサービスを使うのが嫌だった。既存のブログサービスだけでなく、NetlifyとかGithub Pagesすら使いたくなかった。

価値観と価値観がぶつかり合ってテコンダー朴のネタが現実になるような現代は、些細な発言が問題になる。DPRKな私(????)としては、どうでもいい発言を不用意に行ったせいでBANされるのは避けたい。

そのような事態を避けたいなら、自前で所有するしか無いという判断である。 自前でやってればフルバックアップが簡単に取れるし、間違いなく書いた記事は自分のものである。

IndieAuthやWebmention導入までやりきってIndieWebの方向に向かうのも面白いかもしれない。(この記事を書いている時点では未実装)

ソーシャルメディア経由のアクセスを重視する

しばらくこのブログを運営した感じ(特にバズった某記事へのアクセスを見る感じ)「もはやGoogleで検索して個人ブログを見に来る人はまずいないのでは?」という感想を持った。

今時のウェブサイトはまず何らかのソーシャルメディアで共有される前提で以下を意識するべきではないだろうかと思っている。

  • metaタグやJSON-LDを充実させる
    • 見やすく綺麗なプレビュー表示に貢献する
  • ソーシャルメディアのクローラーからアクセスされる前提で書きだす
    • クローラーが見やすいデータを吐く
    • 検索エンジンのクローラーをブロックする場合でも、Twitterとかのクローラーは通す

移行はなるべく楽に

前述のとおり、このブログは新規作成ではなく移行である。 特にテンプレート系はそのまま転用したいし、各種データもコピペで済ませたい。 Jinja2と互換性のあるテンプレート言語が使えると理想。

バックエンド

典型的なJamstackを採用し、以下の手順をCI/CD環境で自動実行している

  1. Headless CMSからデータを読み込む
  2. Static Stie Generatorで静的ページを生成する
  3. サーバーにデプロイ

ただし・・・

  • Headless CMSはSaaSを借りるのではなく自前運用
  • デプロイ先はS3みたいな高級品ではなく、Apacheベースの格安Webホスティング

自分で所有することにこだわりたかったし、でもいろいろコスト(金銭的な物だけでなく手間も含む)を下げたかったというのもある。

使用している主要ツール

SSG: Eleventy (11ty)

https://www.11ty.dev/

EleventyというSSGを使用している。 SSG界のFlaskとでもいうべきシンプルさとカスタマイズ性を持ち、標準対応しているテンプレート形式が多いことからこれを選んでいる。 GraphQLからデータを取得してHTMLに書き出すなんてのも自分で実装すれば可能だし、実際このブログはそうしている。

特にNunjucksに標準対応しているのは大きい。Jinja2で書かれたテンプレートをほとんどコピペで移行することができるので移行が極めて楽だった。(このブログは完全新規製作ではなく、LektorというPython製SSGで書かれた旧ブログから丸ごと移行している)

当然ながらNuxtのような汎用フレームワークほどの自由度は無い。

ちなみに、11tyの拡張にはJavaScriptではなくTypeScriptを使用している。 GraphQLを扱う際に型があると大変都合がよいのでこのようにしている。

Headless CMS: Directus

https://directus.io/

DirectusはPHP製のHeadless CMSで、RDBMSをバックエンドにしている。 そのため典型的なLAMP構成のサーバーで非常にローコストに自前運用できる。要はWordPressが動くと書かれている鯖なら大体どこでも動くと考えてよい。

これを使えば見てのとおり一発でモダンなGUIが手に入り、Gitで文書を管理する前時代的な仕組みとおさらばできる。

今時のHeadless CMSのほとんどはJavascript(Node.js)で動くものばかり、バックエンドにも普通のRDBMSではない何かを使っていたりするものが多い。廉価なサーバーでサクッと動かせるものは多くない。しかしDirectusはただのPHP+MySQLなので激安鯖で普通に動作するのだ。

database-first platformをうたっており、良くも悪くもRDBMSに何でもかんでも突っ込みやがる。(見る感じ変更ログ系データとかもRDBMSに堂々と入れてくるしデータベースへの負荷はそれなりにありそう)

そのためアセットを除くフルバックアップがmysqldump一発で終了するし、バックアップからの復旧も一発で終わる。

実装を見れば見るほどツッコミどころはあるが、Netlifyとか借りずに自前でやりたいなら選択肢の1つとしては間違いなくアリだろう。ただ実際使ってみた感じ、本格運用はかわいらしい見た目に反して楽ではないだろうなという気がする。

Uploader: TinyFileManager改

https://tinyfilemanager.github.io/

Directusにもファイルマネージャーはあるが、もっと単純なものが欲しかったので簡単なファイルマネージャーを別途採用している。 ブログで使用する画像置き場として使っている。

CDNのCloudFlareと連携するために改造を加えている。コードベースが極小で見通しが良いので改造は超簡単。

Webホスティング

Coreserverというサービスを使用している。 10年以上前からある、xreaの有料版的な立ち位置のあのコアサーバーである。

ApacheベースのWebホスティングサービスで、WordPressの設置によく使用されている。いわゆるLAMP環境を提供してくれるサービスである。 ブログのデプロイ場所、Headless CMSの設置場所、Uploaderの設置場所になっている。

現代のリッチなサービスに慣れていると「本当にこんなのでいいのか?」と思うかもしれないが、これでいいのだ。 このブログは静的ファイルなのでcurlやwgetなどでartifacts落としてシンボリックリンク張り替えるだけでデプロイ完了。ファイルを置く場所さえあればどこにだってデプロイできる。

特徴

  • 容量単価が最安級
  • (当然ながら限度はあるけど)制限が緩い
  • 生ログをもらえる
  • (どこまできっちりと更新やってくれてるかは不明だが)お手軽に Let's Encrypt対応ができる
  • サーバーの物理設置場所が日本である
    • これは地味に重要なポイント
    • 激安鯖だと日本企業鯖でも物理場所が海外だったりというのは普通にある

もちろんサポートが薄いとかサーバー機材が微妙に古いとか、いろんな欠点はあるが、そんなものはわかってるし昔からそうなので全く気にしていない。

CDN

アップローダーで管理されているものだけはCloudFlareを通している。

要は画像とかのファイルサイズが大きく転送量がかさむものだけCDN経由にして、それ以外は普通にCoreserverから返している。

ソースコード管理&CI/CD

GitLab.comを使用している。 CI/CDにGitLab CIをぜひとも使用したいという強い動機があったため、GitLab以外の候補は一切考えていなかった。

このブログは「使用している主要ツール」で書いた通り、複数のコンポーネントから成り立っている。複数のバラバラのリポジトリになっているとコンポーネントをまたぐ変更がめんどくさい。なので全部を1つのリポジトリに放り込んでいる。いわゆるmonorepo的なアプローチをとっている。

GitLab CIでやってることは単純で

  • kanikoでDockerFileからイメージ作成
  • dockerイメージを使ってpackage.jsonに定義されたビルドタスクを実行

…くらいである。

フロントエンド

11tyには出来合いのフロントエンドはない(Lektorもだが)ので、基本的には全自作するしかない。(一応ブログの参考実装はある)

SPAとかの小細工はせず、無難に普通のHTMLを吐いている。

フロントエンドには正直言って力を入れていない。とはいえ遅くなるのは嫌いなので、データサイズがなるべく小さくなるよういろいろやってるつもりではある。

画像や文章の多いコンテンツでもパフォーマンスだけはまあまあ良好。

デザイン

私の本業はフロントエンド系エンジニアではないが、大まかなレイアウトは自力で作っている。 迷ったときにはどこかのサイト(主に海外系のニュースサイト)を真似するという力技で解決している。

また全部をフルスクラッチで作りきるだけの技術と時間を確保するのはなかなか面倒であるので、フレームワークの力を活用している。

CSSフレームワーク

CSSフレームワークとしてFoundation6を使用している。

Foundation6は必要なコンポーネントのみをSCSSで組み込むことができる。なのでSCSS版を使用して必要なコンポーネントのみ、sass(dart-sass)を使用してビルドしている。

正直今時のリッチでイケイケなUIを組むには物足りない気がする。 でも実用的な物がそろっている(実際管理画面向けのお堅めUI作るときに使いやすい)し、何よりBootstrap臭がしないという最大級のメリットがある。

hatena