# Self-Host Openclaw

Self-Host Openclaw (Clawdbot) in a Proxmox VM (The Secure Way)

# Self-Host Openclaw (Clawdbot) in a Proxmox VM (The Secure Way)

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-"></div>### Self‑Hosting Openclaw (Clawdbot) on Proxmox VM – Secure Setup

This guide walks through a security‑focused Openclaw (formerly Clawdbot/Moltbot) deployment on Proxmox using a dedicated Ubuntu VM, a non‑privileged user, and a localhost‑only gateway.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--1">---

</div>#### 1. Why a VM and not LXC

Openclaw is an AI agent with shell access, persistent storage, and plugins, so a compromise of the agent can become a compromise of the host if isolation is weak.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-lxc-containers-share">- LXC containers share the host kernel; a container escape could give an attacker access to the Proxmox host.
- A Proxmox VM uses hypervisor isolation: if the VM is compromised, you can destroy it and your Proxmox host remains protected.

</div>##### Additional prerequisites (strongly recommended):

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-up%E2%80%91to%E2%80%91date-proxmox-h">- Up‑to‑date Proxmox host with QEMU agent support.
- Router firewall + IDS/IPS as appropriate.
- Regular backups of important data (treat this VM as disposable).

---

</div>#### 2. Create the Proxmox VM

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-in-proxmox%2C-create-a">1. In Proxmox, create a new VM, name it e.g. `openclaw`.
2. OS:
    
    
    - Use Ubuntu Server 24.04 ISO (or similar) as the installation media.
3. System settings:
    
    
    - Machine: default (q35) is fine.
    - BIOS: default.
    - CPU:
        
        
        - Cores: at least 2 vCPUs.
        - Type: `host` to expose all CPU features.
    - Memory:
        
        
        - Give more than the minimum (e.g. 4–8 GB depending on what you’ll run).
        - Disable ballooning; Node.js + plugins can use more RAM unexpectedly, and ballooning can cause instability.
    - Disk: 32 GB+ recommended (depends on logs, plugins, etc.).
4. Enable the QEMU guest agent for better integration.
5. Finish the wizard and start the VM.

</div>##### Inside the Ubuntu installer:

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-accept-most-defaults">- Accept most defaults.
- On the “SSH” step, **enable OpenSSH server** so you can use your own terminal later instead of the web console.

---

</div>#### 3. Initial Ubuntu hardening and updates

From your workstation:

```bash
 ssh youruser@<vm-ip> 
```

Then:

```bash
 sudo apt update && sudo apt upgrade -y
```

Apply security updates before installing anything else.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--2">---

</div>#### 4. Create a dedicated Openclaw user

Never run Openclaw as `root`. Use a separate, unprivileged user as a sandbox.

```bash
sudo adduser openclaw
```

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-%23-follow-prompts-for"><div class="w-full md:max-w-[90vw]"><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium">\# Follow prompts for password; optional extra info can be blank</div></div></div>Optionally restrict `sudo` for this user (recommended: no sudo at all). Then switch:

```bash
sudo su - openclaw
```

All further Openclaw‑related steps run as this **openclaw** user unless otherwise noted.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--3">---

</div>#### 5. Add swap (for Node.js compilation)

Openclaw is a Node.js package and can compile plugins and dependencies during install; lack of RAM/swap can cause failures.

As `root`:

```bash
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
```

Verify:

```bash
swapon --show 
```

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--5">---

</div>#### 6. Install Node.js and Openclaw

Still on the VM:

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-install-node.js-%28exa">1. Install Node.js (example using distro or NodeSource; adapt to your preferred method). The video uses a repository add + install flow.

</div>Example (NodeSource, adjust version as needed):

```bash
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
```

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-switch-to-the-dedica">2. Switch to the dedicated user and install Openclaw globally:

<div class="w-full md:max-w-[90vw]"><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium"><div class="translate-y-xs -translate-x-xs bottom-xl mb-xl flex h-0 items-start justify-end sm:sticky sm:top-xs"><div class="overflow-hidden border-subtlest ring-subtlest divide-subtlest bg-base rounded-full"><div class="border-subtlest ring-subtlest divide-subtlest bg-subtle"><div class="flex items-center min-w-0 gap-two justify-center"><div class="flex shrink-0 items-center justify-center size-4">  
</div></div></div></div></div></div></div></div>```bash
sudo su - openclaw
npm install -g openclaw
```

(Use the actual package name used in the docs; the video installs the “cloudbot/Openclaw” CLI globally via npm.)

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--6">---

</div>#### 7. Telegram bot setup

The example integration in the video uses Telegram, but you can map this process to any supported chat client.

From your phone/desktop Telegram client:

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-talk-to-%40botfather.-">1. Talk to `@BotFather`.
2. `/newbot` → choose a name and username.
3. Copy the **HTTP API token**; you’ll paste it in the Openclaw onboarding later.
4. In BotFather:
    
    
    - Disable group privacy so the bot can read all messages in groups (if you want group usage).
5. Get your personal Telegram user ID:
    
    
    - Talk to `@userinfobot` (or similar), send `/start`, copy the numeric user ID.

</div>Keep:

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-bot-api-token.-your-">- Bot API token.
- Your Telegram user ID.

---

</div>#### 8. Run the Openclaw onboarding wizard

From the `openclaw` user shell:

```bash
openclaw init
```

\# or the appropriate CLI command that starts the onboarding wizard

During the wizard (as shown in the video):

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-choose-manual-config">1. Choose **manual configuration**.
2. Select your LLM provider:
    
    
    - Example in the video: Anthropic, model `claude-3-opus-4.5` (adjust for current names/pricing).
    - Paste your API key.
