ホスティング先をVercelからCloudflareに移行した
特にVercelに不満があったわけではないけど、唐突にCloudflareに移行したい気持ちになったので移行した。
動機としては弱めのものがいくつかあって、何が決定打というわけではないけど、逆に「Vercelを使い続けたい理由」もそこまでなかったので気持ちを優先した。
- このサイトはAstroで構築していて、Astro開発チームは年初にCloudflareに加わっている(参考: AstroがCloudflareに)
- tacona.net のドメインはCloudflare Registrarから購入している
- VercelもCloudflareも、僕の個人サイト程度のアクセス数なら無料枠で十分事足りるので、好みで選んで問題ない
そんなこんなで、Astroの事情や自分のドメイン管理の都合上「Cloudflareに寄せちゃえばいいんじゃ?」という気持ちが増えてきた。
元々Vercelを使っていたのはこのサイトの前身にあたるサイトをNextjsのStatic Site Generatorを使っていたからであって、とりあえず一旦Vercelで…という理由しかなかった。
とはいえ無料枠で長いこと使わせてもらっていてVercelには感謝しかない。
Astro製のプロダクトをCloudflare Workersにホスティングする移行手順を備忘録がてらメモしておく。
事前準備
Cloudflare API Token 生成
僕のサイトはmainブランチへのpushをデプロイのトリガーにはしておらず、GitHubリリース(バージョニング)やAstro Content Collectionsの変更(ノートの追加)をトリガーに意図したタイミングでのみデプロイを実行している。
そのため、CloudflareのGitHub連携は利用せずGitHub Actionsからデプロイを実行する構成を採っている。
この際、デプロイのためにCloudflare Workersに対する権限を持ったAPI Tokenが必要になるのでこれを予め作成しておく。
Workers向けの権限のプリセットが用意されているので、今回はこれをこのまま使うことにした。

生成したトークンは1passwordなどのパスワードマネージャーで厳重に管理しておく。
GitHub の Secrets 生成
GitHub Actionsでデプロイを実行する際に参照する秘匿情報を登録しておく。
CLOUDFLARE_ACCOUNT_ID: Cloudflareの Workers & Pages で確認できるアカウントIDCLOUDFLARE_API_TOKEN: 事前に準備した Cloudflare API Token
移行手順
依存関係の更新
wranglerというCloudflare Workersの管理用コマンドラインをdevDependenciesに追加しておく。
vp add -D wrangler
wrangler の設定ファイル作成
wranglerの設定を以下のように追加しておく。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "{YOUR_PROJECT_NAME}",
"compatibility_date": "{YYYY-MM-DD(CURRENT_DATE)}",
"assets": {
"directory": "./dist",
},
}
参考: Configuration | Cloudflare Docs
Actionsの作成
Cloudflareはcloudflare/wrangler-actionという公式のActionを提供しているため、これを利用する。
僕は管理のしやすさを意識してデプロイ関連のワークフローはComposite Actionとしてファイルを切り出している。
秘匿情報はSecretsに登録していて公開しても差し支えないので、そのまま添付する。
name: ☁️ Cloudflare Workers Deployment
description: Cloudflare Workersにデプロイを実行するAction
inputs:
cloudflare_account_id:
description: CloudflareのAccount ID
required: true
cloudflare_api_token:
description: CloudflareのWorkers向けAPI Token
required: true
runs:
using: 'composite'
steps:
- name: Set Cloudflare Environment Variables
run: |
echo "CLOUDFLARE_ACCOUNT_ID=${{ inputs.cloudflare_account_id }}" >> $GITHUB_ENV
echo "CLOUDFLARE_API_TOKEN=${{ inputs.cloudflare_api_token }}" >> $GITHUB_ENV
shell: bash
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: 'package.json'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
package_json_file: 'package.json'
- name: Install dependencies
run: pnpm i --frozen-lockfile
shell: bash
- name: Build Astro
run: pnpm run build
shell: bash
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ inputs.cloudflare_api_token }}
accountId: ${{ inputs.cloudflare_account_id }}
呼び出し側からは以下のように実行するだけで良い。
jobs:
cloudflare-deployment:
runs-on: ubuntu-latest
steps:
# https://github.com/actions/checkout
# HEADのみ取得
- uses: actions/checkout@v6
with:
fetch-depth: 1
# Cloudflare Workers へのデプロイを実行する
- uses: ./.github/actions/cloudflare-deployment
with:
cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
参考: Creating a composite action | GitHub Docs
デプロイの実行
試しに作業ブランチのpushをトリガーに発火する一時的なワークフローで上記の「☁️ Cloudflare Workers Deployment」を実行する。
無事にデプロイが成功するとCloudflareのコンソールにある Workers & Pages というページにプロジェクトが表示される。
そこからホスティングしたページへのアクセスも確認できるため、無事に表示されていればひとまずはデプロイは成功となる。
カスタムドメインの設定
今回はドメインの新規割り当てではなく元々Vercelのプロジェクトに割り当てていたドメインをCloudflare Workers向けに指定しなおす対応をした。
順序としては以下の流れで対応した。
- Vercel ProjectのDomain設定からカスタムドメインの設定を削除
- Cloudflareの対象ドメインのDNSレコードから、Vercelのホスティング先に対するレコードを削除
- 対象のCloudflare Workersのカスタムドメイン設定に対象ドメインを設定
この設定の間は一時的に tacona.net へのアクセスができない状態になった。
本当は瞬断しないやり方とかもあるだろうけど、僕のサイトのアクセス数では気にするレベルでもなかったので許容した。

これで、無事にtacona.netがCloudflare Workersから配信されるようになった🎉
後片付け
Vercel関連の情報はすべて不要なので、以下あたりのお掃除を実施。
- 不要になったVercelプロジェクトの削除
- GitHub AppからVercelを削除
- GitHub Secretsに登録されていたVercelの秘匿情報などを削除
vercel.jsonを削除- Vercelに対するデプロイジョブを削除
- Vercel Speed Insightの関連実装と依存関係の削除
これで完全にCloudflareへの一本化が完了し、今後はCloudflareにベッタリしていく生活の始まりとなった☁️
実際やったことはそんなに難しくないのだが、Vite+を使っていることに若干拘ってしまってActionsが失敗することが何度かあって若干時間を浪費してしまった。
cloudflare/wrangler-actionは内部的にリポジトリのlockfileを見てどのパッケージマネージャを利用するかを判断するらしいのだが、lockfileではvpを使うことなど判断できないのでvoidzero-dev/setup-vpを利用するとうまくいかなかった。
こういう時は素直にpnpm/action-setupとか使わないとだな〜〜という小さな学び。
まだCloudflareのコンソールに慣れてなさすぎるので、Core Web Vitalsの確認方法なども今後模索していきたい🚀