Self-host Nod, n8n's personal agent, on a server that stays on
n8n's personal agent with its own computer, on a VM that never sleeps.
Shelley handles the setup. About 20 minutes. Needs a 50 GB disk: Shelley sends you a link to grow it.
Prefer a terminal?
curl -fsSL https://exe-staging.dev/deploy/nod/prompt.txt | ssh exe.dev new --disk=50GB --prompt=/dev/stdinNod is n8n Labs' personal agent "with its own computer": a Linux workspace and a Chromium browser where it does your errands, from chasing invoices to watching a price, and asks before it acts for you. Its site warns that it "needs the computer running it to stay on and awake", and suggests a Mac mini or a server of your own for its schedules and Telegram or WhatsApp messages.
An exe.dev VM is that server. Docker is already there for Nod's containers, the disk keeps its memory, vault and logins, and exe.dev's HTTPS proxy puts your exe.dev login in front of Nod's own token, so there's no SSH tunnel, domain or open port. GPT-6.1 Sol comes through exe.dev's LLM integration, so you don't need an API key to start.
Nod is a research preview and releases several times a day. These steps build the source of nod-v0.7.5, which we ran end to end on 13 November 2026.
What you get#
- Nod's server, PostgreSQL, browser and workspace containers built from nod-v0.7.5, healthy and set to start again after a reboot
- Nod at
https://<vm>.exe.xyz/, behind your exe.dev login and Nod's own access token - GPT-6.1 Sol through exe.dev's LLM integration as the first model, with no API key on the VM
- Nod's workspace and browser checked to be unable to reach exe.dev's integrations
- A first backup in
~/backups
What's running, and where
https://my-nod.exe.xyz/
Nod's web app and API, behind your exe.dev login and then Nod's access token
Deploy with Shelley#
Click Deploy and Shelley will set up Nod on a new VM, then check that it works. No config-file wrangling required.
Nod needs a 50 GB disk, more than a new VM has. Shelley checks first and, if it's too small, gives you a link to grow it; the terminal command below makes the VM that size from the start.
Prefer a terminal?
curl -fsSL \
https://exe-staging.dev/deploy/nod/prompt.txt \
| ssh exe.dev new --disk=50GB --prompt=/dev/stdinWhat Shelley is told
Set up Nod on this VM by following the exe.dev recipe at https://exe-staging.dev/deploy/nod.md from top to bottom.
The recipe's example VM name is my-nod. This VM's name is the output of `hostname`: use it wherever the recipe writes my-nod. Skip the step that creates the VM; you are on it.
This recipe needs a 50GB disk, and a new VM's may be smaller. Before you install anything, run `df -h /`. If its size is under 45G, stop and ask me to grow the disk, either with this link: https://exe.dev/suggest?command=resize%20my-nod%20--disk%3D50GB or, on my computer, with `ssh exe.dev resize my-nod --disk=50GB`. When I say it's done, run `sudo resize2fs "$(findmnt -no SOURCE /)"`, check `df -h /` again, and carry on.
You are done when all of these are true. Check each one yourself:
- Nod's server, PostgreSQL, browser and workspace containers built from nod-v0.7.5, healthy and set to start again after a reboot
- Nod at `https://<vm>.exe.xyz/`, behind your exe.dev login and Nod's own access token
- GPT-6.1 Sol through exe.dev's LLM integration as the first model, with no API key on the VM
- Nod's workspace and browser checked to be unable to reach exe.dev's integrations
- A first backup in `~/backups`
Read the whole recipe, including the closed details. For initial setup,
follow "Install by hand" first, skipping VM creation and SSH but doing
the disk check. The opening walkthrough is for the owner. Build exactly
the pinned tag. The build takes about 12 minutes: run it in tmux or with
a long timeout, and don't interrupt it. Do not run the restore or update
instructions, and don't reboot.
Keep the VM private: never run share set-public, keep NOD_BIND_ADDRESS
at 127.0.0.1, and don't remove or change the workspace-network service.
On an existing VM, ask before replacing anything that listens on port
8000. Never print NOD_VAULT_KEY or NOD_POSTGRES_PASSWORD.
Verify every check in "Install by hand", including both blocked
integration checks, then take the first backup with backup.sh.
Finish by giving the owner https://<vm>.exe.xyz/ and the value of
NOD_AUTH_TOKEN, and point them to "Open Nod".
Finish with the URLs I should open.
Also at /deploy/nod/prompt.txt. The recipe it follows is /deploy/nod.md.
Open Nod#
When Shelley finishes, it gives you Nod's address and access token. Open
https://my-nod.exe.xyz/, sign in to exe.dev, then paste the token into
Connect to Nod. To see the token again, on your computer:
ssh my-nod.exe.xyz grep ^NOD_AUTH_TOKEN= nod/deployment/self-host/.env
Onboarding offers to connect Gmail or Outlook and asks about you. You can skip all of it. The model is already set to GPT-6.1 Sol through exe.dev, so try:
Run
uname -smin your workspace, then open https://exe.dev/docs in your browser and tell me in one line what it's about.
Nod shows each command and page in the chat. Before it sends, buys, deletes or schedules anything, it shows you the exact action and asks.
Warning
The token gives full control of your assistant and every account you connect to it. Keep the VM private, so strangers meet the exe.dev login before they ever reach Nod's token form, and keep the token to yourself. One Nod server belongs to one person.
The desktop app can use this server too: choose Connect to a server and enter the same address and token.
Message it from Telegram or WhatsApp#
Open Channels in Nod's sidebar:
- Telegram: make a bot with @BotFather, paste its token, then press Start in the bot's chat to link your account. Only that account can message Nod.
- WhatsApp: link a second number, or your own for self-chat, by scanning a QR code from Linked Devices on your phone.
Both connect outbound (Telegram polling, WhatsApp's linked-device connection), so they work while the VM stays private. Nod keeps the bot token and device keys encrypted in its database. Telegram webhooks and Meta's WhatsApp Cloud API would need a public address; this page doesn't use them. We haven't tested either channel yet, since both need your accounts.
exe.dev's Telegram integration can't hold the bot token for Nod, because
Nod always calls api.telegram.org itself.
Choose a model#
Installation adds two server-managed connections, both through exe.dev's LLM integration, so neither holds a key:
- Azure OpenAI with GPT-6.1 Sol, the first choice. Nod can't change the address of its OpenAI connection, but its Azure OpenAI connection accepts any endpoint and speaks the same Responses API, which the integration serves. The key it shows is a placeholder.
- OpenAI-compatible at
llm.int.exe.xyz, for the open models the integration offers, such asfireworks/kimi-k3andfireworks/glm-5p3. Its GPT-5 and GPT-6 entries don't work here; use the Azure connection.
Switch in Settings → Models, or tell Nod: "Switch my model to fireworks/kimi-k3 on the OpenAI-compatible connection." To add another provider, such as Anthropic, Gemini or OpenRouter, choose Add there and paste its key; Nod keeps it encrypted.
Another GPT model through the integration is one line in .env; see
Update for how to apply it:
AZURE_OPENAI_MODEL=gpt-6-luna
What Nod can reach on this VM#
Nod's docs warn that a cloud VM's metadata service can hand cloud
credentials to commands the agent runs. An exe.dev VM has no cloud
credentials to hand out. The closest thing is its
integrations: llm.int.exe.xyz,
reflection.int.exe.xyz and any others attached to the VM answer from the
VM's link-local address and act for you without a key.
Nod's own isolation covers that. Its workspace sits behind a firewall
container that blocks private and link-local addresses, and its browser
refuses them. We checked both on a test VM: curl from the workspace
couldn't connect to reflection.int.exe.xyz, and the browser refused to
open it. Only Nod's server process, which already holds your model keys,
reaches the LLM integration. To keep it that way:
- Don't remove or change the
workspace-networkservice incompose.yaml. - Attach only the integrations Nod needs to this VM. Integrations attached
with
auto:allreach it too; see attaching integrations. - Keep the VM for Nod. Anyone who can SSH in can read
.env, and Shelley on the VM can too.
Keep its memory#
Conversations, schedules, memory, the vault, workspace files and browser
logins live in Docker volumes on the VM's disk, and survive restarts and
reboots. The keys that unlock them are in .env. Nod's
backup.sh copies everything into one folder; see
Back up and restore. Copy backups off the VM,
too. On your computer:
rsync -av my-nod.exe.xyz:backups/ ./nod-backups/
A backup holds the vault key and your conversations. Keep it encrypted and private.
Setup and upkeep#
No need to read on unless you're curious, or doing it yourself.
Install by hand
On your computer (pick another name if my-nod is taken):
ssh exe.dev new --name=my-nod --disk=50GB
ssh my-nod.exe.xyz
A new VM has 2 vCPUs and 8 GB of memory, Nod's suggested starting size.
The disk needs room for about 18 GB of images and their build. All
remaining commands run on the VM, as exedev. Check the disk first:
df -h /
If it shows less than 45 GB, grow it from your computer with
ssh exe.dev resize my-nod --disk=50GB, then run
sudo resize2fs $(findmnt -no SOURCE /) on the VM.
Build and start Nod#
Turn on Docker so the containers start after a reboot, fetch the pinned
source, and let Nod's setup.sh generate .env with the access token,
vault key and database password:
sudo systemctl enable --now docker.service
git clone --branch nod-v0.7.5 --depth 1 https://github.com/n8n-io/nod.git ~/nod
cd ~/nod/deployment/self-host
sh setup.sh
Point Nod at the VM's address. Port 8000 is the one
https://<vm>.exe.xyz/ reaches; the server stays on loopback, where the
exe.dev proxy finds it. Then add the two model connections through the
LLM integration:
sed -i -e 's/^PORT=.*/PORT=8000/' \
-e "s|^NOD_PUBLIC_URL=.*|NOD_PUBLIC_URL=https://$(hostname).exe.xyz|" .env
cat >> .env <<'EOF'
AZURE_OPENAI_ENDPOINT=https://llm.int.exe.xyz/v1
AZURE_OPENAI_API_KEY=exe-llm-integration
AZURE_OPENAI_MODEL=gpt-6.1-sol
OPENAI_COMPATIBLE_BASE_URL=https://llm.int.exe.xyz/v1
LLM_PROVIDER=azure
EOF
grep -E '^(PORT|NOD_BIND_ADDRESS|NOD_PUBLIC_URL)=' .env
Expect PORT=8000, NOD_BIND_ADDRESS=127.0.0.1 and your VM's
https:// address. Leave Nod's https profile off: exe.dev's proxy
already handles HTTPS.
Build and start the stack. On 2 vCPUs this takes about 12 minutes, most of it compiling the workspace's tools:
docker compose up -d --build --wait
docker compose ps --format '{{.Service}}: {{.Status}}'
Expect six services Up, with server, postgres, browser and
workspace-network (healthy). Then check that Nod answers on its
address and wants its token:
curl -s -o /dev/null -w '%{http_code}\n' -H "Host: $(hostname).exe.xyz" http://127.0.0.1:8000/api/settings
docker compose logs server | grep 'Nod is ready'
Expect 401 and Nod is ready at https://<vm>.exe.xyz. A 403 means
NOD_PUBLIC_URL doesn't match the VM's address.
Check what the agent can reach#
The workspace and browser should be cut off from exe.dev's integrations; the server, which makes the model calls, should not:
P=$(grep ^COMPOSE_PROJECT_NAME= .env | cut -d= -f2)
docker exec nod-workspace-$P curl -sS -m 10 -o /dev/null https://llm.int.exe.xyz/v1/models; echo "workspace: $?"
docker exec nod-workspace-$P curl -sS -m 10 -o /dev/null -w 'internet: %{http_code}\n' https://example.com/
docker exec $P-server-1 node -e 'fetch("https://llm.int.exe.xyz/v1/models").then(r => console.log("server:", r.status))'
Expect Couldn't connect to server and workspace: 7, then
internet: 200 and server: 200. The browser's block is inside Nod; ask
Nod to open https://reflection.int.exe.xyz/ in its browser, and it
reports that the page didn't load.
First backup#
mkdir -p ~/backups && chmod 700 ~/backups
sh backup.sh ~/backups/nod-$(date +%F)
ls -A ~/backups/nod-$(date +%F)
Expect Backup saved, then .env, postgres.dump, four volume archives,
source-commit and complete.
Back up and restore
Nod's backup.sh stops the server, browser and workspace while it copies
the database, the four data volumes, .env and the source commit into a
new folder, then starts them again. On the VM:
cd ~/nod/deployment/self-host
sh backup.sh ~/backups/nod-$(date +%F-%H%M)
Restore into a fresh installation, so the original stays as it was until
you've checked the copy. Clone the backup's commit into a new folder; on
the VM, replacing BACKUP with the backup folder's name:
B=~/backups/BACKUP
git clone https://github.com/n8n-io/nod.git ~/nod-restored
git -C ~/nod-restored checkout "$(cat $B/source-commit)"
cd ~/nod-restored/deployment/self-host
sh restore.sh "$B" nod-restored
Stop the original, so two copies don't run the same schedules or answer the same bot, then start the restored one on the same port:
(cd ~/nod/deployment/self-host && docker compose stop)
docker compose up -d --build --wait
Open Nod with the same token and check your history, files, models and
channels. Once you're happy, keep ~/nod-restored as your installation.
Nod's operations guide
has the details.
Update
Read the releases first, and take a backup. Database migrations run on start, so an older version can't open an upgraded database: roll back by restoring the backup. On the VM, with the tag you chose:
cd ~/nod/deployment/self-host
docker compose stop
git fetch --depth 1 origin tag nod-v0.7.5
git checkout nod-v0.7.5
docker compose up -d --build --wait
After changing only .env, apply it with docker compose up -d --wait;
docker compose restart keeps the old values. Keep
COMPOSE_PROJECT_NAME as it is: it selects your data volumes.
The build cache grows with each update. docker builder prune -f frees it.
Something stuck?
Ask Shelley, or check on the VM:
cd ~/nod/deployment/self-host
docker compose ps
docker compose logs --tail 100 server
This host is not permittedorThis origin is not permitted.NOD_PUBLIC_URLin.envmust be exactlyhttps://<vm>.exe.xyz, with no port or slash. Fix it, thendocker compose up -d --wait.- The page doesn't load at all. Check that the server listens with
ss -ltn | grep 8000, and thatssh exe.dev share show my-nodsays port 8000. - The build stops with
no space left on device. Grow the disk (see Install by hand) and run the build again; it reuses what it finished. - A model request fails. Check the integration on the VM with
curl -s https://llm.int.exe.xyz/v1/models | head -c 300. If that fails, the VM has no LLM integration attached; see the LLM integration docs. - Containers missing after a reboot. Run
sudo systemctl enable --now docker.service; the restart policy brings them back.
Frequently asked questions#
What is Nod?
A personal agent from n8n Labs, released as a research preview on 10 November 2026. It has its own computer, a Linux workspace and a Chromium browser, and works in your apps and on websites, asking before it acts for you. It's separate from n8n, open source under Apache-2.0, and built on the Pi agent runtime.
Why run it on a server?
Nod's schedules, nudges and channels only run while the computer running it is on and awake. Its site suggests a Mac mini or a server of your own. A VM is always on and you don't keep a laptop open. The desktop app and phone can still connect to it.
What does it cost?
Nod is free. The VM is part of your exe.dev plan; it uses the default 8 GB of memory and a 50 GB disk. Models through the LLM integration use your exe.dev LLM allocation, or your own provider if you connect a key in Nod. Nod's Usage page estimates each task's cost, and Nod quotes a monthly estimate when you approve a schedule: a test that ran every two minutes on GPT-6.1 Sol came to over $500 a month, so keep schedules sparse. Nod suggests starting at 2 CPUs and 8 GB; idle, the whole stack used under 1 GB.
Can I use Claude, or my ChatGPT subscription?
Nod can't point its Anthropic or OpenAI connections at another address, so add an Anthropic API key in Settings → Models, or choose OpenAI → Sign in with ChatGPT. On a server, that sign-in ends on a page that doesn't load; paste its address into Callback URL. To keep the subscription off the VM instead, set the LLM integration's OpenAI source to your ChatGPT subscription; Nod's Azure connection goes through it. We didn't test these, since they need your accounts.
How is this different from Nod's guides for Hetzner, DigitalOcean or boxd?
Those give you a machine. Here, exe.dev's proxy provides HTTPS and your exe.dev login in front of Nod's token, so there's no SSH tunnel, domain, open ports or firewall rules. Models come through exe.dev with no key on the VM, and the VM is a fixed part of your plan, not billed by the hour.
Is it stable?
It's a research preview that ships several releases a day. This page pins and was tested with the source of nod-v0.7.5 (13 November 2026). Back up before you update, and update on purpose.
Updated Nov 13, 2026 · tested end to end Nov 13, 2026 · Markdown · manifest.json · Something wrong? Tell us