INTEGRITY Документация

Durable Object Container

Описание

Каждый контейнер управляется Durable Object. Container класс от @cloudflare/containers расширяет DurableObject и берёт на себя управление жизненным циклом, готовность портов и тайм-ауты перехода в спящий режим. Durable Object управляет маршрутизацией, постоянным состоянием и хуками жизненного цикла, а процесс контейнера запускает ваш образ внутри Linux VM.

Низкоуровневый API, описанный на этой странице, доступен в this.ctx.container внутри любого класса Durable Object, у которого есть привязка container. Используйте его, если вам нужен непосредственный контроль над процессом контейнера или вы не можете использовать Container в качестве класса.

Поскольку Container класс расширяет DurableObject, у вас также есть доступ к Хранилище SQLite через this.ctx.storage, alarms, и всех остальных API Durable Objects.

index.js
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.ts
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"],
});

Параметры

Возвращаемые значения

exec

exec запускает ещё один процесс внутри уже работающего Container. Он не запускает остановленный Container.

В следующем примере вызывается this.ctx.container.exec() внутри класса, расширяющего Container от @cloudflare/containers. В RPC-методах проверяйте this.ctx.container.running и вызвать await this.start() при необходимости. Также можно использовать onStart()-хук для выполнения любой последовательности команд при каждом запуске Container.

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

exec операция запускает исполняемый файл напрямую с переданными аргументами. Она не запускает оболочку и не интерпретирует конвейеры, перенаправления, подстановки и другой синтаксис оболочки. Чтобы явно вызвать Bash, используйте ["bash", "-lc", "<COMMAND>"] когда в образе есть Bash. Используйте ["sh", "-c", "<COMMAND>"] для образов, в которых есть только POSIX-совместимая оболочка (Portable Operating System Interface).

Следующий метод 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),
		};
	}
}

Параметры

Возвращаемые значения

Возвращает Promise<ExecProcess>.

Одна ExecProcess содержит следующие поля и методы:

С stderr: "combined", stderr это null на ExecProcess и пустой ArrayBuffer на ExecOutput. Считывайте оба канала вывода из stdout.

output() выбрасывает TypeError при вызове более одного раза или после того, как один из потоков чтения уже начал считываться. Для больших объёмов данных считывайте оба потока чтения параллельно, вместо буферизации их с помощью output().

exec не имеет встроенного тайм-аута. Используйте kill() чтобы запросить завершение работы, а затем отслеживать его через exitCode. Процесс может обработать сигнал или проигнорировать его, поэтому это не гарантирует жёсткий дедлайн. Не делайте выводов о конкретном коде завершения на основании сигнала.

Исключения

Примеры для конкретных задач см. в Выполнять команды.

destroy

destroy останавливает контейнер и, при необходимости, возвращает пользовательское сообщение об ошибке в monitor() колбэк ошибки.

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

Параметры

Возвращаемые значения

signal

signal отправляет контейнеру IPC-сигнал, например SIGKILL или SIGTERM. Это удобно для корректной или принудительной остановки контейнера.

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

Параметры

Возвращаемые значения

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 });
}

Параметры

Возвращаемые значения

monitor

monitor возвращает промис, который разрешается при завершении работы контейнера и отклоняется при возникновении ошибки контейнера. Это удобно для настройки колбэков, обрабатывающих изменения статуса контейнера в коде 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);
	}
}

Параметры

Возвращаемые значения

interceptOutboundHttp

interceptOutboundHttp перенаправляет исходящие HTTP-запросы, соответствующие имени хоста, шаблону имени хоста, IP-адресу, комбинации IP:port или диапазону CIDR, через 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);

Параметры

Возвращаемые значения

interceptAllOutboundHttp

interceptAllOutboundHttp перенаправляет все исходящие HTTP-запросы контейнера через WorkerEntrypoint, независимо от назначения.

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

Параметры

Возвращаемые значения

interceptOutboundHttps

interceptOutboundHttps перенаправляет исходящие HTTPS-запросы, соответствующие имени хоста или шаблону имени хоста, через WorkerEntrypoint. Работает так же, как interceptOutboundHttp но для трафика HTTPS. Контейнер должен доверять сертификату CA по адресу /etc/cloudflare/certs/cloudflare-containers-ca.crt чтобы перехват HTTPS работал.

Поддерживает шаблоны glob, где * соответствует любой последовательности символов.

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);

Параметры

Возвращаемые значения