Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Container インターフェイス

最終更新 Markdown で表示Agent セットアップ

@cloudflare/containersContainer クラス は、Worker からコンテナインスタンスを操作するいちばん一般的な方法です。

ContainerDurableObject を継承します。 Durable Object がルーティング、永続状態、ライフサイクルフックを管理し、コンテナプロセスは Linux VM 内でイメージを実行します。サブクラスは Durable Object なので、永続的な SQLite ストレージ向けの this.ctx.storage や、一意のインスタンス識別子向けの this.ctx.id を含む、Durable Object API 全体を使えます。コンテナの再起動後も残したい状態(設定、ユーザーデータ、タスク結果など)は、Durable Object のストレージに保存します。

npm i @cloudflare/containers

次に、Container を継承するクラスを定義し、共有プロパティをクラスに設定します。

import { Container, getContainer } from "@cloudflare/containers";

export class SandboxContainer extends Container {
	defaultPort = 8080;
	requiredPorts = [8080, 9222];
	sleepAfter = "5m";
	envVars = {
		NODE_ENV: "production",
		LOG_LEVEL: "info",
	};
	entrypoint = ["npm", "run", "start"];
	enableInternet = false;
	pingEndpoint = "localhost/ready";
}

export default {
	async fetch(request, env) {
		return getContainer(env.SANDBOX_CONTAINER, "workspace-123").fetch(request);
	},
};
import { Container, getContainer } from "@cloudflare/containers";

export class SandboxContainer extends Container {
	defaultPort = 8080;
	requiredPorts = [8080, 9222];
	sleepAfter = "5m";
	envVars = {
		NODE_ENV: "production",
		LOG_LEVEL: "info",
	};
	entrypoint = ["npm", "run", "start"];
	enableInternet = false;
	pingEndpoint = "localhost/ready";
}

export default {
	async fetch(request: Request, env) {
		return getContainer(env.SANDBOX_CONTAINER, "workspace-123").fetch(request);
	},
};

Container クラスは DurableObject を継承するため、SQLite ストレージアラームRPC メソッド を含む Durable Object の機能をすべて使えます。コンテナのディスクはデフォルトでエフェメラルですが、Durable Object のストレージはコンテナの再起動をまたいで残ります。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async runAndPersist() {
		const res = await this.containerFetch("/run-task");
		const body = await res.text();
		this.ctx.storage.sql.exec(
			"INSERT OR REPLACE INTO results (value) VALUES (?)",
			body,
		);
		return body;
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async runAndPersist() {
		const res = await this.containerFetch("/run-task");
		const body = await res.text();
		this.ctx.storage.sql.exec(
			"INSERT OR REPLACE INTO results (value) VALUES (?)",
			body,
		);
		return body;
	}
}

コマンドの実行

稼働中の Container 内で別のプロセスを起動するには、this.ctx.container.exec() を使います。起動、ストリーミング、出力、プロセス制御の例は コマンドの実行 を参照してください。

プロパティ

これらはサブクラスのクラスフィールドとして設定します。そのコンテナのすべてのインスタンスに適用されます。

  • defaultPort (number、省略可) — コンテナプロセスがリッスンするポートです。fetch()containerFetch() は、switchPort() または containerFetch()port 引数で別のポートを指定しない限り、ここにリクエストを転送します。ほとんどのサブクラスで設定します。

  • requiredPorts (number[]、省略可) — コンテナを準備完了とみなす前に、接続を受け付ける必要があるポートです。ports 引数を渡さないときの startAndWaitForPorts() で使います。コンテナが複数のサービスを実行し、トラフィックを扱う前にすべてが健全である必要がある場合に設定します。

  • sleepAfter (string | number、デフォルト: "10m") — アクティビティがないときに、コンテナをシャットダウンするまでの生存時間です。秒数、または "30s""5m""1h" などの期間文字列を受け付けます。アクティビティがあるとタイマーはリセットされます。手動リセットは renewActivityTimeout() を参照してください。

  • envVars (Record<string, string>、デフォルト: {}) — 起動のたびにコンテナへ渡す環境変数です。インスタンス単位の変数は、代わりに startAndWaitForPorts() 経由で envVars を渡します。

  • entrypoint (string[]、省略可) — イメージのデフォルトエントリポイントを上書きします。開発サーバーやワンオフタスクなど、イメージを再ビルドせずに別のコマンドを実行したいときに便利です。

  • enableInternet (boolean、デフォルト: true) — コンテナが送信 HTTP リクエストを出せるかどうかを制御します。送信トラフィックをすべて傍受またはブロックしたいサンドボックス環境では false にします。詳細は 送信トラフィックを処理する を参照してください。

  • pingEndpoint (string、デフォルト: "ping") — 起動中にクラスがコンテナのヘルスチェックに使うホストとパスです。ほとんどのユーザーは変更する必要はありません。

