Cloudflare CDN のエッジサーバで動的処理が行える Cloudflare Workers(クラウドフレアワーカーズ)についてまとめています。

Cloudflare 内のサービスで、Cloudflare への登録が前提となります。

🎈 Cloudflare | ふうせん🎈 FU-SEN

Cloudflare Workers を用いて静的サイトを公開できる
Workers Sites については別ページにしてあります。

🎈 Cloudflare Workers Sites | ふうせん🎈 FU-SEN

Cloudflare Workers の CLI wrangler が
2022年5月よりバージョン 2 になりました。
これに合わせて管理 Web・CLI 周りが変化しています。
このページでは wrangler バージョン 2 の説明にしてあります。


目次


公式・関連サイト


特徴

Cloudflare Workers は JavaScript のプログラミング言語を
世界 100 ヶ国以上、200 ヶ所以上存在している
CDN のエッジサーバで実行できます。
エッジサーバは日本には東京・大阪・福岡・那覇にあります。

CDN を提供しているサービスは多いですが、静的ファイルに限られ、
動的処理は特定のサーバで動作するようにしている事がほとんどです。
そのため CDN が効いた状態で動的処理ができるサービスは珍しいです。

ライブラリは制限され、外部参照は URL リクエストや WebSocket に限られます。
また、Worker 割り当ての CPU 時間やメモリも少ないため、
比較的シンプル・単純な処理に制限されます。


CLI のインストール

簡単な処理であれば、Clouflare Workers の Web 上でソースを編集し、
実行する事もできるのですが、
通常は CLI を用いてビルドするようになります。
Cloudflare Workers の CLI は wrangler です。

2022年5月より wrangler がバージョン 2 になりました。

npm install -g wrangler

Version 1 を使用していた影響でインストールがエラーになる場合は
--force を付けて下さい。

続いて次のコマンドで Cloudflare の認証を行います。

wrangler login

ブラウザが起動するので、認証して下さい。

wrangler whoami

を入力し、Account Name ・ Account ID が表示されればログインできています。


プロジェクトの作成

次のコマンドでプロジェクトを作成します。

wrangler init プロジェクト名

プロジェクト名 は英数と - _ を使用できます。

 Workers - Quickstarts | Cloudflare Docs

テンプレートを読み込む事ができます。通常 GitHub にあります。

git clone https://github.com/cloudflare/worker-template
cd worker-template-router
npm install

フォルダ(ディレクトリ名)と package.json や wrangler.toml を
目的のプロジェクト名に変更します。


ファイル構成

最低限次のファイルが必要です。あとは削除しても構いません。

package.json

Wrangler 2 では devDependencies を追加し、
必要な node パッケージを記載します。
すでに他の用途で使用している場合は追記されます。

wrangler.toml

プロジェクト名.サブドメイン.workers.dev で動作させたい場合は
次の wrangler.toml になります。[site] 以降を追加して下さい。

name = "プロジェクト名"
main = "src/index.ts"
compatibility_date = "YYYY-MM-DD"

[site]
bucket = "./public"

Wrangler 2 より独自ドメインは Web 上での設定になりました。
Cloudflare Web サイト 内左サイドバー Worders から
プロジェクトを選び、 トリガー・Triggers 内の
「カスタムドメイン・Custom Domains」です。

index.js

実際に動作するコードです。

このソースコードは Cloudflare Workers のサイト上からプロジェクトを選び、
クイック編集 で Web 上から編集する事もできます。


サンプル

 Workers - Examples | Cloudflare Docs

公式サイトによる一例です。

 cloudflare workers 検索結果GitHub

GitHub にもプロジェクトが多く存在します。

転送

無料プランで使用している場合、🎈 Page Rule は 3 項目、
🎈 Cloudflare Pages でも 100 項目までしか設定できません。
Cloudflare Workers を用いたこの方法では、この制限を超えて設定が可能です。

🎈 Vercel など、他の Web サービスでは
転送元・先・ステータスコードの記載だけで良い、コードは不要ですが、
世界中 100 ヶ国以上、200 ヶ所以上ある近くのサーバから
レスポンスが返ってくるのは大きなメリットになれるでしょう。

const redir = new Map([
  ["/google", "https://www.google.com/"],
  ["/yahoo" , "https://www.yahoo.co.jp/"],
  ["/"      , "https://balloon.asia/" ]
])

async function handleRequest(request) {
  const location = redir.get(new URL(request.url).pathname)
  if (location) {
    return Response.redirect(location, 301)
  }
  return new Response("Not Found", {
    headers: { "content-type": "text/plain" },
    status: 404
  })
}

addEventListener("fetch", async event => {
  event.respondWith(handleRequest(event.request))
})

このサンプルでは該当がない場合は Not Found にしています。

 Workers - Bulk redirects | Cloudflare Docs

