本ブログの技術的仕組み
本ブログでは、NotionをCMSとして使い、Astroで静的なサイトを生成し、Cloudflareから配信しています。この記事では、なぜこの構成を選んだのか、記事を書いてから公開されるまでに何が起きているのかを紹介します。
ブログに求めたこと
構成を考えるにあたり、次の3点を要件としました。
- 運用費を月額100円以内に抑える
- iPhoneのNotionだけで、記事の執筆から公開まで完結できる
- ブログに広告を表示しない この中で特に重視したのが、執筆と公開の手軽さです。PCを開かなくても、思いついたときにスマートフォンで書き、そのまま公開できる環境を目指しました。
NotionをCMSにした理由
わたしは普段からNotionを使っており、PCでもスマートフォンでも快適に操作できる点を気に入っています。文章の書式を整えたり、画像を貼り付けたりする操作も簡単です。 新しい執筆ツールを用意するより、使い慣れたNotionをそのままCMSにするほうが、書くことに集中できます。そこで、Notionを記事と原画像の正本として扱い、そこからブログを生成する構成にしました。 既存のブログサービスでは、最後までnoteの利用も検討しました。しかし、モバイルでの執筆体験はNotionのほうが自分に合っていたこと、ブログに広告を出したくなかったことから、今回は自前でサイトを構築することにしました。 将来、より広く読まれてほしいと思えるまとまった論考が生まれたときには、noteへの投稿も検討するつもりです。
全体のアーキテクチャ
Notionで管理している記事をAstroで静的なHTMLに変換し、Cloudflare Workers Static Assetsから配信しています。ソースコードはGitHubで管理し、ビルド、ホスティング、画像配信、DNSまでCloudflareに集約しました。 全体像は次のとおりです。
flowchart LR
NOTION["Notion<br/>記事・原画像の正本"]
GITHUB["GitHub<br/>Astroコード"]
subgraph CF["Cloudflare"]
direction LR
BUILD["Workers Builds<br/>Astro + Content Layer + Sätteri"]
MANIFEST["R2 private<br/>記事manifest"]
MEDIA["R2 public<br/>WebP画像master<br/>media.aquord.me"]
STATIC["Workers Static Assets<br/>blog.aquord.me"]
IMAGES["Image Transformations<br/>mobile 960px"]
end
BROWSER["閲覧者のブラウザ"]
NOTION -->|"Deploy Hook / コンテンツ"| BUILD
GITHUB -->|"main"| BUILD
MANIFEST -->|"再利用"| BUILD
BUILD -->|"更新"| MANIFEST
BUILD -->|"画像を正規化"| MEDIA
BUILD -->|"静的サイトをdeploy"| STATIC
STATIC -->|"HTML / CSS / JS"| BROWSER
MEDIA -->|"desktop / zoom"| BROWSER
MEDIA -->|"変換元"| IMAGES
IMAGES -->|"mobile"| BROWSER記事が公開されるまで
日常的な操作はNotionの中だけで完結します。
- Notionで記事を書き、画像や必要なプロパティを設定します。
- 記事のステータスを「下書き」から「公開」に変更します。
- Deploy Hookを通じてCloudflareのビルドが開始されます。
- AstroがNotionからコンテンツを取得し、静的なサイトを生成します。
- 生成されたサイトがWorkers Static Assetsへデプロイされ、ブログが更新されます。 つまり、公開時にコードを操作したり、PCから手動でデプロイしたりする必要はありません。iPhoneのNotionでステータスを変更するだけで、公開まで進むようにしています。
画像の配信
Notionに貼り付けた画像は、ビルド時にWebP形式へ正規化してCloudflare R2へ保存します。閲覧時にはR2上の画像をそのまま配信するほか、モバイル向けにはCloudflare Image Transformationsでリサイズした画像を配信します。 これにより、Notionを画像の管理場所として使いながら、ブログ上では端末に合ったサイズの画像をCDN経由で届けられます。
Cloudflareを選んだ理由
基盤にはFirebaseも検討しました。ただし、このブログではログイン機能やデータベースを利用しないため、Firebaseの主要な機能を十分には活用できません。 一方、Cloudflareには、静的サイトのビルドと配信、R2による画像保存、Image Transformationsによる画像最適化、DNSとドメイン管理など、今回必要な機能がそろっています。ドメインを安価に管理できることも含め、ブログ全体を一つのサービス群へ集約できる点が決め手になりました。
まとめ
この構成によって、使い慣れたNotionで記事を書き、ステータスを「公開」に変えるだけでブログを更新できるようになりました。