ライフサイクルフック

コンテナの状態が変わったときに Worker のコードを実行するには、これらのメソッドをオーバーライドします。完全な例は ステータスフックの例 を参照してください。

onStart

コンテナが起動したあとで Worker のコードを実行します。

onStart(): void | Promise<void>

戻り値: void | Promise<void>。起動ロジックが終わったら resolve します。

起動のログ記録、データの投入、schedule() による定期タスクのスケジュールに使います。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async onStart() {
		await this.containerFetch("http://localhost/bootstrap", {
			method: "POST",
		});
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    override async onStart() {
    	await this.containerFetch("http://localhost/bootstrap", {
    		method: "POST",
    	});
    }

}

onStop

コンテナプロセスが終了したあとで Worker のコードを実行します。

onStop(params: StopParams): void | Promise<void>

パラメーター:

  • params.exitCode - コンテナプロセスの終了コードです。
  • params.reason - コンテナが停止した理由です。プロセスが自ら終了した場合は 'exit'、ランタイムがシグナルを送った場合は 'runtime_signal' です。

戻り値: void | Promise<void>。シャットダウンロジックが終わったら resolve します。

ログ記録、アラート、コンテナの再起動に使います。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	onStop({ exitCode, reason }) {
		console.log("Container stopped", { exitCode, reason });
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	override onStop({ exitCode, reason }) {
		console.log("Container stopped", { exitCode, reason });
	}
}

onError

起動時とポートチェック時のエラーを処理します。

onError(error: unknown): any

パラメーター:

  • error - 起動時またはポートチェック中に投げられたエラーです。

戻り値: any。デフォルト実装はエラーをログに書き、再スローします。

エラーを抑制する、外部サービスに通知する、再起動を試みる、といった用途でオーバーライドします。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	onError(error) {
		console.error("Container failed to start", error);
		throw error;
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	override onError(error: unknown) {
		console.error("Container failed to start", error);
		throw error;
	}
}

onActivityExpired

sleepAfter タイマーが期限切れになったときに Worker のコードを実行します。

onActivityExpired(): Promise<void>

戻り値: Promise<void>。アイドル時のロジックが終わったら resolve します。

受信リクエストがないまま sleepAfter タイムアウトが切れたときに呼ばれます。デフォルト実装は stop() を呼び出します。

このメソッドをオーバーライドしてコンテナを停止しない場合、タイマーは更新され、次の期限切れでフックが再び発火します。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	sleepAfter = "2m";

	async onActivityExpired() {
		const state = await this.getState();
		console.log("Container is idle, stopping it now", state.status);

		await this.stop();
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	sleepAfter = "2m";

    override async onActivityExpired() {
    	const state = await this.getState();
    	console.log("Container is idle, stopping it now", state.status);

    	await this.stop();
    }

}

リクエストメソッド

fetch

受信した HTTP または WebSocket リクエストを処理します。

fetch(request: Request): Promise<Response>

パラメーター:

  • request - コンテナへプロキシする受信リクエストです。

戻り値: コンテナ、またはカスタムルーティングロジックからの Promise<Response> です。

デフォルトでは、fetch はリクエストを defaultPort のコンテナプロセスへ転送します。コンテナがまだ動いていなければ、自動で起動します。

ルーティング、認証、その他のミドルウェアをコンテナへ転送する前に入れたいときは、fetch をオーバーライドします。オーバーライド内では無限再帰を避けるため、this.fetch() ではなく this.containerFetch() を呼び出してください。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async fetch(request) {
		const url = new URL(request.url);

		if (url.pathname === "/health") {
			return new Response("ok");
		}

		return this.containerFetch(request);
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    override async fetch(request: Request): Promise<Response> {
    	const url = new URL(request.url);

    	if (url.pathname === "/health") {
    		return new Response("ok");
    	}

    	return this.containerFetch(request);
    }

}

WebSocket のプロキシに対応しているのは fetch だけです。完全な例は WebSocket の例 を参照してください。

containerFetch

コンテナプロセスへ HTTP リクエストを直接送ります。通常は、fetch がオーバーライドされていない限り、fetch の使用を推奨します。

