Skip to content

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

Durable Object Container

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

説明

コンテナ は Durable Object が管理します。@cloudflare/containersContainer クラスDurableObject を拡張し、ライフサイクル管理、ポートの準備完了、スリープタイムアウトを代わりに処理します。Durable Object がルーティング、永続状態、ライフサイクルフックを管理し、コンテナプロセスは Linux VM 内でイメージを実行します。

このページで説明する低レベル API は、コンテナバインディングを持つ任意の Durable Object クラス内の this.ctx.container で使えます。コンテナプロセスを直接制御したい場合や、Container クラスを使えない場合に使います。

Container クラスは DurableObject を拡張するため、this.ctx.storage 経由の SQLite ストレージAlarms、そのほかすべての Durable Object API にもアクセスできます。

index.jsjs
export class MyDurableObject extends DurableObject {
	constructor(ctx, env) {
		super(ctx, env);

		// boot the container when starting the DO
		this.ctx.blockConcurrencyWhile(async () => {
			this.ctx.container.start();
		});
	}
}
index.tsts
export class MyDurableObject extends DurableObject {
	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env);

    	// boot the container when starting the DO
    	this.ctx.blockConcurrencyWhile(async () => {
    		this.ctx.container.start();
    });
    }

}

属性

running

running は、コンテナが現在実行中なら true を返します。コンテナが完全に起動し、リクエストを受け付けられる状態であることまでは保証しません。

	this.ctx.container.running;

メソッド

start

start はコンテナを起動します。このメソッドは、コンテナが完全に起動するまでブロックしません。 使う前に、コンテナがリクエストを受け付けられる状態かを確認するとよいです。

this.ctx.container.start({
	env: {
		FOO: "bar",
	},
	enableInternet: false,
	entrypoint: ["node", "server.js"],
});

パラメーター

  • options(任意): 次のプロパティを持つオブジェクトです。
    • env: コンテナへ渡す環境変数を含むオブジェクトです。設定値やシークレットをコンテナへ渡すときに使います。
    • entrypoint: コンテナ内で実行するコマンドを表す文字列の配列です。
    • enableInternet: コンテナのインターネットアクセスを有効にするかどうかを示す boolean です。

戻り値

  • なし。

exec

exec は、すでに実行中の Container 内で別プロセスを開始します。停止中の Container は起動しません。

次の例は、@cloudflare/containersContainer を拡張したクラス内で this.ctx.container.exec() を呼び出します。RPC メソッドでは this.ctx.container.running を確認し、必要なら await this.start() を呼び出します。Container が起動するたびに一連のコマンドを実行するには、onStart() フックも使えます。

exec(
  cmd: string[],
  options?: ContainerExecOptions,
): Promise<ExecProcess>

exec 操作は、渡した引数で実行ファイルを直接開始します。シェルは起動せず、パイプ、リダイレクト、展開、そのほかのシェル構文も解釈しません。イメージに Bash がある場合は、["bash", "-lc", "<COMMAND>"] で明示的に Bash を呼び出します。Portable Operating System Interface(POSIX)シェルだけのイメージでは ["sh", "-c", "<COMMAND>"] を使います。

次の RPC メソッドは、コマンドを実行する前に Container を起動します。

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

export class MyContainer extends Container {
	async runCommand() {
		if (!this.ctx.container.running) {
			await this.start();
		}

		const process = await this.ctx.container.exec(["node", "--version"]);
		const output = await process.output();

		return {
			pid: process.pid,
			exitCode: output.exitCode,
			stdout: new TextDecoder().decode(output.stdout),
		};
	}
}
import { Container } from "@cloudflare/containers";

export class MyContainer extends Container {
	async runCommand() {
		if (!this.ctx.container.running) {
			await this.start();
		}

		const process = await this.ctx.container.exec(["node", "--version"]);
		const output = await process.output();

		return {
			pid: process.pid,
			exitCode: output.exitCode,
			stdout: new TextDecoder().decode(output.stdout),
		};
	}
}

