Cloudflare PagesではなくWorkers Assetsで個人開発CMSを公開した理由 Cloudflare

Cloudflare PagesではなくWorkers Assetsで個人開発CMSを公開した理由

Cloudflare

このサイトがCloudflare Workersと静的アセット配信で公開されている構成を、wrangler.toml、ルーティング、公開前確認の実装に沿って整理します。

Cloudflare Workers Assetsで個人開発CMSを公開する構成図
このサイトでは、Worker本体とpublic配下の静的アセットを同じプロジェクトで配信しています。

最初のタイトルはCloudflare Pagesで無料サイトを公開する流れでした。ただ、このリポジトリの現在の構成を見ると、実際に公開を担っているのはCloudflare Workersです。wrangler.toml では main = "src/index.ts" が指定され、同時に [assets]./public を配信しています。この記事では、一般的なPages紹介ではなく、このサイトがなぜWorkers中心の構成になっているかを整理します。

このサイトの公開構成

公開ページ、管理画面、API、RSS、sitemap、robots.txtは、すべて src/index.ts のWorkerで処理されています。画像は public/articles/public/x-profile/ に置き、/assets/... のパスで返します。単なる静的ブログならPagesだけでも足りますが、このサイトはD1から記事を取得し、予約投稿、問い合わせ、コメント制御、アクセスログ、AdSenseモード切り替えを行うため、WorkerでHTMLを返す構成が合っています。

wrangler.tomlで見える実装

main = "src/index.ts"
routes = [
  { pattern = "sugekiji.com", custom_domain = true },
  { pattern = "www.sugekiji.com", custom_domain = true }
]

[assets]
directory = "./public"
binding = "ASSETS"

この設定により、アプリ本体はWorkerとして動き、画像などの静的ファイルはAssets binding経由で配信されます。serveStaticAsset では /assets/ から始まるURLを受け取り、実体のパスへ変換して env.ASSETS.fetch に渡しています。

Pagesだけでは足りなかった部分

記事一覧や詳細ページを静的に生成するだけならPagesで十分です。しかし、このCMSでは公開対象を statusnoindexcontent_typereview_status で切り替えます。さらに、AdSense審査中は審査対象外のURLを公開しない、RSSとsitemapには確認済み技術記事だけを出す、といった条件分岐が必要です。これらはWorkerでリクエストごとに判定した方が扱いやすい部分でした。

公開前に確認するURL

  • //articles に公開対象の記事だけが出るか
  • /sitemap.xml に下書き、noindex、審査対象外の記事が入っていないか
  • /rss.xml が技術記事だけを返すか
  • /robots.txt/admin//api/、審査中の /posts/ を避けているか
  • /assets/articles/... の画像が200で返るか

この構成は、単に無料で公開するための選択ではありません。DBを使うCMSとして、公開条件をコードで制御しながら、静的アセットも同じデプロイで扱うための構成です。関連記事としては、DB側の公開条件を扱う Cloudflare D1の記事 と、API側の実装を扱う Workersの記事 が近い内容です。

参考資料