Node.js にデプロイ

このページ

EmDash は Node.js 22.16 以降で動作します。このガイドではローカルまたは S3 互換ストレージを使用した SQLite を使用します。libSQL と PostgreSQL は Node.js で同じように動作します — データベースオプションを参照してください。

前提条件

  • Node.js v22.16.0 以上
  • Node.js ホスティングプロバイダーまたは VPS

設定

Node.js デプロイ用に EmDash を設定します:

import { defineConfig } from "astro/config";
import node from "@astrojs/node";
import emdash, { local, s3 } from "emdash/astro";
import { sqlite } from "emdash/db";

export default defineConfig({
	output: "server",
	adapter: node({ mode: "standalone" }),
	integrations: [
		emdash({
			database: sqlite({ url: "file:./data/emdash.db" }),
			storage: local({
				directory: "./data/uploads",
				baseUrl: "/_emdash/api/media/file",
			}),
		}),
	],
});

ビルドと実行

  1. プロジェクトをビルド:

    npm run build
  2. サーバーを起動:

    node ./dist/server/entry.mjs

サーバーはデフォルトで http://localhost:4321 で実行されます。マイグレーションは最初のリクエストで適用されます。データベースが空でセットアップが完了していない場合、シードファイル(ない場合は組み込みのデフォルト)もその最初のリクエストで適用されます。

スケジュールされたタスク

組み込みスケジューラは Node.js プロセスが実行中の間のみ動作します。スケジュールされた公開、プラグインタスク、一般的なメンテナンスを処理します。

本番環境では少なくとも1つの Node.js プロセスを継続的に実行してください。スケジュールされたタスクはすべてのプロセスが停止またはスリープすると一時停止します。

プラグインサンドボックス

マーケットプレイスプラグインと sandboxed: [] にリストされたプラグインにはサンドボックスランナーが必要です。Node.js では、ランナーは @emdash-cms/sandbox-workerd で、workerd 子プロセスでプラグインを実行します。プラグインサンドボックスではインストール、workerd プロセスの実行方法、障害モードについて説明しています。

本番ストレージ

本番環境では、ローカルファイルシステムの代わりに S3 互換ストレージを使用します:

import emdash, { s3 } from "emdash/astro";

export default defineConfig({
	integrations: [
		emdash({
			database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
			storage: s3({
				endpoint: process.env.S3_ENDPOINT,
				bucket: process.env.S3_BUCKET,
				accessKeyId: process.env.S3_ACCESS_KEY_ID,
				secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
				publicUrl: process.env.S3_PUBLIC_URL, // オプションの CDN URL
			}),
		}),
	],
});

Docker

ビルドコンテキストを小さく保つために .dockerignore を追加します:

node_modules
dist
.git

Dockerfile を作成します:

FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./

RUN mkdir -p data

ENV HOST=0.0.0.0
ENV PORT=4321

EXPOSE 4321
CMD ["node", "./dist/server/entry.mjs"]

シードファイルはビルド時に読み込まれバンドルにインライン化されるため、ランタイムイメージにコピーする必要はありません。マイグレーションはデプロイ後の最初のリクエストで実行されます。シードはデータベースにコレクションがなくセットアップが完了していない場合にのみ適用されます — 既存のデータは上書きされません。

イメージをビルドしてコンテナを実行します:

docker build -t my-emdash-site .
docker run -p 4321:4321 -v emdash-data:/app/data my-emdash-site

Docker Compose ファイルで名前付きボリューム付きの同じコンテナを管理します:

services:
  emdash:
    build: .
    ports:
      - "4321:4321"
    volumes:
      - emdash-data:/app/data
    restart: unless-stopped

volumes:
  emdash-data:

バックグラウンドでスタックを起動します:

docker compose up -d

環境変数

推奨:暗号化キー

EMDASH_ENCRYPTION_KEY はプラグインシークレットを保存時に暗号化するためのキーです。キーは起動時に検証されます。プラグインシークレットの暗号化は有効化後にこのキーを使用します。すべてのデプロイで設定して、後の設定変更なしにシークレットが保護されるようにしてください。

キーを生成し、結果を環境に追加します:

npx emdash secrets generate  # 結果を環境に追加

キーはあなたが提供するもので、データベースには保存されません。暗号化された暗号文のみが保存されます。耐久性のある場所(パスワードマネージャー、KMS、チームのシークレットストア)にバックアップしてください — 失うとそれで暗号化されたすべてのシークレットを失います。

オプション:安定値オーバーライド

EmDash はプレビュー HMAC シークレットとコメンター IP ハッシュソルトを自動生成し、最初の使用時にデータベースに保存します。以下の環境変数はそれらをあなたが管理する値に固定します — 別のプロセスがメインサイトとシークレットを共有する必要がある場合に便利です。

変数説明
EMDASH_PREVIEW_SECRET自動生成されたプレビュー HMAC シークレットのオーバーライド。
EMDASH_IP_SALT自動生成されたコメンター IP ハッシュソルトのオーバーライド。
EMDASH_AUTH_SECRETオプション。設定すると IP ソルトソースとして使用されます(EMDASH_IP_SALT も設定されている場合はそちらが優先)。既にそれに依存しているインストールのコメンター IP ハッシュを安定させます。新しいデプロイの場合は未設定のままにしてください。

データベースとストレージ

変数説明
DATABASE_PATHSQLite データベースのパス/data/emdash.db
HOSTサーバーホスト0.0.0.0
PORTサーバーポート4321
S3_ENDPOINTS3 エンドポイント URLhttps://xxx.r2.cloudflarestorage.com
S3_BUCKETS3 バケット名my-media-bucket
S3_ACCESS_KEY_IDS3 アクセスキーAKIA...
S3_SECRET_ACCESS_KEYS3 シークレットキー...
S3_PUBLIC_URLメディアの公開 URLhttps://cdn.example.com

永続ストレージ

SQLite には永続的なディスクストレージが必要です。ホスティングプラットフォームが以下を提供することを確認してください:

  • マウントされたボリュームまたは永続ディスク
  • データベースディレクトリへの書き込みアクセス
  • データベースファイルのバックアップメカニズム

ヘルスチェック

ロードバランサー用のヘルスチェックエンドポイントを追加します:

export const GET = () => {
  return new Response("OK", { status: 200 });
};

プラットフォームを設定して、ライブネスプローブのために /health をチェックするようにしてください。