containerFetch(request: Request, port?: number): Promise<Response>
containerFetch(url: string | URL, init?: RequestInit, port?: number): Promise<Response>

パラメーター:

  • request - 転送する既存の Request オブジェクトです。
  • url - 新しいリクエストを組み立てるときのリクエスト先 URL です。
  • init - URL ベースのオーバーロード向けの標準 RequestInit オプションです。
  • port - 省略可能なターゲットポートです。省略時はクラスが defaultPort を使います。

戻り値: コンテナからの Promise<Response> です。

これはデフォルトの fetch() 実装が内部で呼び出すメソッドであり、無限再帰を避けるためにオーバーライドした fetch() からも呼び出すべきメソッドです。既存リクエストの転送ではなく新しいリクエストを組み立てるときに便利な、URL 文字列と RequestInit を取る標準の fetch 形式シグネチャも受け付けます。

WebSocket には対応していません。その場合は switchPort() とあわせて fetch() を使います。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async fetch(request) {
		const url = new URL(request.url);

		if (url.pathname === "/metrics") {
			return this.containerFetch(
				"http://localhost/internal/metrics",
				{
					headers: {
						authorization: request.headers.get("authorization") ?? "",
					},
				},
				9090,
			);
		}

		return this.containerFetch(request);
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    override async fetch(request: Request): Promise<Response> {
    	const url = new URL(request.url);

    	if (url.pathname === "/metrics") {
    		return this.containerFetch(
    			"http://localhost/internal/metrics",
    			{
    				headers: {
    					authorization: request.headers.get("authorization") ?? "",
    				},
    			},
    			9090,
    		);
    	}

    	return this.containerFetch(request);
    }

}

起動と停止

ほとんどの場合、これらのメソッドを直接呼ぶ必要はありません。fetch()containerFetch() がコンテナを自動で起動します。コンテナを事前ウォームする、スケジュールでタスクを実行する、ライフサイクルフック内からライフサイクルを制御する、といったときに明示的に呼び出します。

startAndWaitForPorts

コンテナを起動し、対象ポートが接続を受け付けるまで待ちます。

startAndWaitForPorts(args?: StartAndWaitForPortsOptions): Promise<void>
startAndWaitForPorts(
  ports?: number | number[],
  cancellationOptions?: CancellationOptions,
  startOptions?: ContainerStartConfigOptions,
): Promise<void>

パラメーター:

  • args.ports - 待つポート、またはポートの配列です。ポートの解決順は、明示的な ports、次に requiredPorts、次に defaultPort です。
  • args.startOptions - インスタンス単位の起動時オーバーライドです。
  • args.startOptions.envVars - インスタンス単位の環境変数です。
  • args.startOptions.entrypoint - この起動だけに適用するエントリポイントの上書きです。
  • args.startOptions.enableInternet - この起動で送信インターネットアクセスを許可するかどうかです。
  • args.cancellationOptions.abort - 起動をキャンセルする Abort シグナルです。
  • args.cancellationOptions.instanceGetTimeoutMS - コンテナインスタンスを取得し、起動コマンドを発行するまでの最大時間です。デフォルト: 8000
  • args.cancellationOptions.portReadyTimeoutMS - すべてのポートが準備完了になるまでの最大時間です。デフォルト: 20000
  • args.cancellationOptions.waitInterval - ミリ秒単位のポーリング間隔です。デフォルト: 300

戻り値: Promise<void>。対象ポートの準備が整い、onStart() が実行されたあとに resolve します。

トラフィックを送る前にコンテナの準備完了を確実にしたいときに、明示的に起動するいちばん安全な方法です。

このメソッドは位置引数の portscancellationOptionsstartOptions にも対応しますが、オブジェクト形式のほうが読みやすいです。

import { getContainer } from "@cloudflare/containers";

export default {
	async scheduled(_event, env) {
		const container = getContainer(env.API_CONTAINER, "tenant-42");

		await container.startAndWaitForPorts({
			ports: [8080, 9222],
			startOptions: {
				envVars: {
					API_KEY: env.API_KEY,
					TENANT_ID: "tenant-42",
				},
			},
			cancellationOptions: {
				portReadyTimeoutMS: 30_000,
			},
		});
	},
};
import { getContainer } from "@cloudflare/containers";

