Back to Portfolio
May 31, 2026

ホスティング先を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向けの権限のプリセットが用意されているので、今回はこれをこのまま使うことにした。

Cloudflare Workers向けのテンプレート一覧画面。

生成したトークンは1passwordなどのパスワードマネージャーで厳重に管理しておく。

GitHub の Secrets 生成

GitHub Actionsでデプロイを実行する際に参照する秘匿情報を登録しておく。

  • CLOUDFLARE_ACCOUNT_ID: Cloudflareの Workers & Pages で確認できるアカウントID
  • CLOUDFLARE_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 へのアクセスができない状態になった。
本当は瞬断しないやり方とかもあるだろうけど、僕のサイトのアクセス数では気にするレベルでもなかったので許容した。

Workersのドメイン確認画面。しっかりカスタムドメインが表示されている。

これで、無事に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の確認方法なども今後模索していきたい🚀