パラメーター

  • cmdstring[])— 実行ファイルとその引数です。
  • optionsContainerExecOptions、任意)— プロセスの設定です。
    • stdinReadableStream | "pipe")— 標準入力のソースです。返される stdin ストリーム経由で書き込むには "pipe" を使います。省略すると、標準入力は閉じて EOF(end-of-file)を送ります。
    • stdout"pipe" | "ignore"、既定は "pipe")— 標準出力をキャプチャするか破棄します。
    • stderr"pipe" | "ignore" | "combined"、既定は "pipe")— 標準エラーをキャプチャ、破棄、または標準出力へマージします。"combined" には stdout: "pipe" が必要です。結合した出力は、元ストリーム間の順序を保証しません。
    • cwdstring)— プロセスの作業ディレクトリです。
    • envRecord<string, string>)— 環境変数の追加と上書きです。プロセスは既存の Container 変数を継承します。同じキーは実行ごとの値を使います。
    • userstring)— プロセスに使うイメージユーザーです。

戻り値

Promise<ExecProcess> を返します。

ExecProcess には次のフィールドとメソッドがあります。

  • stdinWritableStream | null)— stdin"pipe" のときの書き込み可能な標準入力です。
  • stdoutReadableStream | null)— パイプしているときの読み取り可能な標準出力です。
  • stderrReadableStream | null)— 別途パイプしているときの読み取り可能な標準エラーです。
  • pidnumber)— プロセス識別子です。
  • exitCodePromise<number>)— プロセス終了時に解決します。ゼロ以外のコードも reject せず、通常どおり解決します。
  • output()Promise<ExecOutput>)— バッファした出力を一度読みます。ExecOutput には stdoutArrayBuffer)、stderrArrayBuffer)、exitCodenumber)が含まれます。無視したストリームは空のバッファになります。テキストへデコードするには TextDecoder を使います。
  • kill(signal?: number)void)— プロセスへシグナルをキューします。既定は SIGTERM(シグナル 15)です。シグナルは 1 から 64 である必要があります。

stderr: "combined" のとき、ExecProcessstderrnullExecOutput では空の ArrayBuffer です。両方の出力チャネルは stdout から読みます。

output() を 2 回以上呼ぶか、いずれかの読み取りストリームの消費を始めたあとに呼ぶと、TypeError を投げます。大きな出力では、output() でバッファせず、両方の読み取りストリームを同時に消費してください。

exec に組み込みのタイムアウトはありません。終了を依頼するには kill() を使い、完了は exitCode で確認します。プロセスはシグナルを処理または無視できるため、これは厳しい期限にはなりません。シグナルから特定の終了コードを推測しないでください。

例外

  • Container が実行中でないとき、exec() は例外を投げます。
  • cmd が空、オプションのモードが無効、または stderr: "combined"stdout: "ignore" と組み合わせたとき、exec()TypeError を投げます。
  • ランタイムがプロセスを作成または開始できない場合、exec() は reject します。
  • 環境変数名に = またはヌル文字は使えません。環境変数の値、cwduser にヌル文字は使えません。
  • シグナルが対応範囲外のとき、kill()RangeError を投げます。

作業向けの例は コマンドを実行する を参照してください。

destroy

destroy はコンテナを停止し、任意で monitor() のエラーコールバックへカスタムエラーメッセージを返します。

this.ctx.container.destroy("Manually Destroyed");

パラメーター

  • error(任意): monitor メソッドのエラーハンドラーへ送る文字列です。ログやデバッグに使えます。

戻り値

  • コンテナが破棄されたときに解決する Promise です。

signal

signal はコンテナへ IPC シグナル(SIGKILL や SIGTERM など)を送ります。コンテナを穏やかに、または強制的に止めるときに使います。

const SIGTERM = 15;
this.ctx.container.signal(SIGTERM);

パラメーター

  • signal: コンテナへ送るシグナルを表す数値です。通常は POSIX シグナル番号で、SIGTERM(15)や SIGKILL(9)などです。

戻り値

  • なし。

getTcpPort

getTcpPort はコンテナの TCP ポートを返します。TCP と HTTP でコンテナと通信できます。

const port = this.ctx.container.getTcpPort(8080);
const res = await port.fetch("http://container/set-state", {
	body: initialState,
	method: "POST",
});
const conn = this.ctx.container.getTcpPort(8080).connect("10.0.0.1:8080");
await conn.opened;

