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

Резервные копии

Создавайте моментальные снимки каталогов песочницы на определённый момент времени и восстанавливайте их с помощью оверлеев copy-on-write.

Методы

createBackup()

Создаёт моментальный снимок каталога на определённый момент времени и загружает его в хранилище R2.

await sandbox.createBackup(options: BackupOptions): Promise<DirectoryBackup>

Параметры:

Возвращает: Promise<DirectoryBackup> содержащий:

import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

// Create a backup of /workspace
const backup = await sandbox.createBackup({ dir: "/workspace" });

// Later, restore the backup
await sandbox.restoreBackup(backup);
import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

// Create a backup of /workspace
const backup = await sandbox.createBackup({ dir: "/workspace" });

// Later, restore the backup
await sandbox.restoreBackup(backup);

Как это работает:

В продакшене:

  1. Контейнер создаёт из каталога сжатый архив squashfs.
  2. Контейнер загружает архив напрямую в R2 по предварительно подписанному URL.
  3. Метаданные хранятся вместе с архивом в R2.
  4. Локальный архив удаляется.

С localBucket: true (локальная разработка):

  1. Контейнер создаёт из каталога сжатый архив squashfs.
  2. Архив загружается напрямую в BACKUP_BUCKET привязка R2.
  3. Метаданные хранятся вместе с архивом в R2.
  4. Локальный архив удаляется.

Исключения:


restoreBackup()

Восстанавливает ранее созданную резервную копию в указанный каталог.

await sandbox.restoreBackup(backup: DirectoryBackup): Promise<RestoreBackupResult>

Параметры:

Возвращает: Promise<RestoreBackupResult> содержащий:

// Create a named backup with 24-hour TTL
const backup = await sandbox.createBackup({
	dir: "/workspace",
	name: "before-refactor",
	ttl: 86400,
});

// Store the handle for later use
await env.KV.put(`backup:${userId}`, JSON.stringify(backup));
// Create a named backup with 24-hour TTL
const backup = await sandbox.createBackup({
	dir: "/workspace",
	name: "before-refactor",
	ttl: 86400,
});

// Store the handle for later use
await env.KV.put(`backup:${userId}`, JSON.stringify(backup));

Как это работает:

В продакшене:

  1. Метаданные загружаются из R2, после чего проверяется TTL. Если срок истёк, выбрасывается ошибка (с запасом в 60 секунд).
  2. Контейнер загружает архив напрямую из R2 по предварительно подписанному URL.
  3. Контейнер монтирует архив squashfs с помощью FUSE overlayfs.

С localBucket: true (локальная разработка):

  1. Метаданные загружаются из BACKUP_BUCKET привязка R2, и проверяется TTL.
  2. Архив загружается из привязки R2.
  3. Архив распаковывается в целевой каталог с помощью unsquashfs.

Исключения:

Сценарии использования

Исключение файлов из .gitignore

Используйте useGitignore чтобы исключить файлы, соответствующие .gitignore правила (например, node_modules/ или dist/) из резервной копии. Это уменьшает размер резервной копии для git-репозиториев.

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

// Exclude gitignored files from the backup
const backup = await sandbox.createBackup({
	dir: "/workspace",
	useGitignore: true,
});

// Without useGitignore (default), all files are included
const fullBackup = await sandbox.createBackup({
	dir: "/workspace",
});
const sandbox = getSandbox(env.Sandbox, "my-sandbox");

// Exclude gitignored files from the backup
const backup = await sandbox.createBackup({
	dir: "/workspace",
	useGitignore: true,
});

// Without useGitignore (default), all files are included
const fullBackup = await sandbox.createBackup({
	dir: "/workspace",
});

Если каталог находится не внутри git-репозитория, useGitignore не действует, и включаются все файлы. Если useGitignore это true но git не установлен в контейнере, BackupCreateError выбрасывается.

Контрольные точки и восстановление

Используйте резервные копии в качестве контрольных точек перед рискованными операциями.

// Save checkpoint before risky operation
const checkpoint = await sandbox.createBackup({ dir: "/workspace" });

try {
	await sandbox.exec("npm install some-experimental-package");
	await sandbox.exec("npm run build");
} catch (error) {
	// Restore to the checkpoint if something goes wrong
	await sandbox.restoreBackup(checkpoint);
}
// Save checkpoint before risky operation
const checkpoint = await sandbox.createBackup({ dir: "/workspace" });

try {
	await sandbox.exec("npm install some-experimental-package");
	await sandbox.exec("npm run build");
} catch (error) {
	// Restore to the checkpoint if something goes wrong
	await sandbox.restoreBackup(checkpoint);
}

Обработка ошибок

import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

try {
	const backup = await sandbox.createBackup({ dir: "/workspace" });
	console.log(`Backup created: ${backup.id}`);
} catch (error) {
	if (error.code === "INVALID_BACKUP_CONFIG") {
		console.error("Configuration error:", error.message);
	} else if (error.code === "BACKUP_CREATE_FAILED") {
		console.error("Backup failed:", error.message);
	}
}
import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

try {
	const backup = await sandbox.createBackup({ dir: "/workspace" });
	console.log(`Backup created: ${backup.id}`);
} catch (error) {
	if (error.code === "INVALID_BACKUP_CONFIG") {
		console.error("Configuration error:", error.message);
	} else if (error.code === "BACKUP_CREATE_FAILED") {
		console.error("Backup failed:", error.message);
	}
}

Поведение

Применение TTL

ttl значение управляет тем, когда резервная копия считается устаревшей. SDK применяет это правило на только время восстановления : при вызове restoreBackup(), SDK считывает метаданные резервной копии из R2 и проверяет, истек ли TTL. Если истек, восстановление отклоняется с ошибкой BACKUP_EXPIRED ошибка.

TTL не автоматически не удаляет объекты из R2. Архивы резервных копий с истёкшим сроком и метаданные остаются в вашем R2 bucket, пока вы их не удалите. Чтобы автоматически очищать объекты с истёкшим сроком, настройте Правило жизненного цикла объекта R2 для вашего бакета резервных копий. Без правила жизненного цикла истёкшие резервные копии продолжают занимать место в хранилище R2.

Типы

BackupOptions

interface BackupOptions {
	dir: string;
	name?: string;
	ttl?: number;
	useGitignore?: boolean;
	localBucket?: boolean;
}

Поля:

DirectoryBackup

interface DirectoryBackup {
	readonly id: string;
	readonly dir: string;
}

Поля:

RestoreBackupResult

interface RestoreBackupResult {
	success: boolean;
	dir: string;
	id: string;
}

Поля: