Cron TriggersでCloudflare Pagesを定期的にビルドする
経由
自分が管理しているサイトは更新頻度が少なく、総データも少ないため、ビルド時にデータを取得するJamstackを採用しています。
データはHeadless CMS(microCMS)と外部APIを利用しています。
Headless CMSはデータの更新時にWebhookによる通知ができます。これによってビルドサーバーに「投稿データを更新したから、再度ビルドしてデータを取得してね」と伝えることができます。
ただ、Webhookによる通知に対応していない外部のAPIを利用する場合、データが更新されてもビルドサーバーはその更新を知ることがないため、ビルドが実行されません。
対応策としては色々あるのですが、今回は多くて1日1回と更新頻度も多くないため、定期的にビルドする方針にしました。
余談: クライアントサイドFetch
他の対応策として「ページ表示時にクライアントサイドでFetchする」という案も考えていたのですが、今回利用した外部APIがCORS対策されているので、外部APIを叩くためのServerless Functionsを立てる必要がありました。
その方が最新の情報を取得できますが、基本的に静的にパッと表示されるサイトにしたかったのと、クライアントサイドFetchのためにLoading等でジャカジャカした表示を見せたくないので見送りました。
Webhookを定期的に叩いてPagesを定期的にビルドする
標準の機能でPagesを定期的にビルドするオプションを探してみましたが、ありませんでした。ただ、前述の通り、PagesはWebhookによる通知で再度ビルドを実行できます。
Cloudflare Workersを定期実行するためのCron Triggersがあります。これを利用して定期的にWebhookで通知を送ります。
Webhookのエンドポイントを控えておく
先にWebhookのエンドポイントを控えておきます。
Cloudflareの管理画面からPagesのプロジェクトを選択してSettings>Builds & deployments>Deploy hooksを選択します。
Add deploy hookで適当な名前をつけてHookを作成します。
ここで取得したデプロイ用のHookは外部に公開しないようにシークレットキーと同等の取り扱いをします。
Cron Triggerの作成
雛形を作成します。 執筆時点ではwrangler init
はサポートされなくなったのでnpm create cloudflare
で雛形を作成します。
実行すると対話方式で聞かれるので回答内容はWhat type of application do you want to create?
にてScheduled Worker (Cron Trigger)
を選択します。
$ npm create cloudflare
作成された雛形を開いて実装します。1日1回実行して欲しいので今回は毎日午前12時に実行するようにしました。開発段階では1時間に1回など、頻度を狭めておくと確認がしやすいです。
[vars]
WEBHOOK_URL = '<YOUR_WEBHOOK_URL>'
[triggers]
# run At 12:00 AM every day
crons = ["0 0 * * *"]
export interface Env {
WEBHOOK_URL: string;
}
export default {
async scheduled(
event: ScheduledEvent,
env: Env,
ctx: ExecutionContext,
): Promise<void> {
try {
const res = await fetch(env.WEBHOOK_URL, {
method: "POST",
});
const wasSuccessful = res.ok ? "success" : "fail";
console.log(`trigger fired at ${event.cron}: ${wasSuccessful}`);
} catch (error) {
if (error instanceof Error) {
console.error(`trigger fired at ${event.cron}: ${error.message}`);
} else {
console.error(`trigger failed at ${event.cron}`);
}
}
},
};
デプロイします。
$ wrangler deploy
Cron TriggersによるWebhook通知が成功すると、Pagesの管理画面のDeployments
にて定期的にビルドされているのが確認できます。
デプロイ頻度があまりに多すぎるとPagesフリープランの上限に引っかかるので適当に設定しましょう。
参考
Discussion