公式ドキュメントにもサンプルがありますが、
転送元は https://ドメイン/redirect/項目 となっているのにご注意下さい。
return fetch(request) とする事で、Cloudflare 配信元の内容を読み込みます。

特定 URL のプロキシ

async function handleRequest(request) {
  return await fetch("https://参照先/~", request)
}

addEventListener('fetch', function(event) {
  event.respondWith(handleRequest(event.request))
})

独自ドメインで特定の URL の時に https://参照先/~ を参照します。
wrangler.toml のroute は http(s):// を外したドメイン名からの URL 指定です。

async function handleRequest(request) {
  const url = new URL(request.url)
  url.hostname = "参照先ドメイン"
  return await fetch(url.toString(), request)
}

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
})

ドメイン名部分を 参照先ドメイン に置き換えて参照します。
これにより、独自ドメイン設定ができないサーバを配信元にできます。
また wrangler.toml のroute で範囲を指定する事で、
その指定範囲だけ別のサーバを参照するようにできます。

API プロキシ

const proxyMAP = new Map([
  ["/command1", "https://ドメイン/command1.php"],
  ["/command2", "https://ドメイン/command2.php"]
])

async function handleRequest(request) {
  const requestURL = new URL(request.url)
  const location = proxyMAP.get(requestURL.pathname)
  const search = requestURL.search

  if (location) {
    return await fetch(location + search, request)
  }

  return new Response("Not Found", {
    headers: { "content-type": "text/plain" },
    status: 404
  })
}

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
})

API の URL を隠すのに有効です。パラメータは GET・POST 共に引き継ぎます。
実行するドメイン内で使用すると、API 側では CORS を付与する必要がなくなります。
proxyMAP を複数サーバ入れておいて、サーバを切り替える事もできます。


プレビュー・公開

ローカルでの動作確認は次のコマンドです。

wrangler dev

http://localhost:8787/ で動作確認を行えます。

または次の URL でプレビュー動作が可能です。

wrangler preview --watch

公開は次のコマンドです。

wrangler publish

wrangler.toml の設定に合わせて プロジェクト名.サブドメイン.workers.dev
または独自ドメインの全体(ドメイン名/*)または一部で動作するようになります。


制限

 Workers - Limits | Cloudflare Docs

ここでは無料プランの場合の制限で記載しています。

Worker としての制限は次があります。

項目制限
リクエスト1 日 100000 リクエスト
1 分 1000 リクエスト
メモリ128M
CPU 動作10 ミリ秒

リクエスト の 1 日 100000 リクエスト は
UTC 午前 0 時からの 24 時間が対象範囲になります。
日本時間は午前 9 時です。

CPU 動作 は本当に CPU が動作している時間で、
呼び出しから応答までの待機時間ではありません。
しかし、あまり複雑なコードは処理が距離され、
比較的簡単な処理にする事が求められる事になります。


Workers KV

 Workers - How KV works | Cloudflare Docs

Key Value 型のデータベース(KVS)です。
Cloudflare アカウント毎に領域があり、名前空間(name space)で区別した上で、
読み書きを行う事ができます。有効期限を設定する事も可能です。
(例えばセッション管理で使用でき、削除処理を考慮する必要がありません)
Value 値はバイナリーも可能で、CLI wrangler ではファイルを入れる事もできます。
🎈 Workers Site はこの仕組みを用いて静的ファイルを保存・提供しています。

 Workers - Runtime APIs / KV | Cloudflare Docs

Cloudflare Workers では KV アクセス用の API が存在します。

 Cloudflare API Documentation

外部サービスから Cloudflare のサービスをコントロールできる Cloudflare API にも
Workers KV 関連の API が存在しているので、外部サービスからのアクセスも可能です。

項目制限
読み込み1 日 100000
書き込み1 日 1000
リスト1 日 1000
削除1 日 1000
容量1GB

無料プランええは上記の制限があります。
ただし、書き込み・削除は一度に複数項目を処理可能です。
KV は Key-Value の項目毎に期限を持っているため、
1 日の単位は常に可変します。
(UTC 午前 0 時区切りの Workers の制限とは異なります)


Q&A

JavaScript 以外のプログラミング言語は使用できますか?

 Workers - Quickstarts | Cloudflare Docs

上の Quickstarts ページには
他のプログラミング言語を用いた時のテンプレートがありますが、
いずれも JavaScript に変換しての実行となっています。

Cloudflare サイト登録ができないドメインで Cloudflare Workers を使用できますか?

Cloudflare Workers でドメインを使用する場合は Cloudflare のサイト登録必須です。
そうでない場合は プロジェクト.サブドメイン.workers.dev で使用する必要があります。

🦕 Deno Deploy
🎈 Deno Deploy | ふうせん🎈 FU-SEN

Cloudflare と同じ API で互換性がある Deno Deploy も独自ドメインが割り当てできます。
Deno Deploy でも動作するソースであれば、こちらも確認してみて下さい。