Cloudflare Workers で自動デプロイ付きのサーバーレスアプリケーションを公開しよう

## はじめに

2/10 のイベントに先駆けて、社内で開催する Cloudflare 勉強会のための資料です

https://cfm-cts.connpass.com/event/307368/

前回までの記事で Cloudflare のアカウントを作り、 Cloudflare Pages 上に Web サイトを公開しました

https://qiita.com/RyoWakabayashi/items/bd9a96290758e11883e8

https://qiita.com/RyoWakabayashi/private/2d40b6e8ae7ddee092db

今回の記事では Cloudflare Workers でサーバーレスアプリケーションを公開します

## Cloudflare Workers とは

https://www.cloudflare.com/ja-jp/developer-platform/workers/

> サーバーレスコードをデプロイして、優れたパフォーマンス、信頼性、拡張性をグローバルに実現しましょう。

Cloudflare Workers はサーバーレスでコードをデプロイ、実行、運用するためのプラットフォームです

コードをデプロイするだけで、 Web からアクセス可能な API などが公開できます

いわゆる FaaS = Function as a Service の一種です

開発者はサーバーを意識することなく、実行したいコードだけに集中できます

サーバーの性能や台数、運用保守に囚われる必要がないため、少人数での運用も可能になります

> ビルトインセキュリティでプロジェクトを拡張

しかも Cloudflare の場合、 WAF や DDoS 攻撃対策などのセキュリティ機能も最初から付いてきます

:::note warn
無料プランの場合、以下の制約があります

> リクエストあたりのCPU時間：10ミリ秒以内

そのため、外部の API を呼び出すような処理は実行できません

10ミリ秒を超えた場合、 Hono だと以下のように `Canceled` とログが出力されます

```
POST https://xxx.yyy.workers.dev/zzz - Canceled @ 2024/2/6 18:21:45
```

有料プラン（$5/月〜）の場合、制約が緩和されます

> リクエストあたりの実時間：30秒以内
:::

## Workers を始めましょう

### ログイン

前々回の記事にも書いた通り、 Cloudflare Workers はクレジットカード登録不要の Free プランで無料から使えます

Cloudflare にログインして、 Workers を始めましょう

https://dash.cloudflare.com/

ログインしたら、ホーム画面（ダッシュボード）が表示されます

![スクリーンショット 2024-02-01 22.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/13590e86-d49b-3410-470e-2d72a5491a30.png)

:::note info
英語表示になっている場合、右上で言語を日本語に設定しましょう
:::

### セットアップ

左メニューから「Workers & Pages」をクリックします

![スクリーンショット 2024-02-02 22.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/cea3d024-c640-713a-a632-0bc374cd6892.png)

「Workers & Pages」の概要ページに遷移します
右上の「アプリケーションの作成」をクリックしてください

![スクリーンショット 2024-02-02 22.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c42ddd35-d32c-5e29-8089-06d2ab87a812.png)

「アプリケーションを作成する」というページに遷移します
「ワーカーの作成」をクリックしてください

![スクリーンショット 2024-02-02 22.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/764d596e-4dbf-55e5-638e-7743cc6c91e0.png)

「"Hello World" スクリプトのデプロイ」というページに遷移します

以下のような JavaScript がコードとして入力されています

```javascript
...

export default {
  async fetch(request, env, ctx) {
    return new Response('Hello World!');
  },
};
```

「Hello World!」という文字列を返すだけのコードになっています

まずは、このまま「デプロイ」をクリックしましょう

![スクリーンショット 2024-02-02 22.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/06a4179f-5ab1-be09-9f67-c1863ee8f716.png)

たったのコレだけでサーバーレスアプリケーションがデプロイできました

「ワーカーをプレビューする」の下にあるリンクをクリックしてみましょう

![スクリーンショット 2024-02-02 22.36.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e50ac8aa-5bbb-e85d-3ea7-6cecbf540c3b.png)

新しいタブで作成したアプリケーションが開きます

![スクリーンショット 2024-02-02 22.37.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d9d2d0c6-587a-d03f-0505-e10c0b8db2aa.png)

