[{"data":1,"prerenderedAt":177},["ShallowReactive",2],{"doc:self-host\u002Fcompute-nodes":3},{"title":4,"description":5,"url":6,"markdownPath":7,"file":8,"section":9,"sectionTitle":10,"html":11,"toc":12,"navigation":36,"previous":175,"next":176},"Compute Nodes","Give Agents an isolated place to work on repository Tasks, on your VPS, on Cloudflare Containers, on Lizard or on your own Docker host.","\u002Fdocs\u002Fself-host\u002Fcompute-nodes","\u002Fdocs\u002Fself-host\u002Fcompute-nodes.md","docs\u002Fself-host\u002Fcompute-nodes.md","self-host","Self-host","\u003Cp>A Compute Node is where an Agent&#39;s repository work runs. When an Agent works on a repository-backed Task, the Server sends workspace operations (read files, run commands, commit) to a connected Compute Node. The Agent&#39;s model and tools stay on the Server; the Node only runs the workspace. Without a connected Node, repository metadata is still available, but Agents cannot write code.\u003C\u002Fp>\n\u003Cp>This page covers setting up compute. For how Agents use it, see \u003Ca href=\"\u002Fdocs\u002Fagents\u002Frepositories\">Repositories\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"choose-a-kind-of-compute\">\u003Ca class=\"heading-anchor\" href=\"#choose-a-kind-of-compute\">Choose a kind of compute\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Open \u003Cstrong>Server settings → Compute\u003C\u002Fstrong> (requires Manage server). \u003Cstrong>Add compute\u003C\u002Fstrong> offers \u003Cstrong>Connect node\u003C\u002Fstrong> and \u003Cstrong>Connect Lizard\u003C\u002Fstrong>. The \u003Cstrong>Server compute setup\u003C\u002Fstrong> entry shows the option that fits where your Server runs.\u003C\u002Fp>\n\u003Cdiv class=\"table-wrap\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Option\u003C\u002Fth>\n\u003Cth>Where it runs\u003C\u002Fth>\n\u003Cth>Good for\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>VPS local executor\u003C\u002Ftd>\n\u003Ctd>Docker on the same VPS as a \u003Ca href=\"\u002Fdocs\u002Fself-host\u002Fvps\">VPS installer\u003C\u002Fa> Server\u003C\u002Ftd>\n\u003Ctd>A single trusted VPS.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Cloudflare Containers\u003C\u002Ftd>\n\u003Ctd>Your Cloudflare account, next to a Cloudflare Server\u003C\u002Ftd>\n\u003Ctd>Cloudflare Servers on Workers Paid.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Lizard\u003C\u002Ftd>\n\u003Ctd>A Lizard VM created by the Server\u003C\u002Ftd>\n\u003Ctd>Compute without running a machine yourself.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Remote Docker Node\u003C\u002Ftd>\n\u003Ctd>Any Linux Docker host you pair\u003C\u002Ftd>\n\u003Ctd>Advanced setups.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\u003C\u002Fdiv>\n\u003Cblockquote class=\"callout callout-warning\">\u003Cp class=\"callout-title\">Warning\u003C\u002Fp>\u003Cp>Docker workspaces share the host&#39;s kernel. Use them only for code and people you trust. They are not a boundary against hostile tenants.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2 id=\"vps-local-executor\">\u003Ca class=\"heading-anchor\" href=\"#vps-local-executor\">VPS local executor\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>On a VPS installer Server, add the executor during install with \u003Ccode>LLLL_FACTORY=true LLLL_SHARED_KERNEL_TRUSTED=1\u003C\u002Fcode>, or later:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">sudo llll compute enable --trust-shared-kernel\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>llll factory\u003C\u002Fcode> is the same command. The CLI downloads the verified Compute Node and workspace image from the release, checks the host, installs a root systemd service and pairs it with the Server automatically after the Owner is claimed. No Git clone, source build or registry is needed.\u003C\u002Fp>\n\u003Cp>The host needs:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Linux amd64 with local Docker.\u003C\u002Fli>\n\u003Cli>At least 17 GiB free disk and 2 GiB available RAM beyond what the Server uses. Each new Task workspace gets a 10 GiB disk.\u003C\u002Fli>\n\u003Cli>Loop-device and mount support (\u003Ccode>fallocate\u003C\u002Fcode>, \u003Ccode>mkfs.ext4\u003C\u002Fcode>, \u003Ccode>mount\u003C\u002Fcode>, \u003Ccode>umount\u003C\u002Fcode>, \u003Ccode>findmnt\u003C\u002Fcode>, \u003Ccode>losetup\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>systemd as process 1.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Manage it with:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">sudo llll compute status\nsudo llll compute logs\nsudo llll compute restart\nsudo llll compute disable\nsudo llll compute backup\nsudo llll compute remove --keep-source\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>disable\u003C\u002Fcode> and \u003Ccode>remove --keep-source\u003C\u002Fcode> keep Task disks and receipts. Compute backups are separate from the Server backup made by \u003Ccode>llll backup\u003C\u002Fcode>; copy them encrypted off the host.\u003C\u002Fp>\n\u003Ch3 id=\"hosts-without-systemd\">\u003Ca class=\"heading-anchor\" href=\"#hosts-without-systemd\">Hosts without systemd\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cp>In a container or on a host whose process 1 is not systemd, add \u003Ccode>--no-systemd\u003C\u002Fcode>. The CLI prepares the same verified files and writes \u003Ccode>factory\u002Ffactory.env\u003C\u002Fcode>; you start the Node yourself:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">set -a; . \u002Fopt\u002Fllll\u002Ffactory\u002Ffactory.env; set +a\n\u002Fopt\u002Fllll\u002Ffactory\u002Freleases\u002FVERSION\u002Fnode \u002Fopt\u002Fllll\u002Ffactory\u002Freleases\u002FVERSION\u002Fsrc\u002Fpair-local.mjs \u002Fopt\u002Fllll\u002F.env\n\u002Fopt\u002Fllll\u002Ffactory\u002Freleases\u002FVERSION\u002Fnode \u002Fopt\u002Fllll\u002Ffactory\u002Freleases\u002FVERSION\u002Fsrc\u002Fdaemon.mjs\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>In that mode \u003Ccode>status\u003C\u002Fcode> and \u003Ccode>logs\u003C\u002Fcode> fail with an explanation instead.\u003C\u002Fp>\n\u003Ch2 id=\"cloudflare-containers\">\u003Ca class=\"heading-anchor\" href=\"#cloudflare-containers\">Cloudflare Containers\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>A Cloudflare Server can run compute in the same Cloudflare account. Open \u003Cstrong>Server settings → Compute → Server compute setup\u003C\u002Fstrong> and choose \u003Cstrong>Enable compute node in Cloudflare\u003C\u002Fstrong>, which opens the official installer with a fresh Cloudflare consent. This needs Workers Paid and available Containers and Artifacts access; the installer never changes your plan. Review the charges, choose compute size, command time and process limits, then return to Settings, confirm the authorization and choose \u003Cstrong>Activate compute node\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp>Each Task gets its own code repository. Compute stops after each checkpoint, one operation runs at a time and there is no nested Docker. \u003Cstrong>Pause compute node and retain source\u003C\u002Fstrong> stops new work and keeps source. See \u003Ca href=\"\u002Fdocs\u002Fcloudflare\u002Fcosts-and-limits\">Costs and limits\u003C\u002Fa> and Cloudflare&#39;s \u003Ca href=\"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcontainers\u002Fpricing\u002F\" rel=\"noopener\">Containers pricing\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"lizard\">\u003Ca class=\"heading-anchor\" href=\"#lizard\">Lizard\u003C\u002Fa>\u003C\u002Fh2>\n\u003Col>\n\u003Cli>Open \u003Cstrong>Server settings → Compute → Add compute → Connect Lizard\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>Enter your Lizard API key and choose \u003Cstrong>Check connection\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>Choose a project and \u003Cstrong>Save connection\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Saving starts a temporary compute VM. The VM stops after two minutes without an active Run and starts again on demand. \u003Cstrong>Stop VM\u003C\u002Fstrong> stops it and prevents automatic restart until you choose \u003Cstrong>Start compute\u003C\u002Fstrong>. Task workspaces stay on the Lizard disk after the VM stops, so storage charges may continue. Release workspaces before choosing \u003Cstrong>Delete unused storage\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Ch2 id=\"remote-docker-node\">\u003Ca class=\"heading-anchor\" href=\"#remote-docker-node\">Remote Docker Node\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>You can pair any trusted Linux Docker host with the Server. The Node connects out to the Server; the Server needs no inbound route to it. This works for both Cloudflare and VPS Servers.\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cp>In \u003Cstrong>Server settings → Compute → Add compute → Connect node\u003C\u002Fstrong>, name the node and choose \u003Cstrong>Create pairing code\u003C\u002Fstrong>. The code works once and expires after ten minutes.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>On the host, build the workspace image from the release you run, push it to your own registry and note its immutable digest. The Node refuses mutable tags.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">docker build -f packages\u002Fcompute-node\u002FDockerfile.workspace -t YOUR_REGISTRY\u002Fl4-workspace:VERSION .\ndocker push YOUR_REGISTRY\u002Fl4-workspace:VERSION\ndocker image inspect YOUR_REGISTRY\u002Fl4-workspace:VERSION --format &#39;{{json .RepoDigests}}&#39;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>Start the Node from a checkout of the same release, entering the pairing code without saving it in shell history:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">export LLLL_SERVER_ORIGIN=https:\u002F\u002FYOUR_SERVER\nexport LLLL_NODE_STATE=\u002FPRIVATE\u002FCOMPUTE_STATE\nexport LLLL_WORKSPACE_IMAGE=YOUR_REGISTRY\u002Fl4-workspace@sha256:DIGEST\nexport LLLL_SHARED_KERNEL_TRUSTED=1\nread -r -s -p &#39;One-use pairing code: &#39; LLLL_PAIRING_TOKEN\nexport LLLL_PAIRING_TOKEN\nsudo --preserve-env=LLLL_SERVER_ORIGIN,LLLL_NODE_STATE,LLLL_WORKSPACE_IMAGE,LLLL_SHARED_KERNEL_TRUSTED,LLLL_PAIRING_TOKEN node packages\u002Fcompute-node\u002Fsrc\u002Fdaemon.mjs\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The Node needs Node.js 24, Docker and the loop\u002Fmount tools listed above, and runs as root. A remote Server must use HTTPS. Later starts reuse the stored connection and need no pairing code; keep \u003Ccode>LLLL_SERVER_ORIGIN\u003C\u002Fcode> set on every start. No public port is opened.\u003C\u002Fp>\n\u003Cp>The full threat model and limits are in the \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Finchidev\u002Fllll\u002Fblob\u002Fmain\u002Fdocs\u002Fsoftware-factory.md\" rel=\"noopener\">Compute Node guide\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"check-a-node\">\u003Ca class=\"heading-anchor\" href=\"#check-a-node\">Check a Node\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Select a Node in \u003Cstrong>Server settings → Compute\u003C\u002Fstrong> to see whether it is \u003Cstrong>Connected\u003C\u002Fstrong>, \u003Cstrong>Offline\u003C\u002Fstrong> or \u003Cstrong>Disabled\u003C\u002Fstrong>, when it was last seen, its disk, parallel operations and image. \u003Cstrong>Disable and revoke\u003C\u002Fstrong> stops it from taking new work.\u003C\u002Fp>\n\u003Cp>\u003Cfigure class=\"doc-shot doc-shot-missing\">\u003Cdiv class=\"doc-shot-frame\" role=\"img\" aria-label=\"Server settings → Compute with the Server compute setup entry and one connected Docker Node\">\u003Cspan class=\"doc-shot-label\">Screenshot coming soon\u003C\u002Fspan>\u003Cspan class=\"doc-shot-alt\">Server settings → Compute with the Server compute setup entry and one connected Docker Node\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cfigcaption>Compute in Server settings\u003C\u002Ffigcaption>\u003C\u002Ffigure>\u003C\u002Fp>\n\u003Cp>To replace a Node, for example after changing its image: export or finish retained work, disable and revoke the old Node, pair a new one, update the repository environment and start new Tasks.\u003C\u002Fp>\n",[13,17,20,24,27,30,33],{"id":14,"text":15,"depth":16},"choose-a-kind-of-compute","Choose a kind of compute",2,{"id":18,"text":19,"depth":16},"vps-local-executor","VPS local executor",{"id":21,"text":22,"depth":23},"hosts-without-systemd","Hosts without systemd",3,{"id":25,"text":26,"depth":16},"cloudflare-containers","Cloudflare Containers",{"id":28,"text":29,"depth":16},"lizard","Lizard",{"id":31,"text":32,"depth":16},"remote-docker-node","Remote Docker Node",{"id":34,"text":35,"depth":16},"check-a-node","Check a Node",[37,62,90,102,121,143,165],{"id":38,"title":39,"pages":40},"get-started","Get started",[41,44,47,50,53,56,59],{"title":42,"url":43},"What is L4","\u002Fdocs\u002Fget-started\u002Fwhat-is-l4",{"title":45,"url":46},"Choose how to run your Server","\u002Fdocs\u002Fget-started\u002Fchoose-how-to-run",{"title":48,"url":49},"Create a Server on Cloudflare","\u002Fdocs\u002Fget-started\u002Fcreate-on-cloudflare",{"title":51,"url":52},"Install on a VPS","\u002Fdocs\u002Fget-started\u002Finstall-on-a-vps",{"title":54,"url":55},"Connect to a Server","\u002Fdocs\u002Fget-started\u002Fconnect-a-server",{"title":57,"url":58},"Invite your team","\u002Fdocs\u002Fget-started\u002Finvite-your-team",{"title":60,"url":61},"Create your first Agent","\u002Fdocs\u002Fget-started\u002Ffirst-agent",{"id":63,"title":64,"pages":65},"cloudflare","Cloudflare",[66,69,72,75,78,81,84,87],{"title":67,"url":68},"L4 on Cloudflare","\u002Fdocs\u002Fcloudflare\u002Foverview",{"title":70,"url":71},"Cloudflare access","\u002Fdocs\u002Fcloudflare\u002Faccess",{"title":73,"url":74},"Costs and limits","\u002Fdocs\u002Fcloudflare\u002Fcosts-and-limits",{"title":76,"url":77},"Custom domain","\u002Fdocs\u002Fcloudflare\u002Fcustom-domain",{"title":79,"url":80},"Mail on Cloudflare","\u002Fdocs\u002Fcloudflare\u002Fmail",{"title":82,"url":83},"Update a Cloudflare Server","\u002Fdocs\u002Fcloudflare\u002Fupdates",{"title":85,"url":86},"Backups on Cloudflare","\u002Fdocs\u002Fcloudflare\u002Fbackups",{"title":88,"url":89},"Remove a Cloudflare Server","\u002Fdocs\u002Fcloudflare\u002Fremove-a-server",{"id":9,"title":10,"pages":91},[92,95,98,101],{"title":93,"url":94},"Run a Server on a VPS","\u002Fdocs\u002Fself-host\u002Fvps",{"title":96,"url":97},"Run a Server with Docker Compose","\u002Fdocs\u002Fself-host\u002Fdocker",{"title":99,"url":100},"Run a Server on Coolify","\u002Fdocs\u002Fself-host\u002Fcoolify",{"title":4,"url":6},{"id":103,"title":104,"pages":105},"concepts","Concepts",[106,109,112,115,118],{"title":107,"url":108},"Servers and the Shell","\u002Fdocs\u002Fconcepts\u002Fserver-and-shell",{"title":110,"url":111},"Accounts, Members and Roles","\u002Fdocs\u002Fconcepts\u002Faccounts-members-roles",{"title":113,"url":114},"Agents, Tasks and Runs","\u002Fdocs\u002Fconcepts\u002Fagents-tasks-runs",{"title":116,"url":117},"Files and backups","\u002Fdocs\u002Fconcepts\u002Ffiles-and-backups",{"title":119,"url":120},"Releases and updates","\u002Fdocs\u002Fconcepts\u002Freleases-and-updates",{"id":122,"title":123,"pages":124},"agents","Agents and MCP",[125,128,131,134,137,140],{"title":126,"url":127},"Agents overview","\u002Fdocs\u002Fagents\u002Foverview",{"title":129,"url":130},"Models and Providers","\u002Fdocs\u002Fagents\u002Fmodels-and-providers",{"title":132,"url":133},"Connect an MCP client","\u002Fdocs\u002Fagents\u002Fmcp",{"title":135,"url":136},"External agents","\u002Fdocs\u002Fagents\u002Fexternal-agents",{"title":138,"url":139},"Repositories and code work","\u002Fdocs\u002Fagents\u002Frepositories",{"title":141,"url":142},"Schedules","\u002Fdocs\u002Fagents\u002Fschedules",{"id":144,"title":145,"pages":146},"guides","Guides",[147,150,153,156,159,162],{"title":148,"url":149},"Chat","\u002Fdocs\u002Fguides\u002Fchat",{"title":151,"url":152},"Projects and Tasks","\u002Fdocs\u002Fguides\u002Fprojects-and-tasks",{"title":154,"url":155},"Mail","\u002Fdocs\u002Fguides\u002Fmail",{"title":157,"url":158},"Calls and Live","\u002Fdocs\u002Fguides\u002Fcalls",{"title":160,"url":161},"Notifications","\u002Fdocs\u002Fguides\u002Fnotifications",{"title":163,"url":164},"Telegram","\u002Fdocs\u002Fguides\u002Ftelegram",{"id":166,"title":167,"pages":168},"reference","Reference",[169,172],{"title":170,"url":171},"Glossary","\u002Fdocs\u002Freference\u002Fglossary",{"title":173,"url":174},"Troubleshooting","\u002Fdocs\u002Freference\u002Ftroubleshooting",{"title":99,"url":100},{"title":107,"url":108},1793335825985]