{
  "manifest_version": "1",
  "slug": "celld",
  "title": "celld",
  "headline": "A Durable Object with celld",
  "description": "Run Cloudflare-style Durable Objects on your own exe.dev VM with celld: a SQLite database per object, saved to a bucket you own.",
  "category": "serverless",
  "tags": [
    "durable objects",
    "cloudflare workers",
    "self-hosted",
    "sqlite",
    "websockets",
    "wrangler",
    "deno",
    "r2"
  ],
  "url": "https://exe.dev/deploy/celld",
  "markdown_url": "https://exe-staging.dev/deploy/celld.md",
  "upstream": {
    "website": "https://celld.dev",
    "source": "https://github.com/denoland/celld",
    "docs": "https://celld.dev/docs",
    "license": "Apache-2.0"
  },
  "example_vm_name": "my-celld",
  "time": "15 minutes",
  "stack": [
    {
      "name": "celld 0.6",
      "detail": "Workers and Durable Objects, managed by systemd",
      "port": 8000,
      "data": "~/celld/state"
    },
    {
      "name": "Chat",
      "detail": "A Worker with one Durable Object per room",
      "data": "~/chat"
    },
    {
      "name": "Your bucket",
      "detail": "Every object's database, saved before celld answers",
      "data": "R2, S3, or Tigris"
    },
    {
      "name": "Nightly snapshots",
      "detail": "A copy of the bucket on the VM; seven kept",
      "data": "~/celld/snapshots"
    }
  ],
  "access": [
    {
      "url": "https://my-celld.exe.xyz/",
      "who": "private",
      "what": "The chat, or whatever you deploy next"
    }
  ],
  "inputs": [
    {
      "name": "CELLD_BUCKET",
      "description": "an empty bucket, written `s3://name` ([get one](#get-a-bucket))"
    },
    {
      "name": "S3_ENDPOINT",
      "description": "R2: `https://\u003cACCOUNT_ID\u003e.r2.cloudflarestorage.com`; Tigris: `https://t3.storage.dev`; Amazon S3: leave empty"
    },
    {
      "name": "AWS_REGION",
      "description": "`auto` for R2 and Tigris; the bucket's region for Amazon S3"
    },
    {
      "name": "AWS_ACCESS_KEY_ID",
      "description": "a key that can read and write that bucket, and nothing else"
    },
    {
      "name": "AWS_SECRET_ACCESS_KEY",
      "description": "the key's secret"
    }
  ],
  "delivers": [
    "celld 0.6.2 serving a chat at `https://\u003cvm\u003e.exe.xyz/`, one Durable Object per room.",
    "Every write in your bucket before celld answers, with the bucket's keys in one private file.",
    "A message that survived restarting celld with an empty local cache.",
    "celld starting at boot and coming back after a crash.",
    "Nightly snapshots of the bucket, and one restored to prove it works."
  ],
  "deploy": {
    "new_vm_url": "https://exe-staging.dev/new?prompt=CELLD_BUCKET%3D%3Cfill-this-in%3E%0AS3_ENDPOINT%3D%3Cfill-this-in%3E%0AAWS_REGION%3D%3Cfill-this-in%3E%0AAWS_ACCESS_KEY_ID%3D%3Cfill-this-in%3E%0AAWS_SECRET_ACCESS_KEY%3D%3Cfill-this-in%3E%0A%0ASet%20up%20celld%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Fcelld.md%20from%20top%20to%20bottom.%0A%0AThe%20values%20at%20the%20top%20of%20this%20message%20are%20mine%3A%0A-%20CELLD_BUCKET%3A%20an%20empty%20bucket%2C%20written%20%60s3%3A%2F%2Fname%60%20%28%5Bget%20one%5D%28%23get-a-bucket%29%29%0A-%20S3_ENDPOINT%3A%20R2%3A%20%60https%3A%2F%2F%3CACCOUNT_ID%3E.r2.cloudflarestorage.com%60%3B%20Tigris%3A%20%60https%3A%2F%2Ft3.storage.dev%60%3B%20Amazon%20S3%3A%20leave%20empty%0A-%20AWS_REGION%3A%20%60auto%60%20for%20R2%20and%20Tigris%3B%20the%20bucket%27s%20region%20for%20Amazon%20S3%0A-%20AWS_ACCESS_KEY_ID%3A%20a%20key%20that%20can%20read%20and%20write%20that%20bucket%2C%20and%20nothing%20else%0A-%20AWS_SECRET_ACCESS_KEY%3A%20the%20key%27s%20secret%0AAsk%20me%20for%20any%20that%20still%20say%20%3Cfill-this-in%3E%20before%20you%20need%20them.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-celld.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-celld.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20celld%200.6.2%20serving%20a%20chat%20at%20%60https%3A%2F%2F%3Cvm%3E.exe.xyz%2F%60%2C%20one%20Durable%20Object%20per%20room.%0A-%20Every%20write%20in%20your%20bucket%20before%20celld%20answers%2C%20with%20the%20bucket%27s%20keys%20in%20one%20private%20file.%0A-%20A%20message%20that%20survived%20restarting%20celld%20with%20an%20empty%20local%20cache.%0A-%20celld%20starting%20at%20boot%20and%20coming%20back%20after%20a%20crash.%0A-%20Nightly%20snapshots%20of%20the%20bucket%2C%20and%20one%20restored%20to%20prove%20it%20works.%0A%0ARead%20the%20whole%20recipe%2C%20including%20the%20closed%20details.%20Follow%20%22Install%20by%0Ahand%22%20first%2C%20skipping%20VM%20creation%3B%20the%20walkthrough%20is%20for%20the%20owner%0Aafterwards.%20Do%20not%20run%20the%20later%20Restore%20or%20Update%20instructions.%0AWrite%20the%20owner%27s%20five%20values%20into%20~%2Fcelld%2Fcelld.env%20and%20never%20print%20the%0Asecret%20key.%20Never%20overwrite%20an%20existing%20celld.env.%20The%20bucket%20must%20be%0Aempty%3A%20if%20%60~%2Fcelld%2Frun%20rclone%20lsf%20celld%3A%60%20lists%20anything%2C%20stop%20and%20ask%0Athe%20owner%2C%20because%20celld%20treats%20everything%20in%20its%20bucket%20as%20its%20own.%0AKeep%20the%20VM%20private%3B%20do%20not%20run%20share%20set-public.%0ACheck%20the%20health%20endpoint%2C%20a%20posted%20message%2C%20the%20same%20message%20after%0Arestarting%20celld%20with%20an%20empty%20~%2Fcelld%2Fstate%2C%20that%20celld.service%20and%0Acelld-snapshot.timer%20are%20enabled%2C%20and%20the%20snapshot%20restore%20test.%0AFinish%20with%20https%3A%2F%2F%3Cvm%3E.exe.xyz%2F%2C%20using%20this%20VM%27s%20name%2C%20and%20tell%20the%0Aowner%20to%20edit%20~%2Fchat%20and%20run%20~%2Fcelld%2Fdeploy%20~%2Fchat%20to%20ship%20changes.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A",
    "terminal": "curl -fsSL https://exe-staging.dev/deploy/celld/prompt.txt | ssh exe.dev new --prompt=/dev/stdin",
    "prompt": "CELLD_BUCKET=\u003cfill-this-in\u003e\nS3_ENDPOINT=\u003cfill-this-in\u003e\nAWS_REGION=\u003cfill-this-in\u003e\nAWS_ACCESS_KEY_ID=\u003cfill-this-in\u003e\nAWS_SECRET_ACCESS_KEY=\u003cfill-this-in\u003e\n\nSet up celld on this VM by following the exe.dev recipe at https://exe-staging.dev/deploy/celld.md from top to bottom.\n\nThe values at the top of this message are mine:\n- CELLD_BUCKET: an empty bucket, written `s3://name` ([get one](#get-a-bucket))\n- S3_ENDPOINT: R2: `https://\u003cACCOUNT_ID\u003e.r2.cloudflarestorage.com`; Tigris: `https://t3.storage.dev`; Amazon S3: leave empty\n- AWS_REGION: `auto` for R2 and Tigris; the bucket's region for Amazon S3\n- AWS_ACCESS_KEY_ID: a key that can read and write that bucket, and nothing else\n- AWS_SECRET_ACCESS_KEY: the key's secret\nAsk me for any that still say \u003cfill-this-in\u003e before you need them.\n\nThe recipe's example VM name is my-celld. This VM's name is the output of `hostname`: use it wherever the recipe writes my-celld. Skip the step that creates the VM; you are on it.\n\nYou are done when all of these are true. Check each one yourself:\n- celld 0.6.2 serving a chat at `https://\u003cvm\u003e.exe.xyz/`, one Durable Object per room.\n- Every write in your bucket before celld answers, with the bucket's keys in one private file.\n- A message that survived restarting celld with an empty local cache.\n- celld starting at boot and coming back after a crash.\n- Nightly snapshots of the bucket, and one restored to prove it works.\n\nRead the whole recipe, including the closed details. Follow \"Install by\nhand\" first, skipping VM creation; the walkthrough is for the owner\nafterwards. Do not run the later Restore or Update instructions.\nWrite the owner's five values into ~/celld/celld.env and never print the\nsecret key. Never overwrite an existing celld.env. The bucket must be\nempty: if `~/celld/run rclone lsf celld:` lists anything, stop and ask\nthe owner, because celld treats everything in its bucket as its own.\nKeep the VM private; do not run share set-public.\nCheck the health endpoint, a posted message, the same message after\nrestarting celld with an empty ~/celld/state, that celld.service and\ncelld-snapshot.timer are enabled, and the snapshot restore test.\nFinish with https://\u003cvm\u003e.exe.xyz/, using this VM's name, and tell the\nowner to edit ~/chat and run ~/celld/deploy ~/chat to ship changes.\n\nFinish with the URLs I should open.\n",
    "prompt_url": "https://exe-staging.dev/deploy/celld/prompt.txt"
  },
  "updated": "2026-10-16",
  "related": [
    "migrate-durable-objects",
    "claude-code",
    "code-server",
    "n8n",
    "openclaw",
    "uptime-kuma"
  ],
  "alternatives": [
    "Cloudflare Durable Objects"
  ]
}
