EmDashの紹介とブログ構築

EmDashとは

WordPressの使用感をAstroで実現したCMSらしい

README にも、

EmDash is what WordPress would look like if you started from scratch with today's tools.

とあり、
WordPressのPHPとJSを並行して管理するのが大変、まともなパフォーマンス出すためにはキャッシュを何層も重ねないといけない、セキュリティがしんどいといった問題点を解決していると書いてある。

WordPressのセキュリティ脆弱性のほぼ全てがプラグイン由来ということで、プラグインをサンドボックス実行できるようにするようにすることで安全性を担保しているということが強調されてるけどそれは今回やらない。お金がかかるので。

EmDashを使ったブログ構築

(ブログを作り直して記事を移行とかしてなければ)このブログはEmDashで構築されている。以下は構築した時の作業メモ。

0 前提

  • 開発環境
    • Node.js 24.16.0(要求は22+)
  • デプロイ先はCloudflareの無料で使える範囲
    • Workers(実行環境)
    • D1(DB)
    • D2(メディア保存)
    • プラグインのサンドボックス実行に使うWorker Loadersは有料専用なので使わない。ので公式プラグインとか使えない
    • クレカの登録とR2の有効化が必要

1 プロジェクト作成

npm create emdash@latest geny7i-com

テンプレートはBlogを選択

プロジェクト名は geny7i-com で進めるので適宜読み替えて

2 Cloudflareリソース作成

npx wrangler login                        # ブラウザで Cloudflare 認証
npx wrangler d1 create geny7i-com            # 出力される database_id を控える
npx wrangler r2 bucket create geny7i-com-media

R2有効化されていないとここで怒られるのでダッシュボードから有効化する

wrangler.jsoncを自動で書き換えるか聞かれるがNOにしておく(どっちでもいいけどすでにemdash用の雛形が作られているので)

3 wrangler.jsonc設定

{
	"$schema": "node_modules/wrangler/config-schema.json",
	"name": "geny7i-com",  // ← ワーカー名を指定
	"main": "./src/worker.ts",
	// 略
	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "geny7i-com",  // ← 手順2で作った DB 名
			"database_id": "xxxxxxxx-...",  // ← d1 create の出力を貼る
		},
	],
	"r2_buckets": [
		{
			"binding": "MEDIA",
			"bucket_name": "geny7i-com-media",  // ← 手順2で作ったバケット名
		},
	],
	// 前提に書いたようにWorker Loadersは有料なので使わない。コメントアウトしておく
	// "worker_loaders": [
	// 	{ "binding": "LOADER" },
	// ],
	// 
	
	// 略
}

シークレットの設定がワーカー名に紐づくのでこの時点で忘れずに設定しておく

ワーカーはシークレットの設定かデプロイ時に作成されるのでこの時点では無くて問題ない

4 astro.config.mjs設定

import cloudflare from "@astrojs/cloudflare";
import react from "@astrojs/react";
// 不要なimportをもろもろ剥がす
import { d1, r2 } from "@emdash-cms/cloudflare";   // ← "sandbox" を import から外す
import { formsPlugin } from "@emdash-cms/plugin-forms";
// import webhookNotifier from "@emdash-cms/plugin-webhook-notifier";  
import { defineConfig, fontProviders } from "astro/config";
import emdash from "emdash/astro";

export default defineConfig({
   // 略
	integrations: [
		react(),
		emdash({
			database: d1({ binding: "DB", session: "auto" }),
			storage: r2({ binding: "MEDIA" }),
			plugins: [formsPlugin()],
			// sandboxed: [webhookNotifier],   // ← 削除
			// sandboxRunner: sandbox(),       // ← 削除
			// marketplace: "https://marketplace.emdashcms.com",  // ← 削除
		}),
	],
	// 略
});

astro.config.mjsからサンドボックス関連の設定を剥がす

5 シークレットを設定

暗号化キーを設定

npx emdash secrets generate                    # 暗号鍵を生成(出力値をコピー)
npx wrangler secret put EMDASH_ENCRYPTION_KEY  # 上でコピーした値を貼る

サイトURLを設定

npx wrangler secret put EMDASH_SITE_URL

設定時よくわかっていなかったのでworkerのデフォルト(https://geny7i-com.<account>.workers.dev)を設定していたが、
EMDASH_SITE_URLとデプロイ先のURLが違くてもデプロイされていることの確認はできると思うので初めから自前のドメインにしても大丈夫なはず

6 デプロイ

npm run deploy

この時点で、デフォルトのURL(https://geny7i-com.<account>.workers.dev)でサイトにアクセスできるようになる

管理者のログイン方法がパスキーの関係で管理者アカウント作成後にドメイン変更すると面倒なことになると思うので、自前のドメインにするならこの時点で紐付けてEMDASH_SITE_URLも合わせておく

7 管理者アカウント作成

https://<公開URL>/_emdash/admin にアクセスすると画像みたいなウィザードが開くので設定、設定が終わると管理者アカウントの有効化とデフォルトの記事の作成がされる

スクリーンショット 2026-06-28 20.20.23.png

デフォリト記事は一旦作ってから削除したがseed/seed.jsonのシードをもとに作成されるので気になるなら事前に消すといいかも

No comments yet