儲存選項

本頁內容

EmDash 將上傳的媒體(圖片、文件、影片)儲存在可設定的儲存後端中。根據您的部署平台和需求進行選擇。

概述

儲存最適合特性
R2 BindingCloudflare Workers零設定,快速
S3任何平台簽名上傳,CDN 支援
Local開發環境簡單的檔案系統儲存

Cloudflare R2 (Binding)

在部署到 Cloudflare Workers 時使用 R2 繫結以獲得最快的整合。

import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";

export default defineConfig({
	integrations: [
		emdash({
			storage: r2({ binding: "MEDIA" }),
		}),
	],
});

設定

選項類型描述
bindingstring來自 wrangler.jsonc 的 R2 繫結名稱
publicUrlstring儲存桶的選用公開 URL

設置

將 R2 繫結新增到您的 Wrangler 設定中:

wrangler.jsonc

{
  "r2_buckets": [
    {
      "binding": "MEDIA",
      "bucket_name": "emdash-media"
    }
  ]
}

wrangler.toml

[[r2_buckets]]
binding = "MEDIA"
bucket_name = "emdash-media"

公開存取

對於公開媒體 URL,在您的 R2 儲存桶上啟用公開存取:

  1. 前往 Cloudflare 控制面板 > R2 > 您的儲存桶
  2. 在設定中啟用公開存取
  3. 將公開 URL 新增到您的設定中:
storage: r2({
	binding: "MEDIA",
	publicUrl: "https://pub-xxxx.r2.dev",
});

S3 相容儲存

S3 配接器適用於 Cloudflare R2(透過 S3 API)、MinIO 和其他 S3 相容服務。

以下設定將 EmDash 指向 S3 相容儲存桶:

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

export default defineConfig({
	integrations: [
		emdash({
			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,
				region: "auto", // Optional, defaults to "auto"
				publicUrl: process.env.S3_PUBLIC_URL, // Optional CDN URL
			}),
		}),
	],
});

設定

選項類型必需描述
endpointstringS3 端點 URL
bucketstring儲存桶名稱
accessKeyIdstring否*存取金鑰
secretAccessKeystring否*密鑰
regionstring區域(預設:"auto"
publicUrlstring選用的 CDN 或公開 URL

* accessKeyIdsecretAccessKey 必須一起提供,或者都省略。

從環境變數解析 S3 設定

s3({...}) 中省略的任何欄位都會在處理程序啟動時從相符的 S3_* 環境變數中讀取。這使您可以建置一次容器映像檔,並在啟動時注入憑證而無需重建。s3({...}) 中的明確值始終優先於環境變數。

環境變數欄位注意事項
S3_ENDPOINTendpoint必須是有效的 http/https URL
S3_BUCKETbucket
S3_ACCESS_KEY_IDaccessKeyId
S3_SECRET_ACCESS_KEYsecretAccessKey
S3_REGIONregion預設:"auto"
S3_PUBLIC_URLpublicUrl選用的 CDN 前綴

環境變數在處理程序啟動時從 process.env 讀取。這是僅限 Node 的功能。

不帶參數呼叫 s3() 會從 S3_* 環境變數讀取每個欄位:

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

export default defineConfig({
	integrations: [
		emdash({
			// 不帶參數的 s3():所有欄位來自 S3_* 環境變數
			storage: s3(),

			// 或混合:覆寫一個欄位,其餘來自環境
			// storage: s3({ publicUrl: "https://cdn.example.com" }),
		}),
	],
});

透過 S3 API 使用 R2

將 S3 憑證與 R2 一起使用以獲得簽名上傳 URL 等功能:

storage: s3({
	endpoint: "https://<account-id>.r2.cloudflarestorage.com",
	bucket: "emdash-media",
	accessKeyId: process.env.R2_ACCESS_KEY_ID,
	secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
	publicUrl: "https://pub-xxxx.r2.dev",
});

在 Cloudflare 控制面板的 R2 > Manage R2 API Tokens 下產生 R2 API 憑證。

MinIO

將 S3 配接器指向帶有存取憑證的 MinIO 端點:

storage: s3({
	endpoint: "https://minio.example.com",
	bucket: "emdash-media",
	accessKeyId: process.env.MINIO_ACCESS_KEY,
	secretAccessKey: process.env.MINIO_SECRET_KEY,
	publicUrl: "https://minio.example.com/emdash-media",
});

本機檔案系統

使用本機儲存進行開發。檔案儲存在磁碟上的目錄中。

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

export default defineConfig({
	integrations: [
		emdash({
			storage: local({
				directory: "./uploads",
				baseUrl: "/_emdash/api/media/file",
			}),
		}),
	],
});

設定

選項類型描述
directorystring檔案儲存的目錄路徑
baseUrlstring提供檔案服務的基礎 URL

除非您設定自訂靜態檔案伺服器,否則 baseUrl 應與 EmDash 的媒體檔案端點(/_emdash/api/media/file)相符。

基於環境的設定

根據環境切換儲存後端:

import emdash, { s3, local } from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";

const storage = import.meta.env.PROD
	? r2({ binding: "MEDIA" })
	: local({
			directory: "./uploads",
			baseUrl: "/_emdash/api/media/file",
		});

export default defineConfig({
	integrations: [emdash({ storage })],
});

簽名上傳

S3 配接器支援簽名上傳 URL,允許用戶端直接上傳到儲存而無需透過您的伺服器。這提高了大檔案的效能。

使用 S3 配接器時簽名上傳是自動的。管理介面在可用時使用它們。

支援簽名上傳的配接器:

  • S3(包括透過 S3 API 的 R2)

不支援簽名上傳的配接器:

  • R2 binding(改用帶有 R2 憑證的 S3 配接器)
  • Local

Storage 介面

所有儲存配接器實作相同的介面:

interface Storage {
	upload(options: {
		key: string;
		body: Buffer | Uint8Array | ReadableStream;
		contentType: string;
	}): Promise<UploadResult>;

	download(key: string): Promise<DownloadResult>;
	delete(key: string): Promise<void>;
	exists(key: string): Promise<boolean>;
	list(options?: ListOptions): Promise<ListResult>;
	getSignedUploadUrl(options: SignedUploadOptions): Promise<SignedUploadUrl>;
	getPublicUrl(key: string): string;
}

這種一致性允許在不更改應用程式程式碼的情況下切換儲存後端。