CloudflareWorkersにBunで作ったNext.jsアプリケーションをデプロイしてみる

cloudflareを使ったことがありますか?

開発者にはとても人気があるサービスだと思うのですが、今回Bunで作ったNext.jsのアプリケーションをデプロイしてみようと思います。

# Cloudflareとは
CDNやインターネットセキュリティ、DNSなど様々なサービスを提供しています。

:::note
### CDNとは
`コンテンツデリバリーネットワーク(CDN)`とは、コンテンツのキャッシュと配信経路の最適化を行うことで質の高いコンテンツを配信するための仕組みです。
:::

一部機能は無料で提供しており、安価で安全にアプリケーション運用をするためのサービスが揃っています。

## Cloudflare workersとは
Cloudflare workersとは、Cloudflareの提供している動的ホスティングが可能なサービスです。

一方でCloudflare Pagesは静的ホスティングが可能なサービスとなっており、一般的にはこちらの方がよく使われます。

しかし、今回はNext.jsのサーバーコンポーネントを使用したいため、動的ホスティングの可能なworkersを使用します。

# 実際にデプロイしてみる

## Next.jsのアプリケーションを１から作成する場合

cloudflareでは、デプロイするための環境をあらかじめセットアップしながらプロジェクトを作ることができます。
```zsh
bun create cloudflare@latest . --framework=next --platform=workers
```

## 既存のNext.jsアプリケーションでデプロイ準備をする場合
しかし、私はすでにアプリケーションを作ってしまっていたので、そのアプリケーションをcloudflareにデプロイできるようしていこうと思います。

まず下のように`@opennextjs/cloudflare`を依存関係に追加します。
```zsh
bun add @opennextjs/cloudflare --dev
```

:::note
### opennextjsとは
opennextjsとは、さまざまなプラットフォームにNext.jsアプリをデプロイするためのツールです。
このツールを使うと、Vercel以外のAWSやCloudflare等のプラットフォームへのデプロイができるようになるだけでなく、一部機能をAWSのECSやLambdaに上げたりすることもできるらしいです。

https://opennext.js.org/

:::

次にwranglerの設定ファイルを記述します。

:::note
### wranglerとは
cloudflareの開発者用CLIツールです。
これを使うことでworkersに対する操作をCLIで行うことができます。

opennextjsはこのツールを内包しています。
:::

jsoncとtomlファイル等で記述できます。
>私はtomlで書いています。

```wrangler.toml
name                 = "duhang-web"                 # Workers サブドメイン名
main                 = ".open-next/worker.js"       # OpenNext が出力するエントリ
compatibility_date   = "2025-04-18"                 # 互換性の基準日
compatibility_flags  = ["nodejs_compat"]            # Node.js API 互換モード

[assets]
directory = ".open-next/assets"  # 静的アセット配置ディレクトリ
binding   = "ASSETS"             # バインディング名
```

```wrangler.jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "main": ".open-next/worker.js",
  "name": "duhang-web",
  "compatibility_date": "2025-04-18",
  "compatibility_flags": ["nodejs_compat"],
  "assets": {
    "directory": ".open-next/assets",
    "binding": "ASSETS"
  }
}

```



# デプロイする
下のコマンドを打つことでcloudflareにあげるためのビルドとデプロイを行ってくれます。

走らせるとcloudflareへのログインが促されるのでログインします。

```zsh
bun opennextjs-cloudflare build && bun opennextjs-cloudflare deploy
```

:::note warn
### 上のコマンドの注意事項
上のコマンドの`&`を一つにしてしまうとdeployが先に走ってしまいます。

`&&`にした場合、左側のbuildが成功しないと右側のdeployが走らないようになります。
:::

完了するとURLがCLIに表示されるのでクリックします。
URLの形式は`https://[プロジェクト名].[アカウント名].workers.dev/`の形式になります。

また、今後簡単にコマンドを打つためにpackage.jsonに以下の内容を追記します。
そうすることでbuildコマンドを`workers:build`,Deployコマンドを`workers:deploy`とすることができる。

```package.json
{
  "name": "duhang_web",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "build:worker": "cloudflare",
    "workers:build": "opennextjs-cloudflare build",
    "workers:deploy": "opennextjs-cloudflare deploy"
  },
```

# CDを組む
今回はGithubActionsでデプロイも自動化するためにCDを組んでみようと思います。

:::note
### CDとは
CDには継続デリバリー、継続デプロイメントの2つの手法のことを指します。

`継続デリバリー`は、コード変更が行われた際に自動でテストやビルドを行い、いつでもリリースできる環境を構築する開発手法のことです。

`継続デプロイメント`は、テストやビルドをパスした状況で、本番環境へ自動デプロイする手法です。
:::

## API TOKENを用意する
デプロイにはCloudflareで発行できるAPI TOKENが必要になります。

なのでCloudflareでトークンを発行します。

Cloudflareの画面右上に人のマークがあると思うのでそれをクリックしてProfileを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/2b098715-5b6d-49a1-8fb1-fcc1d65f0e68.png)

そこから`API Tokens`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/940fef80-a555-4c69-ad68-33d61ea74c79.png)

すると、下の画面が出てくるので`Create Token`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/fe34f144-4c59-41a6-9f12-5fd3667db291.png)

`API Token`のテンプレートが出てくるので今回は`Edit Cloudflare Workers `を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/0127fa4d-8961-4d70-8256-b012f3efabe7.png)

`Token name`を`Deploy by Gtihub Actions`に変更しておきます。

また、`AccountResources`と`ZoneResources`には、自身のアカウントを入力します。
![スクリーンショット 2025-04-20 8.18.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/833c439a-daa8-4496-9673-edcda36561ae.png)

`Continue Summary`で権限を確認し、Tokenを作成できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/48ffacd7-c82a-4a95-9220-8f55114e5805.png)

作成したらAPITokensが見れるようになる。
![スクリーンショット 2025-04-20 8.20.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b44f5c31-3337-42b8-abcb-e1dcdbfba143.png)

これをGitHubのsecretsに保存します。

## Actionsを組む

GithubActionsを使って下のようにCDを組んでみました。

下のようにすることでmainブランチにpushした際にcloudflareに自動デプロイされます。
```yml
name: Release

on:
    push:
      branches:
        - main

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: checkout　
        uses: actions/checkout@v4 #リポジトリをクローン
      - name: setup bun
        uses: antongolub/action-setup-bun@v1 #bunをセットアップ
        with:
          bun-version: "latest"
      - name: install dependencies
        run: bun install #依存関係をインストール

      - name: Build for Cloudflare Workers
        run: bun workers:build #ビルドする

      - name: Deploy to Cloudflare
        run: bun workers:deploy #デプロイする
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} #APITOKENを環境変数に設定する。
```

:::note warn
### ActionsでのCDを使う際に注意したいこと
ここでもしかしたらローカルでDeployコマンドを動かしたら動くのに、Actionsで動かすと動かない人がいると思います。

この原因として考えられるのは環境変数の設定不足です。
ローカルでDeployを行うとプロジェクトにある.envファイルを自動で読み取ってデプロイしてくれるのに対し、CDではActions内で環境変数を設定するようにする必要があります。
なのでsecretsに環境変数を設定し、Actionsのymlファイルにしっかり書くことを忘れないようにしましょう。

```yml
    - name: Deploy to Cloudflare
      run: bun workers:deploy #デプロイする
      env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          NEXT_PUBLIC_API: ${{ secrets.NEXT_PUBLIC_API }}
```
:::