aiproductivitytoolingdeveloper-experiencedevopsopenclaw

Setting Up a Persistent AI Agent on a VPS with OpenClaw

How to run OpenClaw on a DigitalOcean VPS, lock it down with Tailscale, and sync everything to Obsidian with Syncthing.

·11 min read
Disclosure: This post contains affiliate links. We earn commissions when you shop through the links below.

This is Part 4 of my AI coding workflow series. Part 1 covers terminal agents. Part 2 covers editor-level AI. Part 3 covers PR-level agents. This post goes deeper: running a persistent AI agent on a remote server using OpenClaw.

Why run an AI agent on a VPS?

Running AI agents locally works, but has limitations:

  • My laptop sleeps, travels, runs out of battery
  • Long-running tasks get interrupted
  • Can't easily hand off to mobile or other devices

The fix: run OpenClaw on a cheap VPS that's always on, accessible from anywhere via Tailscale VPN, with automatic backups to my Obsidian vault via Syncthing.

I recommend DigitalOcean for this setup because the lowest-tier droplets are enough to run OpenClaw, Tailscale, and Syncthing reliably.

Here's the stack:

┌─────────────────┐     ┌─────────────────┐
│   Your Mac      │────▶│  Tailscale VPN  │
│   (Obsidian)    │◀────│  (encrypted)    │
└─────────────────┘     └─────────────────┘
                               │
                               ▼
                        ┌─────────────────┐
                        │  DigitalOcean   │
                        │  VPS ($12/mo)   │
                        │  ─────────────  │
                        │  OpenClaw       │
                        │  Syncthing      │
                        │  Tailscale      │
                        └─────────────────┘

Not technical? Use an AI assistant

If you're not comfortable with command-line setup, you can use Claude Code or Codex directly on your server to do it for you.

Once you have SSH access to your VPS:

# Install Node.js first (required for terminal AI tools)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs

# Then install your preferred AI coding assistant:
# Option A: Claude Code
sudo npm install -g @anthropic-ai/claude-code

# Option B: Codex CLI
sudo npm install -g @openai/codex

Then run claude or codex and authenticate. Once connected, ask it to:

"I have already installed Node.js. Now, follow this guide to set up OpenClaw with Tailscale and Syncthing. My username is <your_user>."

The AI can run the commands, troubleshoot errors, and adapt to your setup. Once OpenClaw is running, it becomes that assistant permanently.


1. DigitalOcean VPS setup