try {
	if (request.body) {
		await request.body.pipeTo(conn.writable);
	}
	return new Response(conn.readable);
} catch (err) {
	console.error("Request body piping failed:", err);
	return new Response("Failed to proxy request body", { status: 502 });
}

パラメーター

  • port(number): コンテナとの通信に使う TCP ポート番号です。

戻り値

  • TcpPort: TCP ポートを表す TcpPort オブジェクトです。TCP と HTTP でコンテナへリクエストを送れます。

monitor

monitor は、コンテナが終了すると解決し、コンテナがエラーになるとエラーになる Promise を返します。Workers コードでコンテナの状態変化を扱うコールバックを設定するときに使えます。

class MyContainer extends DurableObject {
	constructor(ctx, env) {
		super(ctx, env);
		function onContainerExit() {
			console.log("Container exited");
		}

		// the "err" value can be customized by the destroy() method
		async function onContainerError(err) {
			console.log("Container errored", err);
		}

		this.ctx.container.start();
		this.ctx.container.monitor().then(onContainerExit).catch(onContainerError);
	}
}

パラメーター

  • なし

戻り値

  • コンテナが終了したときに解決する Promise です。

interceptOutboundHttp

interceptOutboundHttp は、ホスト名、ホスト名グロブ、IP アドレス、IP:ポート、または CIDR 範囲に一致する送信 HTTP リクエストを WorkerEntrypoint 経由でルーティングします。コンテナの起動前でも起動後でも呼び出せます。開いている接続は切られず、新しいハンドラーを取り込みます。

const worker = this.ctx.exports.MyWorker({ props: { message: "hello" } });

// Match a specific hostname
this.ctx.container.interceptOutboundHttp("api.example.com", worker);

// Match a hostname glob pattern
this.ctx.container.interceptOutboundHttp("*.example.com", worker);

// Match an IP:port
await this.ctx.container.interceptOutboundHttp("15.0.0.1:80", worker);

// Match a CIDR range (IPv4 and IPv6)
await this.ctx.container.interceptOutboundHttp("123.123.123.123/23", worker);

パラメーター

  • target(string): 照合するホスト名、ホスト名グロブ(例: *.example.com)、IP アドレス、IP:ポート、または CIDR 範囲です。
  • worker(WorkerEntrypoint): 一致するリクエストを処理する WorkerEntrypoint インスタンスです。

戻り値

  • なし。

interceptAllOutboundHttp

interceptAllOutboundHttp は、宛先に関係なく、コンテナからの送信 HTTP リクエストをすべて WorkerEntrypoint 経由でルーティングします。

await this.ctx.container.interceptAllOutboundHttp(worker);

パラメーター

  • worker(WorkerEntrypoint): すべての送信 HTTP リクエストを処理する WorkerEntrypoint インスタンスです。

戻り値

  • インターセプトルールがインストールされたときに解決する Promise です。

interceptOutboundHttps

interceptOutboundHttps は、ホスト名またはホスト名グロブに一致する送信 HTTPS リクエストを WorkerEntrypoint 経由でルーティングします。動作は interceptOutboundHttp と同じで、対象は HTTPS トラフィックです。HTTPS インターセプトを動かすには、コンテナが /etc/cloudflare/certs/cloudflare-containers-ca.crt の CA 証明書を信頼する必要があります。

グロブパターンに対応しており、* は任意の文字シーケンスに一致します。

const worker = this.ctx.exports.MyWorker({ props: {} });

// Match a specific hostname
this.ctx.container.interceptOutboundHttps("api.example.com", worker);

// Match a hostname glob pattern
this.ctx.container.interceptOutboundHttps("*.example.com", worker);

// Intercept all HTTPS traffic
this.ctx.container.interceptOutboundHttps("*", worker);

パラメーター

  • target(string): 照合するホスト名またはホスト名グロブパターンです。すべての HTTPS トラフィックをインターセプトするには * を使います。
  • worker(WorkerEntrypoint): 一致するリクエストを処理する WorkerEntrypoint インスタンスです。

戻り値

  • なし。

関連リソース

役に立ちましたか?