EmDashは複数のデータベースバックエンドをサポートしています。デプロイ先に応じて選択してください。
概要
| データベース | 最適な用途 | デプロイ先 |
|---|---|---|
| D1 | Cloudflare Workers | エッジ、グローバル分散 |
| Hyperdrive | Cloudflare Workers上のPostgreSQL | エッジ、既存のPostgres |
| PostgreSQL | Node.js本番環境 | Postgresが使えるあらゆるプラットフォーム |
| libSQL | リモートデータベース | エッジまたはNode.js |
| SQLite | Node.js、ローカル開発 | 単一サーバー |
Cloudflare D1
D1はCloudflareのサーバーレスSQLiteデータベースです。Cloudflare Workersにデプロイする場合に使用します。
import { d1 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({ binding: "DB" }),
}),
],
});
設定
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
binding | string | — | wrangler.jsoncのD1バインディング名 |
session | string | "disabled" | 読み取りレプリケーションモード(下記参照) |
bookmarkCookie | string | "__em_d1_bookmark" | セッションブックマーク用Cookie名 |
セットアップ
wrangler.jsonc
{
"d1_databases": [
{
"binding": "DB",
"database_name": "emdash-db"
}
]
} wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "emdash-db" リードレプリカ
D1はグローバルに分散されたサイトの読み取りレイテンシーを下げるために読み取りレプリケーションをサポートしています。有効にすると、読み取りクエリは常にプライマリデータベースを照会するのではなく、近くのレプリカにルーティングされます。
EmDashはD1 Sessions APIを使用してこれを透過的に管理します。sessionオプションで有効にします:
import { d1 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({
binding: "DB",
session: "auto",
}),
}),
],
});
セッションモード
| モード | 動作 |
|---|---|
"disabled" | セッションなし。すべてのクエリはプライマリへ。デフォルト。 |
"auto" | 匿名リクエストは最寄りのレプリカから読み取り。認証済みユーザーはブックマークCookieによるread-your-writes一貫性を取得。 |
"primary-first" | "auto"と同様だが、最初のクエリは常にプライマリへ。書き込みが非常に頻繁なサイト向け。 |
仕組み
- 匿名訪問者は
first-unconstrainedを取得 — 最低レイテンシーのために最寄りのレプリカから読み取り。匿名ユーザーは書き込みを行わないため、一貫性保証は不要。 - 認証済みユーザー(エディター、著者)はブックマークベースのセッションを取得。書き込み後、ブックマークCookieが次のリクエストが少なくともその状態を見ることを保証。
- 書き込みリクエスト(
POST、PUT、DELETE)は常にプライマリデータベースから開始。 - ビルド時クエリ(Astroコンテンツコレクション)はセッションを完全にバイパスし、直接プライマリを使用。
libSQL
libSQLはリモート接続をサポートするSQLiteのフォークです。Cloudflare D1なしでリモートデータベースが必要な場合に使用します。
import { libsql } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: libsql({
url: process.env.LIBSQL_DATABASE_URL,
authToken: process.env.LIBSQL_AUTH_TOKEN,
}),
}),
],
});
設定
| オプション | 型 | 説明 |
|---|---|---|
url | string | データベースURL(libsql://...またはfile:...) |
authToken | string | リモートデータベースの認証トークン(ローカルではオプション) |
ローカル開発
開発中はローカルのlibSQLファイルを使用:
database: libsql({ url: "file:./data.db" });
PostgreSQL
PostgreSQLは完全なリレーショナルデータベースが必要なNode.jsデプロイメントでサポートされています。
import { postgres } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: postgres({
connectionString: process.env.DATABASE_URL,
}),
}),
],
});
設定
接続文字列または個別パラメータで接続できます:
// 接続文字列
database: postgres({
connectionString: "postgres://user:password@localhost:5432/emdash",
});
// 個別パラメータ
database: postgres({
host: "localhost",
port: 5432,
database: "emdash",
user: "emdash",
password: process.env.DB_PASSWORD,
ssl: true,
});
| オプション | 型 | 説明 |
|---|---|---|
connectionString | string | PostgreSQL接続URL |
host | string | データベースホスト |
port | number | データベースポート |
database | string | データベース名 |
user | string | データベースユーザー |
password | string | データベースパスワード |
ssl | boolean | SSLを有効化 |
pool.min | number | プール最小接続数(デフォルト0) |
pool.max | number | プール最大接続数(デフォルト10) |
コネクションプーリング
アダプターは内部的にpg.Poolを使用します。デプロイメントに応じてプールサイズを調整してください:
database: postgres({
connectionString: process.env.DATABASE_URL,
pool: { min: 2, max: 20 },
});
Hyperdrive
hyperdrive()アダプターを使用して、既存のPostgreSQL — またはPostgres互換(例:PlanetScale Postgres)— データベースでCloudflare Workers上のEmDashを実行します。HyperdriveはCloudflareネットワーク経由で接続をプールし高速化します。EmDashのPostgreSQLダイアレクトがクエリを実行します。
import { hyperdrive, r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: hyperdrive({ binding: "HYPERDRIVE" }),
storage: r2({ binding: "MEDIA" }),
}),
],
});
要件
- サイトに
pg >= 8.16.3がインストールされていること(pnpm add pg) compatibility_flags: ["nodejs_compat"]compatibility_date >= "2024-09-23"
セットアップ
Hyperdrive設定を作成し、Wrangler設定にバインディングを追加します:
wrangler hyperdrive create emdash-db \
--connection-string "postgres://user:password@host/db?sslmode=verify-full" \
--caching-disabled
wrangler.jsonc
{
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "<your-hyperdrive-id>"
}
]
} wrangler.toml
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<your-hyperdrive-id>" 設定
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
binding | string | "HYPERDRIVE" | プライマリ(キャッシュ無効)Hyperdriveバインディング |
cachedBinding | string | — | 匿名読み取り用のキャッシュ有効オプショナルバインディング |
max | number | 5 | Hyperdriveへのインワーカーコネクションプールの最大サイズ |
匿名読み取りをキャッシュから提供する
デフォルトでは、管理画面と書き込みがread-after-write一貫性を必要とするため、Hyperdriveキャッシュを完全に無効にします。しかし匿名パブリック読み取り — セッションなし、書き込みなし — は短い古いデータのウィンドウを許容できます。このトレードオフが許容できる場合、同じデータベース上で2つのHyperdrive設定を実行します:1つはキャッシュ無効(プライマリbinding)、もう1つはキャッシュ有効(cachedBinding)。EmDashは匿名読み取りリクエストをキャッシュ有効バインディング経由でルーティングし、すべての認証済みリクエストと書き込みはキャッシュなしのプライマリに留まり、read-after-write一貫性を維持します。
# プライマリ — キャッシュ無効(管理、認証リクエスト、書き込み、マイグレーション用)
wrangler hyperdrive create emdash-db \
--connection-string "postgres://user:password@host/db?sslmode=verify-full" \
--caching-disabled
# キャッシュ有効 — 同じ接続文字列、キャッシュ有効(匿名読み取り専用)
wrangler hyperdrive create emdash-db-cached \
--connection-string "postgres://user:password@host/db?sslmode=verify-full"
{
"hyperdrive": [
{ "binding": "HYPERDRIVE", "id": "<caching-disabled-id>" },
{ "binding": "HYPERDRIVE_CACHED", "id": "<caching-enabled-id>" }
]
}
database: hyperdrive({ binding: "HYPERDRIVE", cachedBinding: "HYPERDRIVE_CACHED" });
これはCloudflareがキャッシュ用にドキュメント化している2構成パターンです。EmDashはリクエストごとにどのバインディングを使用するか判断します:
- パブリックサイトパスの匿名読み取り(
GET/HEAD、セッションなし、/_emdash配下でない)→ キャッシュ有効cachedBinding。 - 認証済みリクエスト(エディター、著者)→ キャッシュなし
binding。 - 書き込み(
POST、PUT、DELETE、匿名含む)→ キャッシュなしbinding。 /_emdash配下のすべてのリクエスト(管理、セットアップ、認証、内部API)、匿名GETも含む → キャッシュなしbinding。- マイグレーションとコールドスタート → 常にプライマリ
binding。
SQLite
better-sqlite3によるSQLiteは、Node.jsデプロイメントの最もシンプルなオプションです。
import { sqlite } from "emdash/db";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: "file:./data.db" }),
}),
],
});
設定
| オプション | 型 | 説明 |
|---|---|---|
url | string | file:プレフィックス付きファイルパス |
ファイルパス
urlはfile:で始まる必要があります:
// 相対パス
database: sqlite({ url: "file:./data/emdash.db" });
// 絶対パス
database: sqlite({ url: "file:/var/data/emdash.db" });
// 環境変数から
database: sqlite({ url: `file:${process.env.DATABASE_PATH}` });
マイグレーション
EmDashはサポートされるすべてのダイアレクト(D1、SQLite、libSQL、PostgreSQL)で最初のリクエスト時にマイグレーションを自動実行します。マイグレーションはemdashパッケージにバンドルされ、ビルドに埋め込まれます。
データベースが空(コレクションなし)でセットアップウィザードが完了していない場合、EmDashは初回起動時にシードファイルも適用します。シードは.emdash/seed.json、package.json#emdash.seedのパス、またはseed/seed.jsonから読み取られます — 最初に見つかったもの — そしてコンパイル時にビルドに組み込まれます。いずれも存在しない場合、組み込みのデフォルトシードが使用されます。既存のデータベースに対する以降の起動はそのコンテンツを変更しません。
環境ベースの設定
環境ごとに異なるデータベースを使用:
import { sqlite, libsql, postgres } from "emdash/db";
import { d1 } from "@emdash-cms/cloudflare";
const database = import.meta.env.PROD ? d1({ binding: "DB" }) : sqlite({ url: "file:./data.db" });
export default defineConfig({
integrations: [emdash({ database })],
});
ビルドモードではなく環境変数に基づいて選択することもできます:
const database = process.env.DATABASE_URL
? postgres({ connectionString: process.env.DATABASE_URL })
: sqlite({ url: "file:./data.db" });