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

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

🎈 Cloudflare | ふうせん🎈 FU-SEN

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

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


目次


公式・関連サイト


特徴

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

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

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


CLI のインストール

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

npm install -g @cloudflare/wrangler

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

wrangler login

次の表示になるので y を選んで下さい。

Allow Erangler to open a page in your browser? [y/n]

ブラウザが起動するので、認証してトークンを渡します。

もう一つのログイン方法

wrangler login でうまくいかない場合、(例えば複数環境から使用する場合)
もう一つの認証方法があります。次を入力します。

wragler config

API トークンの入力になります。

 Cloudflare の Web サイトへログインし、
右上  - マイプロフィール から 上 API トークン を選択、
「API トークン」の *トークンを作成する+ を選択します。
「API ロークンテンプレート」として Cloudflare Workers を編集する を選択し、
あとは手順のまま進めて下さい。API トークンが表示されるので、
これをコピーし、シェルの入力部分へ貼り付けます。

wrangler whoami

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


プロジェクトの作成

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

wrangler generate プロジェクト名

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

 Workers - Quickstarts | Cloudflare Docs

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

wrangler generate プロジェクト名 https://github.com/cloudflare/worker-template

この erangler コマンドが失敗する場合がありますが、
この場合は単にクーロンして構いません。

git clone https://github.com/cloudflare/worker-template

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


ファイル構成

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

package.json

最小限だと次のような内容になります。

{
  "private": true,
  "name": "プロジェクト名",
  "version": "0.0.0",
  "description": "説明",
  "main": "index.js"
}

特に重要なのは main で実行されるファイルです。
このファイルが参照で実行されるファイルになります。
デフォルトは index.js ですが、変更可能です。

wrangler.toml

プロジェクト名.サブドメイン.workers.dev で動作させたい場合は
次の wrangler.toml になります。

name = "プロジェクト名"
type = "javascript"
account_id = "アカウント ID"
workers_dev = true

独自ドメインに適用する場合は次になります。
対象の独自ドメインは 🎈 Cloudflare でサイト登録されている必要があります。

name = "プロジェクト名"
type = "javascript"
account_id = "アカウント ID"
route = "ドメイン/*"
zone_id = "ゾーン ID"

zone_id は Cloudflare Web サイトでログインしている時に、
ドメインを選択すると、API のゾーン ID/Zone ID で表示されています。
この文字列を入れます。

route は ドメイン\* にすると、
そのドメイン名内で参照する毎に実行されるようになります。
代わりに ドメイン/search/* や ドメイン/boot という指定もできますが、
この方法では ? を使用した動作は * を使わない場合うまく機能しませんので、
ディレクトリ・ファイル部分にパラメータを含めるか、
POST メソッドにする必要があります。

routes = ["ドメイン/範囲", "ドメイン/範囲"]

route の代わりに routes を使用すると、複数指定が可能です。

route や routes の指定により、
ドメイン 内の指定で Worker 動作を変える事ができます。

https://sub.ドメイン/ファイル が動作する時、
*.ドメイン/* や sub.ドメイン/* よりも
* がない sub.ドメイン/ファイル の実行が優先されます。

Cloudflare Web サイトのドメイン内にある Workers 内では
ルートの指定先として 何も表示しない/None が存在し、
特定のルートだけ Workers を実行せずに配信サーバを参照させるようにもできます。

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 でも動作するソースであれば、こちらも確認してみて下さい。