export default {
	async scheduled(_event, env) {
		const container = getContainer(env.API_CONTAINER, "tenant-42");

    	await container.startAndWaitForPorts({
    		ports: [8080, 9222],
    		startOptions: {
    			envVars: {
    				API_KEY: env.API_KEY,
    				TENANT_ID: "tenant-42",
    			},
    		},
    		cancellationOptions: {
    			portReadyTimeoutMS: 30_000,
    		},
    	});
    },

};

完全な例は 環境変数とシークレットの例 を参照してください。

start

すべてのポートが準備完了になるのを待たずに、コンテナを起動します。

start(startOptions?: ContainerStartConfigOptions, waitOptions?: WaitOptions): Promise<void>

パラメーター:

  • startOptions - インスタンス単位の起動時オーバーライドです。
  • startOptions.envVars - インスタンス単位の環境変数です。
  • startOptions.entrypoint - この起動だけに適用するエントリポイントの上書きです。
  • startOptions.enableInternet - この起動で送信インターネットアクセスを許可するかどうかです。
  • waitOptions.portToCheck - 起動中にプローブするポートです。省略時はクラスが defaultPortrequiredPorts の先頭、またはフォールバックポートを使います。
  • waitOptions.signal - 起動をキャンセルする Abort シグナルです。
  • waitOptions.retries - メソッドが例外を投げるまでの最大起動試行回数です。
  • waitOptions.waitInterval - リトライ間のミリ秒単位のポーリング間隔です。

戻り値: Promise<void>。起動試行が成功し、onStart() が実行されたあとに resolve します。

バッチジョブや cron タスクなど、コンテナがポートを公開しない場合や、waitForPort() で準備完了を自分で管理したいときに使います。すべてのポートの準備完了を待つ必要がある場合は、代わりに startAndWaitForPorts() を使います。

import { getContainer } from "@cloudflare/containers";

export default {
	async scheduled(_event, env) {
		const container = getContainer(env.JOB_CONTAINER, "nightly-report");

		await container.start({
			entrypoint: ["node", "scripts/nightly-report.js"],
			envVars: {
				REPORT_DATE: new Date().toISOString(),
			},
			enableInternet: false,
		});
	},
};
import { getContainer } from "@cloudflare/containers";

export default {
	async scheduled(_event, env) {
		const container = getContainer(env.JOB_CONTAINER, "nightly-report");

    	await container.start({
    		entrypoint: ["node", "scripts/nightly-report.js"],
    		envVars: {
    			REPORT_DATE: new Date().toISOString(),
    		},
    		enableInternet: false,
    	});
    },

};

完全な例は cron の例 を参照してください。

waitForPort

1 つのポートが接続を受け付けるまでポーリングします。

waitForPort(waitOptions: WaitOptions): Promise<number>

パラメーター:

  • waitOptions.portToCheck - 確認するポート番号です。
  • waitOptions.signal - 待機をキャンセルする Abort シグナルです。
  • waitOptions.retries - メソッドが例外を投げるまでの最大リトライ回数です。
  • waitOptions.waitInterval - ミリ秒単位のポーリング間隔です。

戻り値: Promise<number>。数値の戻り値は、複数の待機にまたがるカスタムの準備完了ロジックを調整するときに主に役立ちます。

リトライ上限内にポートが利用可能にならない場合は例外を投げます。start() のあと、複数のポートを独立して、または特定の順序で確認したいときに使います。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	async warmInspector() {
		await this.start();

		const retryCount = await this.waitForPort({
			portToCheck: 9222,
			retries: 20,
			waitInterval: 500,
		});

		console.log("Inspector port became ready:", retryCount);
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	async warmInspector() {
		await this.start();

    	const retryCount = await this.waitForPort({
    		portToCheck: 9222,
    		retries: 20,
    		waitInterval: 500,
    	});

    	console.log("Inspector port became ready:", retryCount);
    }

}

stop

コンテナプロセスへシグナルを送ります。

stop(signal?: 'SIGTERM' | 'SIGINT' | 'SIGKILL' | number): Promise<void>

パラメーター:

  • signal - 送るシグナルです。デフォルトは 'SIGTERM' です。

戻り値: Promise<void>。シグナル送信と、保留中の停止処理が完了したあとに resolve します。

デフォルトは SIGTERM で、プロセスにグレースフルシャットダウンの余地を与えます。onStop() をトリガーします。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async fetch(request) {
		if (new URL(request.url).pathname === "/admin/stop") {
			await this.stop();
			return new Response("Container is stopping");
		}

		return this.containerFetch(request);
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    override async fetch(request: Request): Promise<Response> {
    	if (new URL(request.url).pathname === "/admin/stop") {
    		await this.stop();
    		return new Response("Container is stopping");
    	}

    	return this.containerFetch(request);
    }

}

