# 自社サイトを Vercel から Cloudflare Workers へフル移行した記録

- 公開日: 2026-06-11
- 更新日: 2026-07-24
- URL: https://systemdesignworks.co.jp/news/vercel-to-cloudflare-workers-migration
- 発行: 株式会社システムデザインワークス

> AI 時代のセキュリティリスクへの備えとコスト最適化を狙い、弊社コーポレートサイト（Next.js + Payload CMS）を Vercel から Cloudflare Workers へフル移行しました。Hyperdrive・R2・Durable Objects を組み合わせた構成と、workerd 特有のハマりどころを共有します。

こんにちは！システムデザインワークスの山岸です。

現在ご覧いただいている弊社のコーポレートサイト（Next.js + Payload CMS 構成）のホスティングを、Vercel から Cloudflare Workers へ全面的に移行しました。データベース接続・画像配信・メール送信・定期実行まで含めた「フル移行」です。狙いは、AI 時代に急速に高まるセキュリティリスクへの備えと、コストの最適化でした。

結論から言うと、サイトはいま Cloudflare のエッジ（世界中に分散したサーバー網）上で安定稼働しています。ただ、移行は一筋縄ではいきませんでした。Workers は一般的なサーバーとは仕組みが異なる実行環境のため、「これまで普通に動いていた画像処理やメール送信が、移行した途端に動かなくなる」という壁に何度もぶつかったのです。本記事では、採用した構成と、特にハマった 3 つのポイントを共有します。

## 背景・課題：AI 時代のセキュリティリスクに、先回りして備えたい

移行前の構成は、ホスティングが Vercel、メディアストレージが Vercel Blob、データベースが Supabase（PostgreSQL）でした。Vercel の開発体験は素晴らしく、不満があったわけではありません。特に、GitHub にプッシュするだけで確認用のプレビュー URL が自動発行される体験は秀逸で、レビューや動作確認のスピードを大きく支えてくれていました。

それでも移行を決めた一番の理由は、**セキュリティ**です。

生成 AI の登場により、攻撃の様相は急速に変わっています。脆弱性の探索や攻撃コードの作成が自動化・高速化され、情報漏洩や脆弱性を突いたハッキングのリスクは、企業規模を問わず急激に高まっています。「うちは小さい会社だから狙われない」が通用しない時代になりました。

Cloudflare は世界中のインターネットトラフィックの相当な割合を中継する、世界最大級のセキュリティ企業です。DDoS 攻撃（大量アクセスでサービスを停止させる攻撃）の防御や WAF（Web アプリケーションファイアウォール）をエッジで標準的に提供しており、アプリケーションが動く場所そのものを Cloudflare 上に置けば、この防御網の内側でサイトを運用できます。

もう一つの理由は**コスト**です。Workers の有料プラン（Workers Paid）は月 5 ドルからと安価で、R2（Cloudflare のオブジェクトストレージ）は転送量課金がありません。セキュリティを高めながら固定費も抑えられる、という点が決め手になりました。

ただし条件を一つ決めていました。**Vercel で気に入っていた「プッシュすればプレビュー URL が出る」開発体験は、移行後も手放さない**こと。セキュリティとコストのために開発スピードを犠牲にしては本末転倒だからです。

加えて、「まず自分たちで試して、効果と落とし穴を把握してからお客様に提案する」が弊社のスタイルです。今回の移行はその実践でもありました。

## 移行後の構成：すべて Cloudflare のマネージドサービスに寄せる

Next.js を Cloudflare Workers で動かすために、公式が推奨する **OpenNext**（`@opennextjs/cloudflare`）を採用しました。Next.js のビルド成果物を Workers のランタイムである workerd 向けに変換してくれるアダプタです。

役割ごとの構成は次のとおりです。

