Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/denoland/celld/llms.txt

Use this file to discover all available pages before exploring further.

celld uses one S3-compatible or GCS bucket as the coordination backbone. The bucket stores deployments, cell state (SQLite replicas), ownership leases, node leases, and the peer-authentication secret. There is no membership protocol or consensus service — one atomic conditional write to the bucket gives a node ownership of a cell.

Prerequisites

The bucket must support two conditional write operations and read-after-write consistency:
  • If-None-Match: * — a conditional create that fails when the object already exists.
  • If-Match — a conditional overwrite that fails when the object has changed since the last read.
  • Read-after-write consistency — a read immediately after a successful write must return that write.
These properties are required because the ownership records depend on them. See Ownership and fencing for the full mechanism.

Qualifying stores

StoreQualifies
Amazon S3✅ Yes
Cloudflare R2✅ Yes
Azure Blob Storage✅ Yes
Tigris✅ Yes
Google Cloud Storage✅ Yes (use gs:// — see Google Cloud)
MinIO (community edition)❌ No
Backblaze B2❌ No
Hetzner Object Storage❌ No
DigitalOcean Spaces❌ No
Some stores accept the If-None-Match and If-Match headers without applying the condition. A store that silently ignores conditional writes will cause two nodes to acquire ownership of the same cell simultaneously, resulting in data corruption. Test any unfamiliar store against the conditional-write requirements before trusting a fleet to it.

Cloudflare R2 setup

1

Create a bucket

In the Cloudflare dashboard, navigate to R2 Object Storage and create a new bucket. Note the bucket name and your Cloudflare account ID.
2

Create an S3 API token

In the R2 dashboard, go to Manage R2 API Tokens and create a token with Object Read & Write permissions scoped to the bucket you created.
3

Set environment variables

Export the following variables before starting celld or running celld deploy:
export AWS_ACCESS_KEY_ID=<your-r2-access-key-id>
export AWS_SECRET_ACCESS_KEY=<your-r2-secret-access-key>
export AWS_REGION=auto
export S3_ENDPOINT=https://ACCOUNT_ID.r2.cloudflarestorage.com
export CELLD_BUCKET=s3://YOUR-BUCKET
Replace ACCOUNT_ID with your Cloudflare account ID and YOUR-BUCKET with the bucket name from step 1.
4

Deploy and start a node

celld deploy . \
  --bucket "$CELLD_BUCKET" \
  --endpoint "$S3_ENDPOINT" \
  --region "$AWS_REGION"

celld \
  --bucket "$CELLD_BUCKET" \
  --endpoint "$S3_ENDPOINT" \
  --region "$AWS_REGION"

AWS S3 setup

celld uses the standard AWS credential chain for S3. You do not need to set S3_ENDPOINT or AWS_REGION — celld infers the region from the bucket. Explicit static credentials, instance metadata credentials, and web identity tokens all work. celld does not read ~/.aws profiles or SSO logins.
1

Create a bucket

Create an S3 bucket in your AWS account and note the bucket name.
2

Set credentials

Supply credentials via the standard AWS credential chain. For explicit static credentials:
export AWS_ACCESS_KEY_ID=<your-access-key-id>
export AWS_SECRET_ACCESS_KEY=<your-secret-access-key>
export CELLD_BUCKET=s3://YOUR-BUCKET
On EC2 or ECS, an instance role or task role is picked up automatically — no explicit key variables are required.
3

Deploy and start a node

celld deploy . --bucket "$CELLD_BUCKET"

celld --bucket "$CELLD_BUCKET"

Environment variable reference

export AWS_ACCESS_KEY_ID=<your-r2-access-key-id>
export AWS_SECRET_ACCESS_KEY=<your-r2-secret-access-key>
export AWS_REGION=auto
export S3_ENDPOINT=https://ACCOUNT_ID.r2.cloudflarestorage.com
export CELLD_BUCKET=s3://YOUR-BUCKET

Bucket key prefix

A bucket value can include a key prefix to namespace all fleet objects below a path:
export CELLD_BUCKET=s3://YOUR-BUCKET/PREFIX
Every object that celld writes — deployments, SQLite replicas, ownership records, node leases, the peer-auth secret — then lands under PREFIX/. This lets two independent fleets share one bucket without interfering with each other. A bucket value without a prefix keeps objects at the root of the bucket. An existing fleet configured without a prefix stays at the root and does not need to be migrated.
The bucket credentials give full control of the fleet. Anyone who can read or write the bucket can read deployments, modify ownership records, and access the peer-authentication secret. Keep the credentials safe and scope them to only the bucket celld uses.

Build docs developers (and LLMs) love