---
title: "Self-host Nod, n8n's personal agent, on a server that stays on"
description: "Run Nod's server on an exe.dev VM: n8n's personal agent with its own browser and workspace, behind your exe.dev login, with GPT through exe.dev."
url: https://exe-staging.dev/deploy/nod
category: "AI agents"
updated: 2026-11-13
---

# 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.

- **Software:** Nod (https://nod.n8n.io)
- **Source:** https://github.com/n8n-io/nod
- **License:** Apache-2.0
- **Time:** 20 minutes
- **Example VM name:** `my-nod` (yours will differ; on the VM, `hostname` prints it)
- **Machine-readable:** https://exe-staging.dev/deploy/nod/manifest.json

## 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`

Running on the VM:

- **Nod server**: built from the nod-v0.7.5 source in Docker Compose; restarts with Docker, port 8000, data in `~/nod/deployment/self-host/.env and the server-data volume`
- **PostgreSQL 17**: postgres:17-alpine, private to the stack, data in `postgres-data volume`
- **Workspace**: Nod's Linux sandbox container, behind its own firewall container, data in `workspace-data and workspace-tools volumes`
- **Browser**: Chromium in its own container, data in `browser-data volume`
- **Models**: GPT-6.1 Sol and open models through exe.dev's LLM integration

How it is reached:

- https://my-nod.exe.xyz/ (private): Nod's web app and API, behind your exe.dev login and then Nod's access token

## Deploy with Shelley

Open https://exe-staging.dev/new?prompt=Set%20up%20Nod%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Fnod.md%20from%20top%20to%20bottom.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-nod.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-nod.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AThis%20recipe%20needs%20a%2050GB%20disk%2C%20and%20a%20new%20VM%27s%20may%20be%20smaller.%20Before%20you%20install%20anything%2C%20run%20%60df%20-h%20%2F%60.%20If%20its%20size%20is%20under%2045G%2C%20stop%20and%20ask%20me%20to%20grow%20the%20disk%2C%20either%20with%20this%20link%3A%20https%3A%2F%2Fexe.dev%2Fsuggest%3Fcommand%3Dresize%2520my-nod%2520--disk%253D50GB%20or%2C%20on%20my%20computer%2C%20with%20%60ssh%20exe.dev%20resize%20my-nod%20--disk%3D50GB%60.%20When%20I%20say%20it%27s%20done%2C%20run%20%60sudo%20resize2fs%20%22%24%28findmnt%20-no%20SOURCE%20%2F%29%22%60%2C%20check%20%60df%20-h%20%2F%60%20again%2C%20and%20carry%20on.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20Nod%27s%20server%2C%20PostgreSQL%2C%20browser%20and%20workspace%20containers%20built%20from%20nod-v0.7.5%2C%20healthy%20and%20set%20to%20start%20again%20after%20a%20reboot%0A-%20Nod%20at%20%60https%3A%2F%2F%3Cvm%3E.exe.xyz%2F%60%2C%20behind%20your%20exe.dev%20login%20and%20Nod%27s%20own%20access%20token%0A-%20GPT-6.1%20Sol%20through%20exe.dev%27s%20LLM%20integration%20as%20the%20first%20model%2C%20with%20no%20API%20key%20on%20the%20VM%0A-%20Nod%27s%20workspace%20and%20browser%20checked%20to%20be%20unable%20to%20reach%20exe.dev%27s%20integrations%0A-%20A%20first%20backup%20in%20%60~%2Fbackups%60%0A%0ARead%20the%20whole%20recipe%2C%20including%20the%20closed%20details.%20For%20initial%20setup%2C%0Afollow%20%22Install%20by%20hand%22%20first%2C%20skipping%20VM%20creation%20and%20SSH%20but%20doing%0Athe%20disk%20check.%20The%20opening%20walkthrough%20is%20for%20the%20owner.%20Build%20exactly%0Athe%20pinned%20tag.%20The%20build%20takes%20about%2012%20minutes%3A%20run%20it%20in%20tmux%20or%20with%0Aa%20long%20timeout%2C%20and%20don%27t%20interrupt%20it.%20Do%20not%20run%20the%20restore%20or%20update%0Ainstructions%2C%20and%20don%27t%20reboot.%0AKeep%20the%20VM%20private%3A%20never%20run%20share%20set-public%2C%20keep%20NOD_BIND_ADDRESS%0Aat%20127.0.0.1%2C%20and%20don%27t%20remove%20or%20change%20the%20workspace-network%20service.%0AOn%20an%20existing%20VM%2C%20ask%20before%20replacing%20anything%20that%20listens%20on%20port%0A8000.%20Never%20print%20NOD_VAULT_KEY%20or%20NOD_POSTGRES_PASSWORD.%0AVerify%20every%20check%20in%20%22Install%20by%20hand%22%2C%20including%20both%20blocked%0Aintegration%20checks%2C%20then%20take%20the%20first%20backup%20with%20backup.sh.%0AFinish%20by%20giving%20the%20owner%20https%3A%2F%2F%3Cvm%3E.exe.xyz%2F%20and%20the%20value%20of%0ANOD_AUTH_TOKEN%2C%20and%20point%20them%20to%20%22Open%20Nod%22.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A to create a VM whose agent, Shelley, follows this recipe. From a terminal:

```sh
curl -fsSL https://exe-staging.dev/deploy/nod/prompt.txt | ssh exe.dev new --disk=50GB --prompt=/dev/stdin
```

It needs a 50 GB disk. The terminal command makes the VM that size; after the button, Shelley checks and, if the disk is smaller, gives you a link to grow it.

Or follow the steps below by hand.

[Nod](https://nod.n8n.io) 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](/docs/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](/docs/integrations-llm), 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.

## 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:

```bash
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 -sm` in 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](https://nod.n8n.io/docs/get-started/install-desktop/)
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](https://t.me/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 as `fireworks/kimi-k3` and `fireworks/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](#update) for how to apply it:

```bash
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](/docs/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-network` service in
  `compose.yaml`.
- Attach only the integrations Nod needs to this VM. Integrations attached
  with `auto:all` reach it too; see [attaching integrations](/docs/integrations-attach).
- 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](#back-up-and-restore). Copy backups **off the VM**,
too. On your computer:

```bash
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.

<details id="create-the-vm" data-manual-setup class="dp-details">
<summary>Install by hand</summary>

On your computer (pick another name if `my-nod` is taken):

```bash
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:

```bash
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:

```bash
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:

```bash
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:

```bash
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:

```bash
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:

```bash
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

```bash
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`.

</details>

<details id="back-up-and-restore" class="dp-details">
<summary>Back up and restore</summary>

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:

```bash
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:

```bash
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:

```bash
(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](https://nod.n8n.io/docs/deploy/server-operations/)
has the details.

</details>

<details id="update" class="dp-details">
<summary>Update</summary>

Read the [releases](https://github.com/n8n-io/nod/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:

```bash
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.

</details>

<details id="troubleshooting" class="dp-details">
<summary>Something stuck?</summary>

Ask Shelley, or check on the VM:

```bash
cd ~/nod/deployment/self-host
docker compose ps
docker compose logs --tail 100 server
```

- **`This host is not permitted` or `This origin is not permitted`.**
  `NOD_PUBLIC_URL` in `.env` must be exactly `https://<vm>.exe.xyz`, with no
  port or slash. Fix it, then `docker compose up -d --wait`.
- **The page doesn't load at all.** Check that the server listens with
  `ss -ltn | grep 8000`, and that `ssh exe.dev share show my-nod` says port
  8000.
- **The build stops with `no space left on device`.** Grow the disk (see
  [Install by hand](#create-the-vm)) 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](/docs/integrations-llm).
- **Containers missing after a reboot.** Run
  `sudo systemctl enable --now docker.service`; the restart policy brings
  them back.

</details>

## 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](/deploy/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](https://exe.dev/pricing); it uses the default 8 GB of memory and a 50 GB disk. Models through the [LLM integration](/docs/integrations-llm) 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](/docs/integrations-llm); 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.


## Related

- [Run the Pi coding agent on a remote server](https://exe-staging.dev/deploy/pi.md): An agent that doesn't ask first, on a computer that can take it.
- [Host a Pi Durable agent](https://exe-staging.dev/deploy/pi-durable.md): An agent that picks up where it left off, even after kill -9.
- [Self-host OpenMausBot, the open-source Grok Bot alternative](https://exe-staging.dev/deploy/openmausbot.md): A team of AI bots, each with a computer that isn't your laptop.
- [Host OpenClaw](https://exe-staging.dev/deploy/openclaw.md): An AI sidekick with its own computer. Your laptop can take a nap.
- [Self-host Hermes Agent](https://exe-staging.dev/deploy/hermes-agent.md): An agent that remembers you, on a computer that never sleeps.
- [Self-host n8n](https://exe-staging.dev/deploy/n8n-2.md): Connect your apps. Let the boring bits run themselves.
