TL;DR: I moved my OpenClaw setup from a Jetson Nano to a VPS. Persistent block volume for state, Node 24 LTS instead of a hand-compiled Node 22, and the whole migration took about 20 minutes once I stopped fighting ARM constraints.
Why leave the Jetson Link to heading
I’ve been running OpenClaw on a Jetson Nano since February. It worked, but the maintenance cost kept climbing. The Nano runs Ubuntu 18.04 with an ancient glibc, so I had to compile Node 22 from source (27 hours). Bun global installs broke when OpenClaw tightened plugin manifest validation. Upgrades were a gamble.
I’d spent more time maintaining the runtime environment than using the assistant. The Jetson made for a fun experiment, an always-on AI assistant on a tiny ARM board. But the old OS tax had compounded past the point of being worth it.
The new setup Link to heading
I had a VPS sitting idle on an OpenStack provider. x86_64, Ubuntu 22.04, 8 vCPUs, 16GB RAM. Modern glibc, prebuilt Node binaries. No more cross-compiling.
The one catch: the VM boots from an ephemeral image disk. If the instance gets rebuilt or terminated, the disk goes with it. OpenClaw’s state (config, memory, Telegram sessions) needs to survive that.
Persistent storage Link to heading
I created a 10GB block volume via the OpenStack CLI and attached it to the VM:
source ~/.config/openstack/my-openrc.sh
openstack volume create --size 10 \
--description "Persistent storage" my-data
openstack server add volume my-vm my-data
On the VM, format and mount it:
sudo mkfs.ext4 -L my-data /dev/vdb
sudo mkdir -p /mnt/data
sudo mount /dev/vdb /mnt/data
Add it to fstab with nofail so the VM still boots if the volume gets detached:
echo 'LABEL=my-data /mnt/data ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab
Then symlink OpenClaw’s state directory to the persistent volume:
sudo chown $USER:$USER /mnt/data
mkdir -p /mnt/data/openclaw-home
ln -s /mnt/data/openclaw-home ~/.openclaw
Now ~/.openclaw points to the block volume. If the VM dies, I attach the volume to a new instance, recreate the symlink, and pick up where I left off.
Installing Node 24 Link to heading
No more building from source. nvm works fine on a modern x86_64 Ubuntu:
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install 24
Node 24.14.1 LTS. Installed in seconds.
Installing OpenClaw Link to heading
npm install -g openclaw
I went from OpenClaw 2026.4.2 on the Jetson to 2026.4.8 on the new VM. No shebang hacks, no Bun shims. npm global install works on a system where the runtime isn’t fighting the OS.
Migrating the state Link to heading
Same as with my earlier upgrades: OpenClaw’s state lives under ~/.openclaw. The binary package is disposable. Config, memory, Telegram sessions, and workspace are what matter.
On the old machine:
sudo systemctl stop openclaw-gateway
tar czf /tmp/openclaw-migrate.tar.gz -C ~/.openclaw .
Transfer to the new VM (I went via my laptop since the two machines can’t reach each other directly):
scp old-host:/tmp/openclaw-migrate.tar.gz /tmp/
scp /tmp/openclaw-migrate.tar.gz new-host:/tmp/
On the new VM:
tar xzf /tmp/openclaw-migrate.tar.gz -C ~/.openclaw
Verify checksums at each hop. My first transfer produced a corrupt archive that extracted with gzip errors. A re-transfer fixed it, but I’d have been in trouble if I hadn’t checked.
The only config change needed was updating home directory paths. The old machine used a different username:
sed -i 's|/home/olduser|/home/newuser|g' ~/.openclaw/openclaw.json
The Telegram bot token Link to heading
If you’re running OpenClaw with Telegram, the bot token can only have one active polling connection. Running two instances with the same token causes conflicts. One instance will keep disconnecting the other.
Since I was migrating rather than running both in parallel, I stopped the old service before starting the new one. The Telegram session data (~/.openclaw/telegram/) transferred without issues and the bot reconnected on the new machine without re-pairing.
Systemd service Link to heading
The service file is simpler on a system where Node lives in a normal path:
[Unit]
Description=OpenClaw Gateway
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu
Environment=OPENCLAW_GATEWAY_PORT=18789
Environment=OPENCLAW_GATEWAY_TOKEN=your-token-here
ExecStart=/home/ubuntu/.nvm/versions/node/v24.14.1/bin/node \
/home/ubuntu/.nvm/versions/node/v24.14.1/lib/node_modules/openclaw/openclaw.mjs \
gateway run --port 18789 --bind loopback
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable openclaw-gateway
sudo systemctl start openclaw-gateway
Verify:
curl -s http://127.0.0.1:18789/health
# {"ok":true,"status":"live"}
Don’t forget to disable the old one Link to heading
After confirming everything works on the new machine, go back to the old one and disable the service so it doesn’t start on reboot:
ssh old-host "sudo systemctl disable openclaw-gateway"
I almost forgot this. The old service was stopped but still enabled, one reboot away from a Telegram bot token conflict.
What I gained Link to heading
| Jetson Nano | VPS | |
|---|---|---|
| OS | Ubuntu 18.04 (EOL) | Ubuntu 22.04 LTS |
| CPU | 4x ARM Cortex-A57 | 8x x86_64 vCPUs |
| RAM | 4GB | 16GB |
| Node install | 27 hours (source) | 10 seconds (prebuilt) |
| Node version | 22.22.0 | 24.14.1 LTS |
| OpenClaw upgrade | prayer and clean reinstalls | npm update -g openclaw |
| Storage | local eMMC | persistent block volume |
The Jetson proved I could run an AI assistant on minimal ARM hardware at the edge. The VPS lets me stop thinking about the runtime and focus on using the thing.
Further reading Link to heading
- Installing OpenClaw on a Jetson Nano (the original setup)
- Upgrading OpenClaw to Latest on Jetson Nano with Node 22 (the 27-hour Node compilation)
- OpenClaw documentation
- OpenStack Cinder volumes