Create the droplet

  1. Sign up / log in at DigitalOcean
  2. Click Create → Droplets
  3. Choose your configuration:
    • Region: Pick something geographically close (London or Singapore from Thailand both work)
    • Image: Ubuntu 24.04 LTS
    • Size: Regular (shared CPU), 2GB / 1 vCPU ($12/mo) is plenty. The AI runs in the cloud; the VPS just needs to run the CLI and Syncthing
    • Authentication: SSH Key (we'll set this up next)
  4. Give it a hostname like openclaw and create it
  5. Note the public IP address once it's provisioned

Initial server hardening

Once you can SSH in, do the basics:

# Update everything
apt update && apt upgrade -y

# Create a non-root user (replace <your_user> with your username)
adduser <your_user>
usermod -aG sudo <your_user>

# Copy your SSH key to the new user
mkdir -p /home/<your_user>/.ssh
cp ~/.ssh/authorized_keys /home/<your_user>/.ssh/authorized_keys
chown -R <your_user>:<your_user> /home/<your_user>/.ssh
chmod 700 /home/<your_user>/.ssh
chmod 600 /home/<your_user>/.ssh/authorized_keys

# Disable root login and password auth
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd

Install Node.js

OpenClaw requires Node.js:

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --version  # confirm v22+

Install OpenClaw

npm install -g openclaw

Run through the setup wizard:

openclaw onboard

Check the OpenClaw documentation for configuration options.


2. Tailscale VPN setup

Tailscale gives you a private, encrypted mesh network between your devices. No need to expose SSH to the public internet.

Install on the VPS

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

This prints an auth URL. Open it, log in to your Tailscale account (or create one), and authorise the device.

Install on your Mac

# Via Homebrew
brew install --cask tailscale

# Or download from https://tailscale.com/download/mac

Open the Tailscale app, sign in with the same account, and connect.

Verify the connection

# On your Mac, check both devices are visible
tailscale status

# You should see both your Mac and the VPS listed with their Tailscale IPs (100.x.x.x)

In the Tailscale admin console:

  1. Find your VPS machine
  2. Click the ... menu → Disable key expiry

This prevents the VPS from dropping off the network when the auth key expires.


3. SSH key setup on Mac

Generate a key

# Ed25519 is modern and preferred
ssh-keygen -t ed25519 -C "your-email@example.com"

# Accept the default path (~/.ssh/id_ed25519)
# Set a passphrase (recommended)

Add the public key to DigitalOcean

Either:

  • During droplet creation: Paste the contents of ~/.ssh/id_ed25519.pub into the SSH key field
  • After creation: Copy it to the server manually:
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@<DROPLET_PUBLIC_IP>

Set up your SSH config

Edit ~/.ssh/config:

Host openclaw
    HostName 100.x.x.x  # Tailscale IP of your VPS
    User <your_user>
    IdentityFile ~/.ssh/id_ed25519

Now you can just run ssh openclaw from anywhere on your Tailscale network.


4. Accessing via Tailscale only

Once both your Mac and the VPS are on Tailscale, stop using the public IP for SSH and use the Tailscale IP instead.

Lock down the firewall

On the VPS, restrict SSH to only Tailscale:

# Allow SSH only on the Tailscale interface
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow in on tailscale0 to any port 22
sudo ufw enable

SSH is now only accessible through your Tailscale VPN, not from the public internet.

MagicDNS (optional)

Tailscale's MagicDNS lets you use hostnames instead of IPs:

ssh <your_user>@openclaw  # if your machine is named "openclaw" in Tailscale

Enable it in the Tailscale admin console under DNS → MagicDNS.


5. Obsidian setup

Obsidian is a markdown-based knowledge management tool. We'll use it to store conversation logs and project files from the agent.

Install on Mac

Download from obsidian.md or:

brew install --cask obsidian

Create your vault

  1. Open Obsidian
  2. Create new vault → name it something like openclaw-vault
  3. Choose a location, e.g. ~/Documents/openclaw-vault
  4. This is where all your synced files will live
openclaw-vault/
├── clawd/              # ← synced from the server
│   ├── projects/
│   ├── conversations/
│   └── memory/
├── notes/              # Your own notes
├── templates/          # Obsidian templates
└── README.md

6. Syncthing: bidirectional vault sync

Syncthing provides continuous, encrypted, peer-to-peer file sync. No cloud middleman.

Install on the VPS

# Add the Syncthing repo
sudo curl -o /usr/share/keyrings/syncthing-archive-keyring.gpg \
  https://syncthing.net/release-key.gpg

echo "deb [signed-by=/usr/share/keyrings/syncthing-archive-keyring.gpg] \
  https://apt.syncthing.net/ syncthing stable" | \
  sudo tee /etc/apt/sources.list.d/syncthing.list

sudo apt update
sudo apt install -y syncthing

Run as a systemd service

# Enable and start for your user
sudo systemctl enable syncthing@<your_user>
sudo systemctl start syncthing@<your_user>

# Check it's running
systemctl status syncthing@<your_user>

Install on Mac

brew install syncthing
brew services start syncthing

Access the Syncthing web UI

On your Mac, Syncthing's UI runs at http://127.0.0.1:8384.

For the VPS, access it via SSH tunnel:

ssh -L 8385:localhost:8384 openclaw

Then open http://127.0.0.1:8385 in your browser.

Connect the devices

  1. On the Mac's Syncthing UI: go to Actions → Show ID and copy the device ID
  2. On the VPS's Syncthing UI: click Add Remote Device and paste the Mac's device ID
  3. Accept the pairing on both sides

Share the Obsidian vault folder

  1. On the Mac's Syncthing UI: click Add Folder
    • Folder Path: ~/Documents/openclaw-vault
    • Folder ID: openclaw-vault (must match on both sides)
    • Share with: your VPS device
  2. On the VPS, accept the incoming folder share
    • Set the folder path to /home/<your_user>/openclaw-vault

Verify sync

Create a test file on your Mac:

echo "sync test" > ~/Documents/openclaw-vault/test.md

After a few seconds, check on the VPS:

cat ~/openclaw-vault/test.md
# Should show "sync test"

Syncthing ignore patterns

Create a .stignore file in the vault root to skip files you don't need synced:

// .stignore
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.DS_Store
*.tmp

Configure OpenClaw to write directly into the synced vault.

Set your clawd working directory to be inside the vault:

# OpenClaw writes directly to the vault
mkdir -p /home/<your_user>/openclaw-vault/clawd

# Set this path as workspace in your openclaw config
# agents.defaults.workspace in ~/.openclaw/openclaw.json

If you prefer keeping clawd in its own location:

mkdir -p /home/<your_user>/clawd
ln -s /home/<your_user>/clawd /home/<your_user>/openclaw-vault/clawd

Note: If using symlinks, enable "Follow Symlinks" in Syncthing's folder settings under Advanced.

What this gives you

Once wired up:

  • OpenClaw writes files, logs, and project data to the vault
  • Syncthing picks up changes and syncs them to your Mac
  • Obsidian on your Mac sees everything with full markdown rendering
  • Changes flow both ways: add notes in Obsidian and they sync back to the server

8. Secure web access with Tailscale Serve

OpenClaw has a web interface. Instead of exposing it to the public internet, use Tailscale Serve to make it accessible only within your Tailscale network.

Why Tailscale Serve?

  • Services only accessible from devices on your Tailscale network
  • Automatic HTTPS with valid certificates for your *.ts.net domain
  • Works through NATs and firewalls without port forwarding

Set up Tailscale Serve

On the VPS, expose the OpenClaw gateway (default port 18789):

# Serve the gateway over HTTPS on your Tailscale network
sudo tailscale serve --bg https / http://localhost:18789

This makes the service available at https://<your-vps-hostname>.<tailnet-name>.ts.net/.

Exposing multiple services

# OpenClaw gateway on /
sudo tailscale serve --bg https / http://localhost:18789

# Syncthing UI on a separate port
sudo tailscale serve --bg --https=8384 http://localhost:8384

Check running services

tailscale serve status

Access from any device

Once configured, access your services from any device on your Tailscale network:

  • Mac/PC: Open https://openclaw.<your-tailnet>.ts.net/ in browser
  • Mobile: Install Tailscale app, connect, then access the same URL

Security notes

  • Only devices authenticated to your Tailscale network can access these URLs
  • You can further restrict access using Tailscale ACLs
  • No need to open any ports on your firewall

9. Gateway web UI and device pairing

When you first visit the OpenClaw web UI, you might see "disconnected (1008): pairing required". The gateway needs to approve your browser as a trusted device.

Approve your browser

On the VPS, check for pending device requests:

openclaw devices list

You'll see something like:

Pending (1)
┌──────────────────────────────────────┬────────────────────────────────────┬──────────┐
│ Request                              │ Device                             │ Role     │
├──────────────────────────────────────┼────────────────────────────────────┼──────────┤
│ 44e05baf-ae0b-4a5f-b640-04195b8acca9 │ 2286fb5a55e891dcb8f6c8c76645c387...│ operator │
└──────────────────────────────────────┴────────────────────────────────────┴──────────┘

Approve it:

openclaw devices approve <request-id>

Refresh the browser and you should be connected.

Getting your gateway token

If the UI prompts for a token, find it in your config:

grep '"token"' ~/.openclaw/openclaw.json

Or check ~/.openclaw/openclaw.json under gateway.auth.token.

Managing devices

# List all devices (pending and paired)
openclaw devices list

# Revoke a device
openclaw devices revoke <device-id>

# Rotate a token
openclaw devices rotate <role>

Quick reference

ComponentMacVPS
TailscaleApp or brew install --cask tailscalecurl -fsSL https://tailscale.com/install.sh | sh
SSHssh openclaw (via ~/.ssh/config)Locked to Tailscale interface only
Syncthingbrew install syncthinglocalhost:8384apt install syncthing → systemd service
Obsidianbrew install --cask obsidianNot needed on server
OpenClawOptional (for local use)npm install -g openclaw

Ports and access

ServicePortAccess
SSH22Tailscale only (tailscale0 interface)
Syncthing Web UI8384Localhost or Tailscale Serve
Syncthing Sync22000Tailscale only
OpenClaw Gateway18789Tailscale Serve (https://<hostname>.<tailnet>.ts.net/)

Troubleshooting

Syncthing not syncing? Check systemctl status syncthing@<your_user> on the VPS. Make sure both devices show as "Connected" in the web UI.

Can't SSH via Tailscale? Run tailscale status on both devices. If the VPS shows as offline, run sudo tailscale up again.

Symlink not syncing? Enable "Follow Symlinks" in Syncthing's folder settings, or switch to the direct path approach.

Obsidian not seeing new files? Obsidian watches the filesystem, but large syncs can take a moment. Try closing and reopening the vault.

OpenClaw auth issues? Run openclaw doctor on the VPS to check auth status. See OpenClaw authentication docs for setup.

Gateway shows "pairing required"? Run openclaw devices list and approve the pending request with openclaw devices approve <request-id>.


What's next

With this setup running:

  • Persistent AI agent that's always on
  • Secure access from anywhere via Tailscale
  • Automatic backup of agent output to Obsidian
  • Bidirectional sync between server and local

From here you could:

  • Add more Syncthing folders (code repos, notes)
  • Configure OpenClaw with custom skills and cron jobs
  • Connect chat channels (Telegram, Slack, Discord)
  • Build dashboards to monitor agent activity

The VPS becomes your AI command center: cheap, always available, and you control all of it.