- **ホスティング**: Cloudflare Workers（OpenNext 経由）
- **データベース接続**: Supabase PostgreSQL へ **Hyperdrive**（Cloudflare のコネクションプーリングサービス）経由で接続
- **メディアストレージ**: Vercel Blob から **R2** へ全件移行
- **画像リサイズ**: sharp（画像処理ライブラリ）の代わりに **Cloudflare Image Transformations** へ委譲
- **SSG/ISR キャッシュ**: ページキャッシュは R2、タグ管理と再生成キューは **Durable Objects**（Workers 用の永続ステートフルオブジェクト）
- **メール送信**: SMTP から **Cloudflare Email Service** へ切替
- **定期実行**: Vercel Cron から **Workers Cron Triggers** へ移植
- **デプロイ**: GitHub Actions から自動デプロイ（ブランチごとのプレビュー URL 付き）

ポイントは「Workers で動かないものを無理に動かす」のではなく、**動かない部分を Cloudflare のマネージドサービスに置き換える**方針で統一したことです。

## 実装・検証の要点：workerd で本当にハマった 3 つ

移行作業の大半は順調でしたが、workerd は Node.js と似て非なるランタイムです。特に苦労した 3 つを紹介します。

### 1. 間欠的に発生する謎のハング（Error 1101）

移行直後、管理画面など DB アクセスの多いページで、リクエストが応答しないまま失敗する現象（Cloudflare の Error 1101）が**間欠的に**発生しました。再現条件が安定せず、ローカルでは再現しない厄介なバグです。

原因は 2 つ重なっていました。

1. **Hyperdrive の接続先が IPv6 専用だった**: Supabase の direct 接続は IPv6 専用で、これがハングの一因に。IPv4 で到達できる Session pooler（`pooler.supabase.com:5432`）へ変更して解消しました。なお Transaction pooler（6543 番ポート）は prepared statement（SQL の事前コンパイル機能）に非対応のため使えません
2. **コネクションプールが workerd の I/O 分離に違反していた**: Node.js の感覚でモジュールスコープに pg のコネクションプールを置くと、DB 接続（ソケット）がリクエストをまたいで再利用されます。workerd はリクエスト間の I/O を分離する設計のため、これが後続リクエストの無限ハングを引き起こしていました。**Workers 上では接続を使い捨て（**`maxUses: 1`**）にし、実際のプーリングは Hyperdrive に委ねる**構成で解決しました

```typescript
// Workers 実行時のみ: 接続は使い捨て、プーリングは Hyperdrive に任せる
const pool = new Pool({
  connectionString,
  max: 10,
  maxUses: 1, // リクエストをまたいだソケット再利用を防ぐ
})
```

修正後は管理画面への同時 20 リクエストがすべて正常応答し、Error 1101 はゼロになりました。

### 2. sharp が動かない、そして SVG が全滅した

Payload CMS や next/image が使う画像処理ライブラリ sharp はネイティブバイナリを含むため、workerd では起動時にクラッシュします。そこで画像のリサイズ・再エンコードは Cloudflare Image Transformations（`/cdn-cgi/image/` の URL に変換を委譲する仕組み）へ切り替えました。

ところが切り替え後、サイト中のロゴや技術アイコンが**一斉に表示されなくなりました**。原因は、Image Transformations がベクター画像（SVG）の変換に対応しておらず 404 を返すこと。カスタムローダー側で SVG と GIF は変換を通さず原本を直接配信するよう除外して解決しました。

### 3. 問い合わせメールが「静かに」届かなくなっていた

移行後しばらくして、お問い合わせフォームの通知メールが届いていないことに気づきました。workerd では DNS/TCP の制約により nodemailer の SMTP 送信が機能しません。しかも送信エラーはフォームライブラリ側で握りつぶされており、表面上は正常に見えていました。

対応として、Cloudflare Email Service（`send_email` バインディング）を使う Payload 用のメールアダプタを実装し、Workers 上では `env.EMAIL.send()` で送信する構成に切り替えました。ローカル開発では従来どおり SMTP を使い分けています。

エラーが画面に出ない「サイレント障害」は、移行プロジェクトで最も怖い類のものです。**移行後は主要動線（問い合わせ・ログイン・記事更新）を実際に通すスモークテストが欠かせない**と再認識しました。

### やめたこと・採らなかった選択肢