3. **Gateway binding (critical security step)**:
    
    
    - Set the gateway bind address to **loopback only** (e.g. `127.0.0.1:PORT`).
    - This ensures the HTTP gateway listens only on the VM itself, with **no open ports to your LAN or the internet**.
4. Enable Telegram integration:
    
    
    - Paste the Telegram bot token.
    - Enter your Telegram user ID if requested as an initial allowed user.
5. Skip skills/hooks initially to keep the surface area small.

</div>The wizard may attempt to install a systemd service and report a message like “system user services unavailable” at the end. We’ll fix that manually next.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--7">---

</div>#### 9. Fixing the `USER_ID` environment gotcha

In the video, the service failed to start until an environment variable for the current user ID was exported.

As the `openclaw` user:

```bash
echo "export USER_ID=$(id -u)" >> ~/.bashrc source ~/.bashrc
```

If Openclaw expects a different variable name (e.g. `CLOUD_USER_ID` or similar), match what the docs/onboarding output indicates; the video exports the current user ID so the Node environment/compiler knows which user it is running as.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-bash-echo-%22export-us"><div class="w-full md:max-w-[90vw]"><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium"><div class="translate-y-xs -translate-x-xs bottom-xl mb-xl flex h-0 items-start justify-end sm:sticky sm:top-xs"><div class="overflow-hidden border-subtlest ring-subtlest divide-subtlest bg-base rounded-full"><div class="border-subtlest ring-subtlest divide-subtlest bg-subtle"><div class="flex items-center min-w-0 gap-two justify-center"><div class="flex shrink-0 items-center justify-center size-4"></div></div></div></div></div><div class="-mt-xl">  
</div></div></div></div><div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--8">---

</div>#### 10. Create a systemd service manually

Since the onboarding script’s service creation is unreliable, create a systemd unit yourself so Openclaw auto‑starts on boot and survives logout.

As `root`:

```bash
sudo nano /etc/systemd/system/openclaw.service 
```

Example unit file (adapt command/paths to your setup):

```text
[Unit]
Description=Openclaw AI Agent
After=network.target

[Service]
Type=simple
User=openclaw
WorkingDirectory=/home/openclaw
Environment=USER_ID=%i # or the variable you need, or drop if not required
ExecStart=/usr/bin/npx openclaw start
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
```

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-save-and-reload-syst"><div class="w-full md:max-w-[90vw]"><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium">Save and reload systemd:</div><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium">  
</div><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium">  
</div></div></div>```bash
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw.service
sudo systemctl status openclaw.service
```

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-text-%5Bunit%5D-descript"><div class="w-full md:max-w-[90vw]"><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium">  
</div><div class="codeWrapper bg-subtle text-light selection:text-super selection:bg-super/10 my-md relative flex flex-col rounded-lg font-mono text-sm font-medium">Confirm the service is **active (running)**.</div></div></div><div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--9">---

</div>#### 11. Run the built‑in security audit

Openclaw ships with a security audit command that checks configuration issues.

As `openclaw`:

```bash
openclaw audit
```

 # or the appropriate audit command

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--10">---

</div>#### 12. Pairing mechanism and Telegram test

Openclaw discourages random users from using your bot by requiring a pairing flow.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-from-telegram%2C-searc">1. From Telegram, search for your bot by its username and send any message.
2. The bot will respond with a **pairing code** instead of executing commands.
3. On the VM, in your terminal (as `openclaw`), run the pairing command (check docs; the video shows entering the code in the terminal to approve the user).
4. Once paired, you can chat normally.

</div>##### Test:

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-ask-for-the-current-">- Ask for the current date/time. Unlike a static LLM, Openclaw knows the host environment and will return the actual VM time and system details, proving shell/environment awareness.
- Ask for a nicely formatted system overview (CPU, memory, disk usage). Openclaw will run the relevant commands and format the output.
- Try asking it to locate the largest files on the server; it will preserve context between messages and refine queries.

</div>Use caution with destructive commands you authorize (e.g. cleaning npm cache); validate suggestions before approval.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--11">---

</div>#### 13. Security recap

This setup is designed so that even if Openclaw is exploited, the blast radius is contained.

##### Key decisions:

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-vm-isolation-instead">- **VM isolation** instead of LXC to avoid container‑to‑host kernel sharing.
- **Dedicated non‑root user** for Openclaw; attackers are stuck in a restricted account.
- **Loopback‑only gateway**: no inbound ports, only outbound polling of Telegram (or other clients). Telegram servers hold messages until Openclaw polls every few seconds.
- **Pairing process**: even if someone finds your Telegram bot username, they cannot use the agent without an approved pairing.
- **Security audit + manual token fix**: ensures internal tokens and permissions are correctly set.

</div>With this in place, you’re not one of the many users exposing full shell agents unauthenticated on the public internet.

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk--12">---

</div>#### 14. Ideas for next steps

<div class="prose dark:prose-invert inline leading-relaxed break-words min-w-0 [word-break:break-word] prose-strong:font-bold [&_>*:first-child]:mt-0 [&_>*:last-child]:mb-0" id="bkmrk-switch-from-remote-a">- Switch from remote APIs to local models (e.g. via Ollama) so the VM uses your own GPU/LLM stack.
- Add skills/plugins gradually for home automation and other workflows; keep auditing configs as you expand.
- Integrate with more chat/voice interfaces while keeping the gateway bound to localhost plus your chosen secure tunnels/VPN.

</div>**<span style="color:rgb(224,62,45);">Ins0mnia</span>**