SIMPLE IS BEST
インフラ··9 min read

Cloudflare R2 で画像ストレージを構築する

R2 は S3 互換のオブジェクトストレージです。Next.js の API Route から画像をアップロードし、CDN 経由で配信するパターンを解説します。


Cloudflare R2 は S3 互換のオブジェクトストレージで、最大の特徴はエグレス(データ転送)料金がゼロであることです。大量の画像を配信するアプリケーションでは、この差が大きなコスト削減につながります。

R2 の特徴

wrangler.toml の設定

toml
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-images"

画像アップロード API の実装

Next.js の API Route から FormData で受け取ったファイルを R2 に PUT します。Edge Runtime で動作させるために export const runtime = "edge" の宣言が必要です。

typescript
import { getRequestContext } from "@cloudflare/next-on-pages";
import { NextRequest, NextResponse } from "next/server";

export const runtime = "edge";

export async function POST(request: NextRequest) {
  const { env } = getRequestContext();
  const formData = await request.formData();
  const file = formData.get("file") as File;

  const key = `uploads/${Date.now()}-${file.name}`;
  await env.BUCKET.put(key, await file.arrayBuffer(), {
    httpMetadata: { contentType: file.type },
  });

  return NextResponse.json({ ok: true, key });
}

画像配信のパターン

ローカルエミュレーション環境では R2 バケットへの公開 URL が使えないため、取得用の API Route を用意する方法が簡単です。本番では R2 バケットにカスタムドメインを設定し、Cloudflare CDN 経由で直接配信するのが最もパフォーマンスが高いパターンです。

ローカルでの確認方法

wrangler pages dev または next dev + setupDevPlatform() を使うと、.wrangler/state/v3/r2/ 以下にファイルがエミュレートされます。アップロードした内容を確認するには、別途 GET エンドポイントを作成して BUCKET.get(key) で取得します。


記事一覧に戻る