← Sandbox SDK / sandbox / guides
Připojení bucketů
Připojte buckety objektového úložiště kompatibilního s S3 jako cesty v lokálním souborovém systému. K objektovému úložišti přistupujte pomocí standardních souborových operací. U Cloudflare R2 v produkčním prostředí můžete bucket připojit také podle názvu vazby R2 workeru, takže přihlašovací údaje zůstanou uvnitř runtime workeru.
Produkční předpoklady pro mounty R2 bindingu
Chcete-li v produkci připojit R2 bucket bez předávání přihlašovacích údajů do kontejneru, přidejte vazbu R2 a exportujte ContainerProxy z entrypointu vašeho Workeru.
{
"$schema": "./node_modules/wrangler/config-schema.json",
"r2_buckets": [
{
"binding": "MY_BUCKET",
"bucket_name": "my-r2-bucket"
}
]
}[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-r2-bucket"import { ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };import { ContainerProxy } from "@cloudflare/sandbox";
export { ContainerProxy };Když vynecháte endpoint, první argument metody mountBucket() musí být název vazby R2 ve Workeru, například MY_BUCKET.
Kdy připojovat buckety
Buckety kompatibilní s S3 připojte, když potřebujete:
- Trvalá data - Data přežijí zničení sandboxu
- Velké datové sady - Zpracování dat bez stahování
- Sdílené úložiště - Více sandboxů přistupuje ke stejným datům
- Nákladově efektivní perzistence - Levnější než udržovat sandboxy trvale spuštěné
Připojení bucketu R2
import { getSandbox } from "@cloudflare/sandbox";
const sandbox = getSandbox(env.Sandbox, "data-processor");
// Mount R2 bucket by Worker binding name
await sandbox.mountBucket("MY_BUCKET", "/data");
// Access bucket with standard filesystem operations
await sandbox.exec("ls", { args: ["/data"] });
await sandbox.writeFile("/data/results.json", JSON.stringify(results));
// Use from Python
await sandbox.exec("python", {
args: [
"-c",
`
import pandas as pd
df = pd.read_csv('/data/input.csv')
df.describe().to_csv('/data/summary.csv')
`,
],
});import { getSandbox } from '@cloudflare/sandbox';
const sandbox = getSandbox(env.Sandbox, 'data-processor');
// Mount R2 bucket by Worker binding name
await sandbox.mountBucket('MY_BUCKET', '/data');
// Access bucket with standard filesystem operations
await sandbox.exec('ls', { args: ['/data'] });
await sandbox.writeFile('/data/results.json', JSON.stringify(results));
// Use from Python
await sandbox.exec('python', { args: ['-c', `
import pandas as pd
df = pd.read_csv('/data/input.csv')
df.describe().to_csv('/data/summary.csv')
`] });V tomto příkladu MY_BUCKET je název bindingu z wrangler.toml. Nemusí se shodovat s názvem bucketu v dashboardu, i když mnoho projektů používá shodné názvy.
Přihlašovací údaje
Mounty R2 bindingu nevyžadují přihlašovací údaje. Mounty vzdálených endpointů zůstávají podporované pro Cloudflare R2 i další poskytovatele kompatibilní s S3, přičemž tyto postupy mohou stále využívat automatickou detekci přihlašovacích údajů nebo explicitní přihlašovací údaje.
Automatická detekce
Když zahrnete endpoint, nastavte přihlašovací údaje jako tajné klíče Workeru a SDK je automaticky rozpozná:
npx wrangler secret put R2_ACCESS_KEY_ID
npx wrangler secret put R2_SECRET_ACCESS_KEY// Credentials automatically detected from environment for remote endpoint mounts
await sandbox.mountBucket("my-r2-bucket", "/data", {
endpoint: "https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com",
});// Credentials automatically detected from environment for remote endpoint mounts
await sandbox.mountBucket('my-r2-bucket', '/data', {
endpoint: 'https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com'
});Explicitní přihlašovací údaje
V případě potřeby předejte přihlašovací údaje přímo:
await sandbox.mountBucket("my-r2-bucket", "/data", {
endpoint: "https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com",
credentials: {
accessKeyId: env.R2_ACCESS_KEY_ID,
secretAccessKey: env.R2_SECRET_ACCESS_KEY,
},
});await sandbox.mountBucket('my-r2-bucket', '/data', {
endpoint: 'https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com',
credentials: {
accessKeyId: env.R2_ACCESS_KEY_ID,
secretAccessKey: env.R2_SECRET_ACCESS_KEY
}
});Proxy pro přihlašovací údaje
Pokud připojíte úložiště s explicitně zadanými přihlašovacími údaji, s3fs tyto údaje zapíše do souboru s heslem na disku kontejneru. Napadený proces kontejneru pak může tyto údaje přečíst a odcizit, nebo je použít k přístupu do úložiště mimo zamýšlený rozsah bucketu.
Nastavte credentialProxy: true aby přihlašovací údaje vůbec nebyly v kontejneru. Durable Object místo předávání skutečných přihlašovacích údajů do kontejneru zachytává veškeré odchozí požadavky S3 na síťové vrstvě, znovu je podepíše skutečnými přihlašovacími údaji a přeposílá je dál. Kontejner tak vždy obsahuje jen fiktivní přihlašovací údaje, které jsou mimo proxy k ničemu.
To funguje s AWS SigV4 ↗ podepisování pro endpointy kompatibilní s S3 (včetně R2) a podepisování HMAC pro Google Cloud Storage. Doporučujeme nastavit credentialProxy: true pro všechna připojení koncových bodů. Ve výchozím nastavení má tato možnost hodnotu false kvůli zpětné kompatibilitě a v budoucí verzi Sandbox SDK se stane výchozí volbou.
await sandbox.mountBucket("my-bucket", "/data", {
endpoint: "https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com",
provider: "r2",
credentials: {
accessKeyId: env.R2_ACCESS_KEY_ID,
secretAccessKey: env.R2_SECRET_ACCESS_KEY,
},
credentialProxy: true,
});await sandbox.mountBucket('my-bucket', '/data', {
endpoint: 'https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com',
provider: 'r2',
credentials: {
accessKeyId: env.R2_ACCESS_KEY_ID,
secretAccessKey: env.R2_SECRET_ACCESS_KEY
},
credentialProxy: true
});Připojení podadresářů bucketu
Konkrétní podadresář v bucketu připojte pomocí prefix volba. V bodě připojení je viditelný pouze obsah pod tímto prefixem:
// Mount only the /uploads/images/ subdirectory
await sandbox.mountBucket("MY_BUCKET", "/images", {
prefix: "/uploads/images/",
});
// Files appear at mount point without the prefix
// Bound bucket: my-r2-bucket/uploads/images/photo.jpg
// Mounted path: /images/photo.jpg
await sandbox.exec("ls", { args: ["/images"] });
// Write to subdirectory
await sandbox.writeFile("/images/photo.jpg", imageData);
// Creates my-r2-bucket/uploads/images/photo.jpg
// Mount different prefixes to different paths
await sandbox.mountBucket("MY_BUCKET", "/training-data", {
prefix: "/ml/training/",
});
await sandbox.mountBucket("MY_BUCKET", "/test-data", {
prefix: "/ml/testing/",
});// Mount only the /uploads/images/ subdirectory
await sandbox.mountBucket('MY_BUCKET', '/images', {
prefix: '/uploads/images/'
});
// Files appear at mount point without the prefix
// Bound bucket: my-r2-bucket/uploads/images/photo.jpg
// Mounted path: /images/photo.jpg
await sandbox.exec('ls', { args: ['/images'] });
// Write to subdirectory
await sandbox.writeFile('/images/photo.jpg', imageData);
// Creates my-r2-bucket/uploads/images/photo.jpg
// Mount different prefixes to different paths
await sandbox.mountBucket('MY_BUCKET', '/training-data', {
prefix: '/ml/training/'
});
await sandbox.mountBucket('MY_BUCKET', '/test-data', {
prefix: '/ml/testing/'
});Mounty jen pro čtení
Chraňte data mountováním bucketů v režimu jen pro čtení:
await sandbox.mountBucket("MY_BUCKET", "/data", {
readOnly: true,
});
// Reads work
await sandbox.exec("cat", { args: ["/data/dataset.csv"] });
// Writes fail
await sandbox.writeFile("/data/new-file.txt", "data"); // Error: Read-only filesystemawait sandbox.mountBucket('MY_BUCKET', '/data', {
readOnly: true
});
// Reads work
await sandbox.exec('cat', { args: ['/data/dataset.csv'] });
// Writes fail
await sandbox.writeFile('/data/new-file.txt', 'data'); // Error: Read-only filesystemLokální vývoj
Během lokálního vývoje můžete také připojit R2 buckety pomocí wrangler dev předáním localBucket volba. Produkční připojení vazby R2 a lokální localBucket připojení se oběma vyhýbají explicitním přihlašovacím údajům, ale jde o odlišné způsoby provádění. Produkce používá zachytávání odchozího provozu bez přihlašovacích údajů a překrývá cílovou cestu. Lokální vývoj používá pravidelnou synchronizaci s vazbou R2.
await sandbox.mountBucket("MY_BUCKET", "/data", {
localBucket: true,
});
// Access files using standard operations
await sandbox.exec("ls", { args: ["/data"] });
await sandbox.writeFile("/data/results.json", JSON.stringify(results));await sandbox.mountBucket('MY_BUCKET', '/data', {
localBucket: true
});
// Access files using standard operations
await sandbox.exec('ls', { args: ['/data'] });
await sandbox.writeFile('/data/results.json', JSON.stringify(results)); readOnly a prefix volby fungují stejně i v lokálním režimu:
// Read-only local mount
await sandbox.mountBucket("MY_BUCKET", "/data", {
localBucket: true,
readOnly: true,
});
// Mount a subdirectory
await sandbox.mountBucket("MY_BUCKET", "/images", {
localBucket: true,
prefix: "/uploads/images/",
});// Read-only local mount
await sandbox.mountBucket('MY_BUCKET', '/data', {
localBucket: true,
readOnly: true
});
// Mount a subdirectory
await sandbox.mountBucket('MY_BUCKET', '/images', {
localBucket: true,
prefix: '/uploads/images/'
});Aspekty místního vývoje
Při lokálním vývoji se soubory synchronizují mezi R2 a kontejnerem pomocí periodického synchronizačního procesu, nikoli přímým připojením souborového systému. Mějte na paměti následující:
- Synchronizační okno - Mezi zápisem souboru a jeho objevením se na druhé straně existuje krátká prodleva. Pokud například nahrajete soubor do R2 a hned poté ho zkusíte přečíst z připojené cesty v kontejneru, nemusí být ještě dostupný. Před čtením nedávno zapsaných dat nechte chvíli čas na dokončení synchronizace.
- Časté zápisy - Rychlé po sobě jdoucí zápisy do stejné cesty k souboru mohou trvat o něco déle, než se plně projeví. Pro nejlepší výsledky se vyhněte souběžnému zápisu do stejného souboru z R2 i z kontejneru.
- Obousměrná synchronizace - Změny provedené v kontejneru se synchronizují do R2 a naopak, změny z R2 se synchronizují zpět do kontejneru. V obou směrech platí stejný model periodické synchronizace.
Odpojení bucketů
// Mount for processing
await sandbox.mountBucket("MY_BUCKET", "/data");
// Do work
await sandbox.exec("python process_data.py");
// Clean up
await sandbox.unmountBucket("/data");// Mount for processing
await sandbox.mountBucket('MY_BUCKET', '/data');
// Do work
await sandbox.exec('python process_data.py');
// Clean up
await sandbox.unmountBucket('/data');Ostatní poskytovatelé
SDK podporuje jakékoli objektové úložiště kompatibilní s S3. Zde jsou příklady pro běžné poskytovatele:
Amazon S3
await sandbox.mountBucket("my-s3-bucket", "/data", {
endpoint: "https://s3.us-west-2.amazonaws.com",
credentials: {
accessKeyId: env.AWS_ACCESS_KEY_ID,
secretAccessKey: env.AWS_SECRET_ACCESS_KEY,
},
});await sandbox.mountBucket('my-s3-bucket', '/data', {
endpoint: 'https://s3.us-west-2.amazonaws.com',
credentials: {
accessKeyId: env.AWS_ACCESS_KEY_ID,
secretAccessKey: env.AWS_SECRET_ACCESS_KEY
}
});Google Cloud Storage
await sandbox.mountBucket("my-gcs-bucket", "/data", {
endpoint: "https://storage.googleapis.com",
credentials: {
accessKeyId: env.GCS_ACCESS_KEY_ID,
secretAccessKey: env.GCS_SECRET_ACCESS_KEY,
},
});await sandbox.mountBucket('my-gcs-bucket', '/data', {
endpoint: 'https://storage.googleapis.com',
credentials: {
accessKeyId: env.GCS_ACCESS_KEY_ID,
secretAccessKey: env.GCS_SECRET_ACCESS_KEY
}
});Další poskytovatelé kompatibilní s S3
U poskytovatelů jako Backblaze B2, MinIO, Wasabi nebo dalších použijte standardní vzor připojení:
await sandbox.mountBucket("my-bucket", "/data", {
endpoint: "https://s3.us-west-000.backblazeb2.com",
credentials: {
accessKeyId: env.ACCESS_KEY_ID,
secretAccessKey: env.SECRET_ACCESS_KEY,
},
});await sandbox.mountBucket('my-bucket', '/data', {
endpoint: 'https://s3.us-west-000.backblazeb2.com',
credentials: {
accessKeyId: env.ACCESS_KEY_ID,
secretAccessKey: env.SECRET_ACCESS_KEY
}
});Konfiguraci specifickou pro daného poskytovatele najdete v wiki s3fs-fuse ↗ pro podporované poskytovatele a doporučené příznaky.
Řešení potíží
Chyba: R2 binding nebyl nalezen
Chyba: R2 binding "MY_BUCKET" not found in Worker env
Řešení: Ujistěte se, že váš Worker má r2_buckets vazba a že mountBucket() se používá název bindingu, nikoli název bucketu z dashboardu:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"r2_buckets": [
{
"binding": "MY_BUCKET",
"bucket_name": "my-r2-bucket"
}
]
}[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-r2-bucket"Připojení R2 bez přihlašovacích údajů selže okamžitě
Řešení: Ujistěte se, že vstupní bod vašeho Workeru exportuje ContainerProxy. Pokud používáte starší verzi Wrangler, může být také potřeba enable_ctx_exports příznak kompatibility.
Chyba chybějících přihlašovacích údajů
Chyba: MissingCredentialsError: No credentials found
Řešení: Tato chyba se týká pouze případů, kdy připojíte vzdálený S3 kompatibilní endpoint nastavením endpoint. Nastavte přihlašovací údaje jako Worker secrets:
npx wrangler secret put R2_ACCESS_KEY_ID
npx wrangler secret put R2_SECRET_ACCESS_KEYnebo
npx wrangler secret put AWS_ACCESS_KEY_ID
npx wrangler secret put AWS_SECRET_ACCESS_KEYChyba selhání připojení
Chyba: S3FSMountError: mount failed
Časté příčiny:
- Nesprávná URL adresa koncového bodu
- Neplatné přihlašovací údaje
- Chybí
ContainerProxyexport, nebo ve starších verzích Wrangleru chybějícíenable_ctx_exports - Bucket neexistuje
- Problémy se síťovým připojením
Ověřte konfiguraci vašeho bindingu nebo endpointu:
try {
await sandbox.mountBucket("MY_BUCKET", "/data");
} catch (error) {
console.error("Mount failed:", error.message);
// Check binding name, ContainerProxy export, or remote endpoint configuration
}try {
await sandbox.mountBucket('MY_BUCKET', '/data');
} catch (error) {
console.error('Mount failed:', error.message);
// Check binding name, ContainerProxy export, or remote endpoint configuration
}Chyba: cesta je již připojena
Chyba: InvalidMountConfigError: Mount path already in use
Řešení: Nejprve odpojte, nebo použijte jinou cestu:
// Unmount existing
await sandbox.unmountBucket("/data");
// Or use different path
await sandbox.mountBucket("bucket2", "/storage", { endpoint: "..." });// Unmount existing
await sandbox.unmountBucket('/data');
// Or use different path
await sandbox.mountBucket('bucket2', '/storage', { endpoint: '...' });Pomalý přístup k souborům
Operace se soubory na připojených bucketech jsou kvůli síťové latenci pomalejší než na lokálním souborovém systému.
Řešení: Zkopírujte často používané soubory lokálně:
// Copy to local filesystem
await sandbox.exec("cp", {
args: ["/data/large-dataset.csv", "/workspace/dataset.csv"],
});
// Work with local copy (faster)
await sandbox.exec("python", {
args: ["process.py", "/workspace/dataset.csv"],
});
// Save results back to bucket
await sandbox.exec("cp", {
args: ["/workspace/results.json", "/data/results/output.json"],
});// Copy to local filesystem
await sandbox.exec('cp', { args: ['/data/large-dataset.csv', '/workspace/dataset.csv'] });
// Work with local copy (faster)
await sandbox.exec('python', { args: ['process.py', '/workspace/dataset.csv'] });
// Save results back to bucket
await sandbox.exec('cp', { args: ['/workspace/results.json', '/data/results/output.json'] });Osvědčené postupy
- Připojujte brzy - Připojení bucketů při inicializaci sandboxu
- Vyberte správný režim připojení - Použijte mounty R2 binding, pokud chcete přístup k R2 spravovaný Workerem, nebo použijte
endpointpro explicitní R2, S3, GCS a další poskytovatele kompatibilní s S3 - Zabezpečené přihlašovací údaje - Vždy používejte tajné klíče Workeru, nikdy je nezapisujte natvrdo
- Jen pro čtení, kdykoli je to možné - Ochrana dat pomocí přípojných bodů jen pro čtení
- Připojujte co nejužší cestu - Pomocí prefixů zpřístupněte sandboxu jen data, která potřebuje
- Cesty připojení - Upřednostněte
/data,/storage, nebo/mnt/*; pokud připojíte pod/workspace, počítejte s tím, že v produkci tuto cestu překrývá připojený svazek - Zpracování chyb - Operace mountování obalte do
try...catchblokuje - Optimalizujte přístup - Zkopírujte často používané soubory lokálně
Související zdroje
- Návod na trvalé úložiště - Kompletní příklad pro R2
- Referenční dokumentace k Storage API - Úplná dokumentace metody
- Proměnné prostředí - Konfigurace přihlašovacích údajů pro připojení vzdálených koncových bodů
- Konfigurace Wrangleru - Nakonfigurujte R2 bindings a compatibility flags
- Dokumentace R2 - Více o Cloudflare R2
- Odchozí provoz - Naučte se, jak
ContainerProxya zachytávání odchozího provozu