定期実行:Github Actions / Vercel cron / Cloudflare
2026年3月12日cron:定期的にコマンドやスクリプトを実行する仕組み
Github Actions
Githubのリポジトリから、またはローカルに
.github/workflows/フォルダを作成し.ymlファイルを作成workflows/フォルダには複数のymlファイルを置くことができる2,000分/月の実行時間まで可能
ymlファイル:認証キーで保護されたAPIルートを呼び出す設定
// cron.yml
name: cron-test
on:
schedule:
- cron: '*/10 * * * *' # 10分おき
workflow_dispatch:
jobs:
run-cron:
runs-on: ubuntu-latest
steps:
- name: Call API
run: |
curl -H "x-api-key: ${{ secrets.CRON_KEY }}" \
${{ vars.APP_BASE_URL }}/api/cron-test環境変数:
「リポジトリ/設定/Actions secrets and variables」から環境変数を設定
secretsとvariablesの使い分けはNextjsのNEXT_PUBLICと同じ感じで判断する。それに照らし合わせるとDB_URLやAPI_KEYはsecrets、BASE_URLはvariablesでいい
*secretsは再び環境変数の値を確認しようとしても表示されない
定期実行するAPIルート:
//route.ts
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
if (req.headers.get("x-api-key") !== process.env.CRON_KEY) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// 実行したい処理
console.log("Cron job running!");
return NextResponse.json({ status: "ok" });
}Vercel cron
Vercel cronは2つのアプリ & それぞれ1日1回まで
"0 13 * * *":正確な時間(13:00)には実行されず、13 ~ 14時の間に実行される
vercel.json:ルートに置く
{
"crons": [
{
"path": "/api/test-cron",
"schedule": "0 17 * * *"
}
]
}Githubの例と違い
vercel.jsonにはHTTPヘッダーは書けないので、VercelのダッシュボードにCRON_SECRETのような環境変数を作成し、該当ルートを保護する
定期実行するAPIルート:
// route.ts
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
if (req.headers.get('authorization') !== `Bearer ${process.env.CRON_SECRET}`) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
console.log("Vercel cron job running!");
return NextResponse.json({ status: "ok" });
}Cloudflare Workers
テンプレートは以下のコマンドから作成
npm create cloudflare@latestindex.ts:
import { env } from 'cloudflare:workers';
export default {
async scheduled() {
console.log('Cron');
await fetch(`${env.APP_BASE_URL}/api/cron`, {
method: 'POST',
headers: {
Authorization: `Bearer ${env.CRON_SECRET}`,
},
});
},
};認証で保護されたアプリ側のAPIルートにCloudflare Workersから定期的にリクエストする
wrangler.jsonc:
"triggers": {
"crons": ["0 * * * *"]
}npm run deployをした後にダッシュボードを見ると「トリガーイベント」が追加されている。
github
/cloudflare
vercel