destroy

コンテナプロセスを直ちに強制終了します。

destroy(): Promise<void>

戻り値: Promise<void>。ランタイムがコンテナを破棄したあとに resolve します。

これは SIGKILL を送ります。グレースフルシャットダウンを待てず、コンテナをすぐに消す必要があるときに使います。onStop() をトリガーします。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async fetch(request) {
		if (new URL(request.url).pathname === "/admin/destroy") {
			await this.destroy();
			return new Response("Container destroyed");
		}

		return this.containerFetch(request);
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    override async fetch(request: Request): Promise<Response> {
    	if (new URL(request.url).pathname === "/admin/destroy") {
    		await this.destroy();
    		return new Response("Container destroyed");
    	}

    	return this.containerFetch(request);
    }

}

状態と監視

getState

現在のコンテナ状態を読み取ります。

getState(): Promise<State>

戻り値: 次を含む Promise<State> です。

  • status - 'running''healthy''stopping''stopped''stopped_with_code' のいずれかです。
  • lastChange - 最後の状態変化の Unix タイムスタンプ(ミリ秒)です。
  • exitCode - status'stopped_with_code' のときの省略可能な終了コードです。

running は、コンテナが起動中で、まだヘルスチェックを通過していない状態です。healthy は稼働中でリクエストを受け付けている状態です。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	async logState() {
		const state = await this.getState();

		if (state.status === "stopped_with_code") {
			console.error("Container exited with code", state.exitCode);
			return;
		}

		console.log("Container status:", state.status);
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	async logState() {
		const state = await this.getState();

    	if (state.status === "stopped_with_code") {
    		console.error("Container exited with code", state.exitCode);
    		return;
    	}

    	console.log("Container status:", state.status);
    }

}

renewActivityTimeout

sleepAfter タイマーをリセットします。

renewActivityTimeout(): void

戻り値: void

受信リクエストはタイマーを自動でリセットします。スケジュールタスクや長時間処理など、アクティビティとして数え、コンテナのスリープを防ぎたいバックグラウンド作業からは、手動で呼び出します。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async processJobs(jobIds) {
		for (const jobId of jobIds) {
			this.renewActivityTimeout();

			await this.containerFetch(`http://localhost/jobs/${jobId}`, {
				method: "POST",
			});
		}
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    async processJobs(jobIds: string[]) {
    	for (const jobId of jobIds) {
    		this.renewActivityTimeout();

    		await this.containerFetch(`http://localhost/jobs/${jobId}`, {
    			method: "POST",
    		});
    	}
    }

}

スケジューリング

schedule

クラス上のメソッドを、あとで実行するようスケジュールします。

schedule<T>(when: Date | number, callback: string, payload?: T): Promise<Schedule<T>>

パラメーター:

  • when - 特定時刻の Date、または遅延する秒数です。
  • callback - 呼び出すクラスメソッドの名前です。
  • payload - コールバックメソッドへ渡す省略可能なデータです。

戻り値: 次を含む Promise<Schedule<T>> です。

  • taskId - 一意のスケジュール ID です。
  • callback - 呼び出されるメソッド名です。
  • payload - コールバックへ渡されるペイロードです。
  • type - 絶対時刻の場合は 'scheduled'、相対遅延の場合は 'delayed' です。
  • time - タスクが実行される Unix タイムスタンプ(秒)です。
  • delayInSeconds - type'delayed' のときの遅延秒数です。

alarm() を直接オーバーライドしないでください。Container クラスはアラームハンドラーでコンテナのライフサイクルを管理するため、代わりに schedule() を使います。

次の例は、コンテナ起動時から定期的なヘルスレポートをスケジュールします。

import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

	async onStart() {
		await this.schedule(60, "healthReport");
	}

	async healthReport() {
		const state = await this.getState();
		console.log("Container status:", state.status);
		await this.schedule(60, "healthReport");
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;

    override async onStart() {
    	await this.schedule(60, "healthReport");
    }

    async healthReport() {
    	const state = await this.getState();
    	console.log("Container status:", state.status);
    	await this.schedule(60, "healthReport");
    }

}

送信の傍受

送信の傍受を使うと、コンテナが外部ホストへ出す HTTP リクエストを傍受、モック、またはブロックできます。サンドボックス、テスト、Worker コード経由での送信トラフィックのプロキシに便利です。