コードに書いてあった通り、「Hello World!」と表示されました

元のタブで「ワーカーの構成」をクリックすると、ワーカーのダッシュボードページが表示されます

![スクリーンショット 2024-02-02 22.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/987c7600-0f7b-ac12-1090-54d21c6a3252.png)

### コードの変更

ワーカーのダッシュボードページで右上「クイック編集」をクリックします

コードの編集ページが開くので、適当に変更してから「保存してデプロイする」をクリックしましょう

![スクリーンショット 2024-02-02 22.39.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/8b69c666-8f04-92a4-4d6a-6c5f1407767e.png)

デプロイしたアプリケーションを再読込すると、変更が反映されています

![スクリーンショット 2024-02-02 22.40.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/7d290a72-1dbd-c2a9-46fd-735a102cea91.png)

コードの変更もボタン一つで適用できてしまいました

## CLI からのアプリケーション公開

### TypeScript プロジェクトの作成

次は CLI からプロジェクトを作ってデプロイしてみましょう

以下のコマンドを実行します

```sh
npm create cloudflare@latest my-worker -- --type hello-world --ts --git
```

デプロイするか質問されるので、一旦 No にしておきます

```sh
╰ Do you want to deploy your application?
  Yes / No
```

生成された my-worker ディレクトリー内の `src/index.ts` を開くと、以下のように TypeScript で「 Hello World!」の文言を返すようになっています

```typescript
export interface Env {
    ...
}

export default {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		return new Response('Hello World!');
	},
};
```

### ローカルでのアプリケーション起動

以下のコマンドを実行しましょう

```sh
cd my-worker
npx wrangler dev
```

`? Would you like to help improve Wrangler by sending usage metrics to Cloudflare? › (Y/n)` など質問されるので適当に答えます

ログインを求められた場合、ブラウザで認証してください

その後、以下のように表示され、ローカルでアプリケーションが起動します

```sh
...
[wrangler:inf] Ready on http://localhost:8787
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit                      │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```

「b」キーを押すと、表示された http://localhost:8787 をブラウザで開きます

![スクリーンショット 2024-02-03 14.37.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6b904ccf-4793-cb7d-2739-6a30e5e33955.png)

確かに「Hello World!」と返ってきました

「x」キーを押して終了します

### CLI からのデプロイ

```sh
npx wrangler deploy
```

実行すると、以下のようにログが表示されます

```sh
 ⛅️ wrangler 3.26.0
-------------------
Total Upload: 0.19 KiB / gzip: 0.16 KiB
Uploaded my-worker (0.89 sec)
Published my-worker (4.66 sec)
  https://my-worker.rwakabay.workers.dev
Current Deployment ID: aa403c6a-f08f-408f-8149-db0c6ff45471
```

表示された URL をブラウザで開くと、「Hello World!」が確認できます

![スクリーンショット 2024-02-03 14.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e3ab5ae6-535d-949b-086b-4317fc85c172.png)

Cloudflare を確認すると、プロジェクトが追加されています

![スクリーンショット 2024-02-03 14.50.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/f84cf7e8-3f9e-860d-bbf1-5f0f8601ff3a.png)

## GitHub 連携

自動デプロイできるように、 GitHub との連携を設定します

GitHub Actions を使うことで、 GitHub にプッシュしたタイミングで Cloudflare Workers にデプロイできます
GitHub Actions はパブリックリポジトリーなら無料で実行可能です

https://github.co.jp/features/actions

以下の記事を参考にしました

https://zenn.dev/camomile_cafe/articles/ec3df91c4e7a58

### トークンの発行

GitHub から Cloudflare にアクセスするため、認証用のトークンを発行します

「Workers & Pages」の概要ページから、右メニューにある「API トークンの管理」をクリックしましょう

![スクリーンショット 2024-02-03 14.59.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c90dc63f-7bad-410b-82df-08ba174c9daf.png)

「API トークン」のページから右上「トークンを作成する」をクリックします

