使用 Workers Cron Trigger 每两分钟运行一次短容器任务。该任务打印其计划时间,然后退出。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "cron-container",
"main": "src/index.ts",
"upload_source_maps": true,
// Set this to today's date
"compatibility_date": "2026-11-14",
"observability": {
"enabled": true
},
"triggers": {
"crons": [
"*/2 * * * *"
]
},
"containers": [
{
"class_name": "CronContainer",
"scheduling_policy": "durable_object",
"images": {
"base": {
"dockerfile": "./Dockerfile"
}
}
}
],
"durable_objects": {
"bindings": [
{
"name": "CRON_CONTAINER",
"class_name": "CronContainer"
}
]
},
"exports": {
"CronContainer": {
"type": "durable-object",
"storage": "sqlite"
}
}
}name = "cron-container"
main = "src/index.ts"
upload_source_maps = true
# Set this to today's date
compatibility_date = "2026-11-14"
[observability]
enabled = true
[triggers]
crons = ["*/2 * * * *"]
[[containers]]
class_name = "CronContainer"
scheduling_policy = "durable_object"
[containers.images.base]
dockerfile = "./Dockerfile"
[[durable_objects.bindings]]
name = "CRON_CONTAINER"
class_name = "CronContainer"
[exports.CronContainer]
type = "durable-object"
storage = "sqlite"import { DurableObject } from "cloudflare:workers";
export class CronContainer extends DurableObject {
currentRun;
run(startTime) {
this.currentRun ??= this.runOnce(startTime).finally(() => {
this.currentRun = undefined;
});
return this.currentRun;
}
async runOnce(startTime) {
const container = this.ctx.container;
if (!container.running) {
container.start({
image: container.images.base,
instance: "lite",
enableInternet: false,
env: { MESSAGE: `Scheduled time: ${startTime}` },
});
}
await container.monitor();
}
}
export default {
fetch() {
return new Response("This Worker runs a scheduled Container task.");
},
async scheduled(controller, env) {
await env.CRON_CONTAINER.getByName("cron").run(
new Date(controller.scheduledTime).toISOString(),
);
},
};import { DurableObject } from "cloudflare:workers";
interface Env {
CRON_CONTAINER: DurableObjectNamespace<CronContainer>;
}
export class CronContainer extends DurableObject<Env> {
private currentRun: Promise<void> | undefined;
run(startTime: string): Promise<void> {
this.currentRun ??= this.runOnce(startTime).finally(() => {
this.currentRun = undefined;
});
return this.currentRun;
}
private async runOnce(startTime: string): Promise<void> {
const container = this.ctx.container!;
if (!container.running) {
container.start({
image: container.images.base,
instance: "lite",
enableInternet: false,
env: { MESSAGE: `Scheduled time: ${startTime}` },
});
}
await container.monitor();
}
}
export default {
fetch(): Response {
return new Response("This Worker runs a scheduled Container task.");
},
async scheduled(controller: ScheduledController, env: Env): Promise<void> {
await env.CRON_CONTAINER.getByName("cron").run(
new Date(controller.scheduledTime).toISOString(),
);
},
} satisfies ExportedHandler<Env>;所有触发器使用同一个 Durable Object。如果一次运行仍在进行,另一个触发器会等待该运行,而不是启动第二个任务。此示例不会将重叠运行排队,也不保证恰好执行一次。当任务修改外部数据时,请使其幂等。
monitor() 报告完成或失败,而不是 HTTP 就绪。请将此任务保持足够短,以便在 Cron Trigger 执行限制 内完成。
FROM alpine:3.20
CMD ["sh", "-c", "printf '%s\\n' \"$MESSAGE\""]启动兼容 Docker 的引擎,并使用 Wrangler 4.136.0 或更高版本。
npm i -D wrangleryarn add -D wranglerpnpm add -D wranglerbun add -d wranglernpx wrangler dev --test-scheduledyarn wrangler dev --test-scheduledpnpm wrangler dev --test-scheduled在另一个终端中触发计划处理程序:
curl 'http://localhost:8787/__scheduled?cron=*/2+*+*+*+*'检查容器日志中的计划时间。部署后,Cron Triggers 会自动调用该处理程序。