0. 起因#
最近、Cloudflare Workers KV に無料のクオータがあることを知りました。面白いことをやってみることができそうです。自分のブログサーバーが国内にあるため、より良いエクスペリエンスを得るために、トラフィックを分散させて国外から直接 Cloudflare にアクセスしたいと思っています。
1. 準備#
Hexo ブログを Cloudflare Workers にデプロイするためには、もちろん Hexo のブログが必要です。
また、Cloudflare のアカウントも必要です〜
2. API キーを申請する#
Cloudflare にログインし、プロフィール - API トークンで API トークンを申請します。
デフォルトの Cloudflare Workers テンプレートを使用します
キーを覚えておいてください。後で使います。
3. ローカルで Wrangler CLI をインストールして初回デプロイを行う#
Wrangler のインストール#
Hexo があるなら、Node.js の環境もあるはずですので、npm または yarn を使用して wrangler をインストールします〜
npm i @cloudflare/wrangler -g
# yarn global add @cloudflare/wrangler
プロジェクトの初期化#
Hexo のルートディレクトリに移動して初期化します
wrangler init --site my-static-site # 最後の名前はお好きな名前に変更してください〜
初期化が完了すると、wrangler.toml
ファイルとworkers-site
ディレクトリがディレクトリに追加されていることがわかるでしょう。
設定の変更#
プロジェクトを設定するために、wrangler.toml を変更する必要があります。
[site]
bucket = "./public"
entry-point = "workers-site"
最も重要なのは、これらの 2 行です。bucket
の値をデプロイしたいディレクトリに変更する必要があります。Hexo の場合は./public
です。
また、上記の個人情報も変更する必要があります。
account_id = ""
workers_dev = true
route = "www.nekomio.com/*"
zone_id = ""
account_id
はログインすると大体見えるはずです。自分のドメインをバインドしていない場合は、route
とzone_id
は一時的に無視しても構いません。
デプロイ#
ここでwrangler config
を実行する必要があります。そして、前述のAPIトークン
を入力します。
preview
でプレビューを表示できます。
wrangler preview --watch
publish
でデプロイします。
wrangler publish
これで、Cloudflare 上でウェブサイトを開くことができます。
4. カスタムルーター#
私は Sukka が提供している設定ファイルを使用しています。主に、index.html で終わるリクエストを index.html を含まない URL に 301 リダイレクトし、CSS のキャッシュ時間を延長しています。
参考までに以下に示します。
import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'
addEventListener('fetch', event => {
try {
event.respondWith(handleEvent(event))
} catch (e) {
if (DEBUG) {
return event.respondWith(
new Response(e.message || e.toString(), {
status: 500,
}),
)
}
event.respondWith(new Response('Internal Error', { status: 500 }))
}
})
async function handleEvent(event) {
const { origin, pathname: path, search } = new URL(event.request.url);
if (path.endsWith('/index.html')) {
return new Response(null, {
status: 301,
headers: {
'Location': `${origin}${path.substring(0, path.length - 10)}${search}`,
'Cache-Control': 'max-age=3600'
}
});
}
if (path === '/atom.xml') {
return getAssetFromKV(event, {
cacheControl: {
edgeTtl: 60 * 60,
browserTtl: 2 * 60 * 60
}
});
}
if (path.startsWith('/css/')) {
const response = await getAssetFromKV(event, {
cacheControl: {
edgeTtl: 365 * 24 * 60 * 60,
browserTtl: 365 * 24 * 60 * 60
}
});
// getAssetFromKVはimmutableを追加しないため、キャッシュコントロールを手動で上書きする必要があります
response.headers.set('cache-control', `public, max-age=${365 * 24 * 60 * 60}, immutable`);
return response;
}
const response = await getAssetFromKV(event, {
cacheControl: {
edgeTtl: 60 * 60,
browserTtl: 5 * 60
}
});
response.headers.set('X-XSS-Protection', '1; mode=block');
return response;
}
最後に、終わりです〜
これは無料の制限を示しています。トラフィックが少ない場合は十分です。記事の数が多い場合は、デプロイ回数が制限される可能性があります。
-
Workers 機能
- 1 日あたり 100,000 リクエスト(UTC+0)
- 各リクエストの最大 CPU 時間は 10 ミリ秒まで
- 最初のリクエスト以降の待機時間が最小限になる
-
キーバリューストア機能
- 1 日あたり 100,000 回の読み取り操作
- 1 日あたり 1,000 回の書き込み、削除、リスト操作