- **OpenNext 生成物への直接パッチ**: 定期実行（cron）を生成された Worker に差し込む案は、OpenNext の更新ごとに壊れるため不採用。cron 専用の小さな Worker を別に立て、service binding（Worker 間の内部呼び出し）で本体 API を叩く構成にしました
- **CDN キャッシュの積極パージ**: 設定不備時に黙って失敗する（silent failure）リスクがあるため、初期構成では意図的に無効化。安定稼働を確認してから段階導入する方針です

## 結果：セキュリティもコストも狙いどおり、デプロイ体験まで向上

- サイト全体が Cloudflare の防御網（DDoS 対策・WAF）の内側で動くようになり、当初の狙いだったセキュリティ面の土台が整った
- ホスティングの固定費は **Workers Paid（月 5 ドル〜）** が基本となり、メディア配信も R2 直配信で転送量課金なし。コストの見通しが立てやすくなった
- 管理画面・公開ページとも安定稼働し、間欠ハング（Error 1101）は解消
- Payload で記事を更新すると該当ページだけが再生成される ISR（ページの差分再生成）も Workers 上で機能
- 移行の条件にしていた「プッシュすればプレビュー URL が出る」体験も再現。GitHub Actions と Workers のプレビュー機能（preview alias）を組み合わせ、**main へのプッシュは本番デプロイ、それ以外のブランチはブランチ名入りのプレビュー URL が自動発行**される開発フローを構築できた

なお、バンドルサイズが Workers 無料プランの上限（gzip 3MiB）を超えるため Workers Paid プランが前提になりますが、それでも月 5 ドルからという価格は移行の後押しになりました。

最後に、移行を終えて振り返った両者の比較を表にまとめます。どちらが優れているという話ではなく、**Vercel の手軽さを取るか、Cloudflare のセキュリティとコストを取るか**という選択だと感じています。

| 比較項目 | Vercel | Cloudflare Workers |
| --- | --- | --- |
| 月額基本料金 | Pro プラン: $20／人 | Workers Paid: **$5〜** |
| メディア配信の転送量 | 転送量に応じて課金 | R2 は**転送量課金なし** |
| セキュリティ | WAF はプラン・設定しだい | **DDoS 防御・WAF を標準提供** |
| 実行環境 | Node.js がそのまま動く | workerd（Node.js 互換は部分的。sharp などのネイティブモジュールは不可） |
| 画像リサイズ | 組み込みの画像最適化 | Image Transformations へ委譲（SVG / GIF は素通しが必要） |
| メール送信（SMTP） | 利用可 | SMTP 不可（Email Service で代替） |
| プレビュー URL | プッシュするだけで自動発行 | CI（GitHub Actions）で構築して再現可能 |
| 構築・移行の手間 | ほぼ設定不要 | OpenNext の導入など個別対応が必要 |

※ 2026 年 6 月時点。Next.js + Payload CMS 構成での弊社の移行経験に基づきます。

## まとめ：移行から得た 3 つの学び

1. **workerd は「ほぼ Node.js」ではない**: ネイティブモジュール（sharp）、SMTP、リクエストをまたぐソケット再利用——Node.js の常識が通用しない箇所は事前にリストアップしておく
2. **動かないものはマネージドサービスに置き換える**: Hyperdrive・R2・Durable Objects・Email Service と、足りないピースは Cloudflare 側に揃っている。無理に互換レイヤーを自作しない
3. **切り戻せる形で段階移行する**: メディア移行は「コピーのみ」で旧環境を残し、画像変換には無効化スイッチを用意。安心して前に進むには退路の設計が効く

## ご相談お待ちしております。

Web サイト・Web システムのセキュリティ強化や、Vercel・AWS からの移行、Cloudflare Workers での新規構築をご検討中の方、栃木県でシステム開発・アプリ開発の会社をお探しの方は、ぜひ一度ご相談ください。

システムデザインワークスでは、今回のような自社での実践に基づき、インフラ選定から移行・運用まで一貫してサポートしております。お気軽にお問い合わせフォームよりご連絡ください。