![スクリーンショット 2024-02-03 15.00.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/bad45174-b368-7b5c-23c0-4a3bea9bda79.png)

Cloudflare Workers にデプロイするためのトークンなので、「Cloudflare Workers を編集する」の右にある「テンプレートをしようする」をクリックします

![スクリーンショット 2024-02-03 15.02.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/fd0b4526-e57f-41ea-445c-28f9cbdb9314.png)

API トークンの作成ページが表示されます

トークン名の鉛筆アイコンをクリックして、トークン名を変更します

![スクリーンショット 2024-02-03 15.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/2f62e50d-70e8-8543-86e7-c88ef00b3cbb.png)

![スクリーンショット 2024-02-03 15.04.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b0f2d489-1cc4-b5fa-d150-37e7d15728ca.png)

以下のように選択してください

- 「アカウントリソース」で自分のアカウントを選択
- 「ゾーンリソース」で「アカウントにあるすべてのゾーン」、自分のアカウントを選択

「概要に進む」をクリックします

![スクリーンショット 2024-02-03 15.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/80f72e8b-c8ff-9488-b991-08fd2c895351.png)

作成内容の確認画面が表示されます
「トークンを作成する」をクリックしてください

![スクリーンショット 2024-02-03 15.06.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/7cfa5324-1e96-93e5-34d8-464f3f9301d8.png)

作成したトークンが表示されます
「Copy」をクリックして、トークンの値をメモ等に保持しておきます

![スクリーンショット 2024-02-03 15.07.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e72e1ee7-4020-a9ee-1555-a0669c60a22f.png)

### GitHub リポジトリーの作成、設定

以下のリンクから GitHub に新しいリポジトリーを作成します

https://repo.new

Repository name に任意を名前を入力して「Create repository」をクリックしてください

![スクリーンショット 2024-02-03 15.14.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/44e09f80-cfcd-3db2-ad6b-86bee22d8aa5.png)

空のリポジトリーが作成されます

右上の「Settings」タブをクリックしてリポジトリーの設定ページを開きます

![スクリーンショット 2024-02-03 15.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/31056282-37f6-c2ce-23ff-94a186233929.png)

緑色の「New repository secret」をクリックしてください

![スクリーンショット 2024-02-03 15.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/507df685-a143-c72d-923a-6c12a12b2e1f.png)

Name に「CF_TOKEN」など、任意の名前を入力し、 Secret に Clopudflare で発行したトークンの値を入力します
「Add secret」をクリックしましょう

![スクリーンショット 2024-02-03 15.20.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b1a41dff-5b88-3810-ccab-d8c555cedab8.png)

「CF_TOKEN」が Repository secrets に追加されました

![スクリーンショット 2024-02-03 15.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6cd96c50-561c-2d7e-56a5-25b4f3c0ac54.png)

### GitHub Actions の追加

ローカルのプロジェクト内に `.github/workflows/deploy.yml` を以下の内容で作成します

```yml
---

name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - uses: actions/checkout@v3
      - name: Deploy
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CF_TOKEN }}
```

適当に index.ts を変更してください

以下のコマンドでローカルのプロジェクトを GitHub 上にプッシュします

```sh
git remote add origin https://github.com/<GitHubユーザー名>/<リポジトリー名>
git branch -M main
git add .
git commit -m 'Add GitHub Actions'
git push -u origin main
```

プッシュ後、 GitHub リポジトリーの Actions タブを開くと、デプロイが実行されています

![スクリーンショット 2024-02-03 15.53.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/26fe0dd4-27f8-0d41-c4b3-cbbffcf2547c.png)

ローカルで変更した内容が反映されました

![スクリーンショット 2024-02-04 9.43.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/697c6895-1438-76ff-b3ae-f3b5fbd801d0.png)

## まとめ

Cloudflare Workers でサーバーレスアプリケーションを公開できました

GitHub Actions を利用することで、自動デプロイも簡単に実装できました

構築、運用保守が究極的に楽になる、まさにサーバーレスの良いところが体現できています

ものによっては Cloudflare に移行することで、インフラ費用も人的コストも節約できそうです