EmDash CMS Cloudflare 無料枠本番運用プレイブック
明確な機能境界と実践的なロールバック指針のもと、Cloudflare の Free プランで EmDash を信頼できる形でデプロイします。
エグゼクティブサマリー
コア CMS のワークフローなら、Cloudflare の Free プラン上で EmDash を本番運用できます。
受け入れる必要があること: サンドボックス化されたプラグイン実行は利用できないため、設定から worker_loaders を削除する必要があります。
このガイドは、機能の最大展開より安定性を優先する前提で書いています。
Free プランでの能力の境界
利用可能
- EmDash のコアサイトと管理フロー
- D1 をバックエンドとしたコンテンツデータ
- R2 をバックエンドとしたメディアストレージ(無料枠内)
- Workers のデプロイとルーティング
利用不可
- サンドボックス化プラグイン用の Dynamic Workers
- マーケットプレイス型の信頼できない第三者ランタイム実行
サンドボックス化された第三者プラグイン実行が公開の前提なら、Free プランでは不十分です。
デプロイ前チェックリスト
デプロイコマンドを実行する前に、次をすべて完了してください。
- Wrangler が認証済み(
wrangler login済み) - プロジェクトがクラウド専用の前提なしにローカルでビルドできる
wrangler.jsoncの D1 と R2 のバインディングがランタイム設定と一致している- Free プラン用に
worker_loadersエントリが削除されている - パッケージマネージャの選択が一貫している(
npmまたはpnpm、混在しない)
リソースのプロビジョニング順序
バインディングの揺り戻しを減らすため、この順序どおりにプロビジョニングします。
- D1 データベースを作成する
- R2 を有効化または作成し、バケットを作成する
- 正確な名前と ID で
wrangler.jsoncを更新する - Worker をビルドしてデプロイする
理由: D1 の ID とバケット名が、環境バインディングのソース・オブ・トゥルースになります。
# まず D1 をプロビジョニング
npx wrangler d1 create your-db-name
# 続けて R2 バケットをプロビジョニング
npx wrangler r2 bucket create your-media-bucket
Free プラン向け最小限の wrangler.jsonc の形
次のスケルトンは意図的に小さくしています。
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "your-site-name",
"main": "./src/worker.ts",
"compatibility_date": "2026-04-08",
"compatibility_flags": ["nodejs_compat"],
"d1_databases": [
{
"binding": "DB",
"database_name": "your-db-name",
"database_id": "replace-with-d1-id"
}
],
"r2_buckets": [
{
"binding": "MEDIA",
"bucket_name": "your-media-bucket"
}
]
}
Free プランでは worker_loaders セクションはありません。
ビルドとデプロイの流れ
EmDash プロジェクトのルートからコマンドを実行します。
# パッケージマネージャは一つに決めて守る
npm run build
npm run deploy
プロジェクトが pnpm ベースの場合:
pnpm build
pnpm deploy
ロックファイルを意図的に同期していない限り、同一デプロイセッションで npm と pnpm を混在させないでください。
デプロイ後の検証チェックリスト
次の順で検証します。
- フロントエンドの URL が解決し、期待どおりのコンテンツが返る
- 管理 URL(
/_emdash/admin)に到達できる - 初回の管理セットアップが正常に完了する
- テスト用のアイテムを一つ作成して公開する
- メディアファイルを一つアップロードし、取得できることを確認する
ルートに届くだけでなく、データ書き込み経路まで検証するまでデプロイは完了ではありません。
高頻度の失敗モードと最短の修正
失敗: デプロイは成功するが管理の初期化に失敗する
想定原因: ランタイム連携と wrangler.jsonc のバインディング不一致。
修正の流れ:
- バインディング名(
DB、MEDIA)がどこでも同一か確認する - 設定修正後に再デプロイする
- 管理の初期化を再試行する
失敗: R2 コマンドがアカウントのプロンプトでブロックされる
想定原因: ダッシュボードでまだ R2 が有効になっていない。
修正の流れ:
- Cloudflare ダッシュボードで R2 を有効にする
- 課金条項に同意する(無料枠はそのまま適用される)
- バケット作成コマンドをやり直す
失敗: Free プランでプラグイン関連のランタイムエラー
想定原因: サンドボックス設定の残骸。
修正の流れ:
worker_loadersを削除する- サンドボックス専用のプラグイン設定を無効にする
- 再デプロイして再テストする
ロールバック戦略
保守的なロールバック方針を取ります。
- 最後に正常だったデプロイのコミットにタグを付けておく
- 本番で退行が出たら、タグ付けした前のコミットを再デプロイする
- トラフィックが安定するまでスキーマやプラグインの変更は延期する
運用上、インシデント中は深いホットフィックスより速いロールバックが勝ちます。
Free から有料へアップグレードするタイミング
次のいずれかが真のときだけアップグレードしてください。
- サンドボックス化された信頼できないプラグイン実行が必要
- トラフィックやストレージが無料枠を定期的に超える
- 統治上、より強いプラグインランタイムの隔離が必要
課金画面のあいまいな文言だけを理由にアップグレードしないでください。具体的な能力要件があるときだけアップグレードします。