import {
	Container,
	ContainerProxy,
	getContainer,
} from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;
	enableInternet = true;

	static outboundByHost = {
		"blocked.example.com": () => {
			return new Response("Blocked", { status: 403 });
		},
	};

	static outbound = async (request, _env, ctx) => {
		console.log(`[${ctx.containerId}] outbound:`, request.url);
		return fetch(request);
	};
}

export { ContainerProxy };

export default {
	async fetch(request, env) {
		return getContainer(env.MY_CONTAINER).fetch(request);
	},
};
import {
	Container,
	ContainerProxy,
	getContainer,
} from "@cloudflare/containers";

export class MyContainer extends Container {
	defaultPort = 8080;
	enableInternet = true;

    static outboundByHost = {
    	"blocked.example.com": () => {
    		return new Response("Blocked", { status: 403 });
    	},
    };

    static outbound = async (request, _env, ctx) => {
    	console.log(`[${ctx.containerId}] outbound:`, request.url);
    	return fetch(request);
    };

}

export { ContainerProxy };

export default {
	async fetch(request: Request, env) {
		return getContainer(env.MY_CONTAINER).fetch(request);
	},
};

詳細は 送信トラフィックを処理する を参照してください。

ユーティリティ関数

これらの関数は、@cloudflare/containers から Container クラスと一緒にエクスポートされます。

getContainer

名前付きコンテナインスタンスのスタブを取得します。

getContainer<T>(binding: DurableObjectNamespace<T>, name?: string): DurableObjectStub<T>

パラメーター:

  • binding - コンテナクラス向けの Durable Object 名前空間バインディングです。
  • name - 安定したインスタンス名です。デフォルトは cf-singleton-container です。

戻り値: 名前付きコンテナインスタンスの DurableObjectStub<T> です。

ユーザーセッション、ドキュメント、ゲームルームなど、安定した名前で識別する論理エンティティごとに 1 つのコンテナが欲しいときに使います。

import { getContainer } from "@cloudflare/containers";

export default {
	async fetch(request, env) {
		const { sessionId } = await request.json();
		return getContainer(env.MY_CONTAINER, sessionId).fetch(request);
	},
};
import { getContainer } from "@cloudflare/containers";

export default {
	async fetch(request: Request, env) {
		const { sessionId } = await request.json();
		return getContainer(env.MY_CONTAINER, sessionId).fetch(request);
	},
};

getRandom

ランダムに選んだコンテナインスタンスのスタブを取得します。

getRandom<T>(binding: DurableObjectNamespace<T>, instances?: number): Promise<DurableObjectStub<T>>

パラメーター:

  • binding - コンテナクラス向けの Durable Object 名前空間バインディングです。
  • instances - 選択対象のインスタンス総数です。デフォルトは 3 です。

戻り値: ランダムに選ばれたインスタンスの Promise<DurableObjectStub<T>> です。

どのコンテナでもどのリクエストを扱えるステートレスなワークロードで、複数インスタンスに負荷を分散したいときに使います。

import { getRandom } from "@cloudflare/containers";

export default {
	async fetch(request, env) {
		const container = await getRandom(env.WORKER_POOL, 5);
		return container.fetch(request);
	},
};
import { getRandom } from "@cloudflare/containers";

export default {
	async fetch(request: Request, env) {
		const container = await getRandom(env.WORKER_POOL, 5);
		return container.fetch(request);
	},
};

完全な例は ステートレスインスタンスの例 を参照してください。

switchPort

fetch() を使いながら、別のコンテナポートをターゲットにします。

switchPort(request: Request, port: number): Request

パラメーター:

  • request - コピーするリクエストです。
  • port - リクエストヘッダーへエンコードするポートです。

戻り値: ターゲットポートを設定した Request のコピーです。

特定のポートをターゲットにし、かつ WebSocket サポートも必要なときに使います。WebSocket が不要なら、代わりに containerFetch() へポートを直接渡します。

import { getContainer, switchPort } from "@cloudflare/containers";

export default {
	async fetch(request, env) {
		const container = getContainer(env.MY_CONTAINER);
		return container.fetch(switchPort(request, 9090));
	},
};
import { getContainer, switchPort } from "@cloudflare/containers";

export default {
	async fetch(request: Request, env) {
		const container = getContainer(env.MY_CONTAINER);
		return container.fetch(switchPort(request, 9090));
	},
};

役に立ちましたか?