Storage
Buckets for any storage client. Work with any storage client or SDK, or read and write files from a function as env.BUCKET.
Create a bucket and the key#
cloudhost buckets create uploads
# created bucket uploads at https://storage.trustpage.ir
# your storage key (secret shown once):
# access key …
# secret key …
cloudhost buckets listA bucket name is 3–63 characters: lowercase letters, digits and hyphens. A team has one storage key for all its buckets; the first bucket makes it, and its secret is shown only then. The region is always us-east-1.
cloudhost storage credentials
# endpoint https://storage.trustpage.ir
# region us-east-1
# access key …
# secret key … (shown once; the previous secret no longer works)cloudhost storage credentials rotates the key's secret: the old one stops at once, and functions bound to the buckets get the new one by themselves. If the team's key was made before buckets could be bound to functions, rotate it once before the first binding.
Storage clients#
[uploads]
type = s3
provider = Other
endpoint = https://storage.trustpage.ir
region = us-east-1
access_key_id = …
secret_access_key = …Any storage tool works with the address https://storage.trustpage.ir, the region us-east-1 and the team's key: rclone, the storage SDK in any language, and backup tools. In an SDK, give it those three: the endpoint, the region and the key.
# a link anyone can use to download for one hour
rclone link uploads:uploads/report.pdf --expire 1hPresigned URLs: with the team's key, make a link to one object that works without a key until it expires (at most 7 days): for downloads (GET) or for uploads (PUT) from your users' browsers. A changed or expired link is refused. Large files: multipart upload is supported (up to 10,000 parts, each up to 5 GB). Storage limit: when your plan's storage is full, new writes are refused with QuotaExceeded; reads and deletes still work. Every request is counted on the usage page.
env.BUCKET in functions#
type Obj = { text(): Promise<string>; size: number; contentType: string | null };
type Env = {
BUCKET: {
put(key: string, body: string | ArrayBuffer | ReadableStream, opts?: { contentType?: string }): Promise<{ size: number }>;
get(key: string): Promise<Obj | null>;
head(key: string): Promise<{ size: number; contentType: string | null } | null>;
list(opts?: { prefix?: string; limit?: number }): Promise<{ objects: { key: string; size: number }[] }>;
delete(key: string): Promise<void>;
};
};
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const key = new URL(request.url).searchParams.get("key") ?? "notes/hello.txt";
if (request.method === "PUT") return Response.json(await env.BUCKET.put(key, await request.text(), { contentType: "text/plain" }));
if (request.method === "DELETE") { await env.BUCKET.delete(key); return Response.json({ deleted: key }); }
const obj = await env.BUCKET.get(key);
return obj ? new Response(await obj.text()) : new Response("no such note\n", { status: 404 });
},
};The function reads the bucket as env.BUCKET, with no key: get, head, put, list and delete.
Deleting#
cloudhost buckets delete uploads deletes an empty bucket only, and not while a live version binds it.