How to Deploy OpenClaw on Your Own Server: The Complete 2026 Guide
OpenClaw is the most popular open-source AI assistant framework — 265K+ GitHub stars, 22+ messaging channels (Telegram, Discord, WhatsApp, Slack, Signal, Teams, Matrix, Feishu, LINE, and more), and a flexible model-agnostic architecture. Sponsored by OpenAI, Vercel, and others.
But let's be honest: getting it running on your own server is not trivial. The official docs are thorough but scattered across many pages. If you've hit a wall during setup, you're not alone — I've seen the same questions come up dozens of times in the Discord.
This guide is what I wish existed when I first deployed OpenClaw. It covers everything from zero to a fully working Telegram bot, including the parts the docs skip over.
What You're Building
By the end of this guide, you'll have:
- A dedicated VPS running OpenClaw as a systemd service
- A Telegram bot connected to an AI model of your choice
- Proper security (firewall, SSH hardening, non-root user)
- Auto-restart on crash and automatic updates
- An understanding of how the pieces fit together
Time estimate: 30-60 minutes if things go smoothly. Longer if you're new to Linux.
Prerequisites
Before you start, make sure you have:
| Requirement | Why |
|---|---|
| A VPS with 2+ vCPU, 4GB+ RAM | OpenClaw + Node.js runtime need headroom |
| Ubuntu 24.04 LTS | This guide is Ubuntu-specific. Debian works too with minor tweaks |
| A domain name (optional) | For HTTPS and webhook-based channels |
| A Telegram bot token | Get one from @BotFather |
| An AI API key | OpenRouter, OpenAI, Anthropic, or any OpenAI-compatible provider |
| Basic terminal comfort | You'll be SSH-ing into a server and running commands |
Recommended VPS Providers
The official docs list eight hosting options including Railway, Northflank, Fly.io, and more. For a dedicated VPS, here are the most popular choices:
| Provider | Spec | Price | Region | Notes |
|---|---|---|---|---|
| Hetzner CPX22 | 3 vCPU, 4GB, 80GB | ~$7.59/mo | EU | Best value in Europe |
| Hetzner CPX21 | 3 vCPU, 4GB, 80GB | ~$10.59/mo | US | Best value in US |
| Oracle Cloud | 4 vCPU ARM, 24GB | Free tier | Various | Unbeatable price, tricky signup |
| Vultr | 2 vCPU, 4GB, 100GB | ~$24/mo | 32 locations | Widest region coverage |
| DigitalOcean | 2 vCPU, 4GB, 80GB | ~$24/mo | 15 locations | Great beginner UX |
| Linode (Akamai) | 2 vCPU, 4GB, 80GB | ~$24/mo | 25 locations | Solid network, good docs |
| Contabo | 4 vCPU, 8GB, 200GB | ~$7.49/mo | EU/US/Asia | Cheapest raw specs, slower support |
| AWS Lightsail | 2 vCPU, 4GB, 80GB | ~$36/mo | Worldwide | Familiar if you're in AWS ecosystem |
How to choose:
- Tightest budget: Oracle Cloud free tier (ARM) or Contabo
- Best value: Hetzner (hard to beat price-to-performance)
- Easiest for beginners: DigitalOcean or Vultr (clean UI, 1-click setup)
- Most regions: Vultr (32 cities) or AWS Lightsail
- Asia-Pacific: Vultr (Tokyo, Seoul, Singapore, Mumbai, Melbourne) or Linode
Part 0: Try It Locally First (Optional)
Before committing to a VPS, you can run OpenClaw on your own computer to get a feel for how it works. This takes about 5 minutes:
# Requires Node.js ≥22.12.0
npm install -g openclaw@latest
openclaw onboard --install-daemon
The onboarding wizard will walk you through AI provider setup and channel configuration. Once running, you can chat with your bot via the built-in WebChat at http://localhost:18789, or connect a Telegram bot.
The catch: Your bot only works while your computer is on. For a 24/7 Telegram or Discord bot, you need a server — which is what the rest of this guide covers.
This local test is still valuable though: it lets you verify your API keys work, see how the config file is structured, and understand what you're automating when you move to a VPS.
Part 1: Server Setup
1.1 — SSH In and Secure the Box
# SSH into your fresh server
ssh root@YOUR_SERVER_IP
# Update everything
apt update && apt upgrade -y
# Create a non-root user (don't run OpenClaw as root)
adduser openclaw
usermod -aG sudo openclaw
# Set up SSH key auth for the new user
mkdir -p /home/openclaw/.ssh
cp ~/.ssh/authorized_keys /home/openclaw/.ssh/
chown -R openclaw:openclaw /home/openclaw/.ssh
chmod 700 /home/openclaw/.ssh
chmod 600 /home/openclaw/.ssh/authorized_keys
# Disable root login and password auth
sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
Important: Before you close this session, open a new terminal and verify you can SSH in as the openclaw user. If you lock yourself out, you'll need to use your VPS provider's console.
1.2 — Set Up the Firewall
# Allow SSH, HTTP, HTTPS
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Only expose the gateway port if you need external WebChat access
# sudo ufw allow 18789/tcp
sudo ufw enable
The gateway port (18789) should generally NOT be exposed to the internet unless you specifically need WebChat or remote access. Telegram, Discord, Slack, and most channels work via outbound connections — they don't need inbound ports. For remote access, the official docs recommend Tailscale Serve/Funnel or SSH tunnels.
1.3 — Add Swap Space (Important for 4GB RAM Servers)
OpenClaw can spike memory usage during heavy conversations. Swap prevents OOM kills.
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 with free -h — you should see 2GB swap.
Part 2: Install OpenClaw (Recommended Method)
The recommended way to install OpenClaw is via npm — no Docker required. The built-in onboard wizard handles most of the configuration for you.
2.1 — Install Node.js 22
OpenClaw requires Node.js ≥22.12.0.
# Install nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.bashrc
# Install and use Node.js 22
nvm install 22
nvm use 22
node -v # Should show v22.12.0 or higher
2.2 — Install OpenClaw
npm install -g openclaw@latest
2.3 — Run the Onboarding Wizard
This is the magic command that walks you through the entire setup:
openclaw onboard --install-daemon
The wizard will:
- Set up the Gateway configuration
- Ask for your AI provider credentials (OpenRouter, OpenAI, Anthropic, etc.)
- Configure your messaging channels (Telegram, Discord, etc.)
- Install OpenClaw as a systemd service that auto-starts on boot
Follow the prompts. For Telegram, you'll need the bot token from @BotFather.
2.4 — Verify the Installation
# Check if the gateway is running
openclaw doctor
# View live logs
openclaw logs --follow
openclaw doctor is your best friend — it checks for common misconfigurations, risky security settings, and connectivity issues.
2.5 — Test Your Bot
Open Telegram, find your bot, and send a message. With the default dmPolicy: "pairing", you'll need to approve yourself first:
- Send any message to your bot in Telegram
- Check the logs:
openclaw logs --follow— you'll see a pairing request - Approve it via the CLI or the pairing flow
For a personal bot where only you use it, you can set dmPolicy: "open" with an allowFrom list of your Telegram user ID. More on this below.
Part 3: Manual Configuration (For Power Users)
If you need more control than the wizard provides, here's how to configure OpenClaw manually.
3.1 — Configuration File
OpenClaw uses JSON5 format (allows comments and trailing commas), stored at ~/.openclaw/openclaw.json:
{
// === AI Models ===
// Minimal config — just set your default model
agent: {
model: "anthropic/claude-opus-4-6"
},
// === Or use OpenRouter for access to many models ===
models: {
providers: {
"openrouter": {
baseUrl: "https://openrouter.ai/api/v1",
apiKey: "${OPENROUTER_API_KEY}",
api: "openai-completions",
models: [
{ id: "anthropic/claude-sonnet-4.5", name: "Claude Sonnet 4.5" },
{ id: "openai/gpt-5.2", name: "GPT-5.2" },
{ id: "google/gemini-3-flash", name: "Gemini 3 Flash" },
{ id: "minimax/MiniMax-M2.5-highspeed", name: "MiniMax M2.5" }
]
}
}
},
// === Default Agent Settings ===
agents: {
defaults: {
model: {
primary: "openrouter/anthropic/claude-sonnet-4.5"
}
}
},
// === Channels ===
channels: {
telegram: {
enabled: true,
botToken: "${TELEGRAM_BOT_TOKEN}",
dmPolicy: "pairing", // Default: requires one-time approval per user
streaming: "partial", // Default since v2026.3.2: live preview streaming
}
// Discord:
// discord: {
// enabled: true,
// token: "${DISCORD_BOT_TOKEN}"
// }
// Slack:
// slack: {
// enabled: true,
// botToken: "${SLACK_BOT_TOKEN}",
// appToken: "${SLACK_APP_TOKEN}"
// }
}
}
3.2 — Environment Variables
Store secrets in ~/.openclaw/.env:
# AI Provider (pick one or more)
OPENROUTER_API_KEY=sk-or-v1-your-key-here
# OPENAI_API_KEY=sk-your-key-here
# ANTHROPIC_API_KEY=sk-ant-your-key-here
# Telegram
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
# Gateway Auth
OPENCLAW_GATEWAY_TOKEN=your-random-token-here
Generate a secure gateway token: openssl rand -hex 16
3.3 — Key Configuration Gotchas
${VARIABLE}syntax: OpenClaw reads from.envautomatically. Don't paste raw API keys in the config — use env var references.- DM Policy defaults to
"pairing": This means new users must be approved before they can chat. For a personal bot, this is great security. For an open bot, set"open"withallowFrom: ["*"]. - Telegram streaming defaults to
"partial": Since v2026.3.2, new Telegram setups get live preview streaming out of the box. Options:off,partial,block,progress. - Telegram Privacy Mode: Bots default to Privacy Mode in groups (can only see commands and mentions). To see all messages, either disable via
/setprivacyin @BotFather or make the bot a group admin. You must remove and re-add the bot to each group after changing this. - Config validation: Run
openclaw config validateto check your config before restarting.
3.4 — Telegram Access Control Deep Dive
Understanding DM policies is critical — getting this wrong means your bot either doesn't respond or is open to the world:
| Policy | Behavior | Use Case |
|---|---|---|
pairing (default) |
One-time approval per user | Personal use, small team |
allowlist |
Only specific Telegram user IDs | Controlled access |
open + allowFrom: ["*"] |
Anyone can DM | Public bot |
disabled |
No DMs | Group-only bot |
Find your Telegram user ID:
- DM your bot, run
openclaw logs --follow, readfrom.idin the log - Or use
@userinfoboton Telegram
Part 4: Performance Tuning
These optimizations are recommended by the official docs, especially for low-power VMs and ARM servers.
4.1 — Enable Module Compile Cache
Add to ~/.bashrc:
export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
mkdir -p /var/tmp/openclaw-compile-cache
export OPENCLAW_NO_RESPAWN=1
NODE_COMPILE_CACHE— Caches compiled Node.js modules. First run warms the cache, subsequent starts are much faster.OPENCLAW_NO_RESPAWN=1— Eliminates overhead from automatic restart mechanisms (systemd handles restarts instead).
4.2 — Tune systemd Service
If you used openclaw onboard --install-daemon, the service is already configured. To add performance overrides:
sudo systemctl edit openclaw
Add:
[Service]
Environment=OPENCLAW_NO_RESPAWN=1
Environment=NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache
Restart=always
RestartSec=2
TimeoutStartSec=90
Use SSD-backed storage for state and cache paths to minimize cold-start latency.
Part 5: Production Hardening
5.1 — Automatic Updates
cat > ~/update-openclaw.sh << 'EOF'
#!/bin/bash
npm install -g openclaw@latest
sudo systemctl restart openclaw
echo "[$(date)] OpenClaw updated to $(openclaw --version)" >> ~/openclaw-update.log
EOF
chmod +x ~/update-openclaw.sh
# Run every Sunday at 3 AM
(crontab -l 2>/dev/null; echo "0 3 * * 0 /home/openclaw/update-openclaw.sh") | crontab -
You can also use update channels:
openclaw update --channel stable # Production (default)
openclaw update --channel beta # Preview features
openclaw update --channel dev # Bleeding edge
5.2 — Basic Monitoring
A lightweight health check that restarts OpenClaw if it goes down:
cat > ~/healthcheck-openclaw.sh << 'EOF'
#!/bin/bash
if ! curl -sf http://localhost:18789/healthz > /dev/null 2>&1; then
echo "[$(date)] ALERT: OpenClaw gateway is DOWN — restarting" >> ~/openclaw-health.log
sudo systemctl restart openclaw
fi
EOF
chmod +x ~/healthcheck-openclaw.sh
# Check every 5 minutes
(crontab -l 2>/dev/null; echo "*/5 * * * * /home/openclaw/healthcheck-openclaw.sh") | crontab -
Part 6: Alternative — Docker Deployment
If you prefer Docker, OpenClaw provides a docker-compose.yml in the repository. Note that there are no pre-built images on Docker Hub — you need to build from source.
git clone https://github.com/openclaw/openclaw.git
cd openclaw
docker compose up -d
The compose file defines two services:
- openclaw-gateway: The main service (ports 18789 + 18790)
- openclaw-cli: A companion CLI service with reduced privileges
The gateway command is: node dist/index.js gateway --bind lan --port 18789
For most users, the native npm install is simpler and recommended. Docker is mainly useful for isolation or if you're already running a Docker-based infrastructure.
Part 7: Troubleshooting
Run the Built-in Diagnostics
Always start here:
openclaw doctor
This checks for common issues including risky security configurations, connectivity problems, and misconfigurations.
Validate Your Config
openclaw config validate --json
Shows detailed error paths for any invalid keys.
Telegram Bot Not Responding
Check these in order:
- Is the gateway running?
sudo systemctl status openclaw - Are there errors in logs?
openclaw logs --follow - Is the bot token correct? Compare with what @BotFather gave you
- Is
channels.telegram.enabledset totrue? Check youropenclaw.json - Did you approve the pairing? With
dmPolicy: "pairing"(the default), you need to approve yourself first - Did another instance steal the webhook? Telegram only allows one active connection per bot token. If you're running OpenClaw somewhere else with the same token, one instance will silently stop receiving messages.
- IPv6 issues? Some VPS hosts resolve
api.telegram.orgto IPv6 first. If you see intermittent failures, add to your config:
{
channels: {
telegram: {
network: {
dnsResultOrder: "ipv4first"
}
}
}
}
"401 Unauthorized" from AI Provider
Your API key is wrong or expired. Test it directly:
curl https://openrouter.ai/api/v1/models \
-H "Authorization: Bearer $OPENROUTER_API_KEY"
If this returns models, the key works. If 401, regenerate it.
High Memory Usage / OOM Kills
OpenClaw with active conversations can use 500MB-1.5GB. If you're running on a 2GB server:
- Add swap (see section 1.3)
- Enable compile cache (see section 4.1)
- Consider a larger VPS
Config Changes Not Taking Effect
OpenClaw hot-reloads openclaw.json — changes should apply within seconds. If they don't:
sudo systemctl restart openclaw
Reality Check: Is Self-Hosting Right for You?
Self-hosting OpenClaw is a great learning experience and gives you full control. But the setup you just read is only day one. Here's what the ongoing commitment actually looks like:
The Visible Costs
| Task | Frequency | Time |
|---|---|---|
| Initial setup (this guide) | Once | 1-2 hours |
| Security updates (apt upgrade, Node.js) | Monthly | 15-30 min |
| Debugging when things break | As needed | 30 min - 2 hours |
| Monitoring and log review | Weekly | 10 min |
| OpenClaw version upgrades (breaking changes happen) | Monthly | 15-60 min |
| API key rotation | Quarterly | 10 min |
The Hidden Costs Nobody Warns You About
AI API key management: If you use multiple models (Claude for complex tasks, Gemini Flash for quick chats), you need separate API keys from separate providers, each with their own billing dashboard, rate limits, and payment methods. When one key expires at 2 AM, your bot goes silent.
Cost surprises: OpenRouter and direct API providers bill per token with no hard caps. A user who pastes a 50-page PDF into the chat can burn through $5 in a single conversation. You won't know until the bill arrives — there's no real-time spending dashboard on a self-hosted setup.
Breaking changes: OpenClaw moves fast. The v2026.3.2 release had 4 breaking changes (default tools profile, ACP dispatch, plugin SDK, Zalo transport). Each upgrade requires reading the changelog, testing, and potentially updating your config. Skip updates and you fall behind on security patches.
The 3 AM problem: Your bot crashes. Your healthcheck script restarts it. But the crash was caused by a corrupt state file, so it crashes again in a loop. Nobody notices until Monday morning. Your team/customers see 48 hours of silence.
The True Monthly Cost of Self-Hosting
| Item | Cost |
|---|---|
| VPS (Hetzner CPX22) | $7.59 |
| AI API costs (varies wildly) | $10-100+ |
| Your time @ $20/hr, ~3 hrs/month | $60 |
| Total | $78-168+ |
The VPS is cheap. Your time isn't.
When Self-Hosting Makes Sense
- You're a developer who enjoys ops work
- You need full data sovereignty
- You want to modify OpenClaw's source code
- You need channels beyond Telegram (Discord, Slack, WhatsApp, Signal, Teams, etc.)
- You want to learn how everything works under the hood
When It Doesn't
- You just want a working AI bot and don't care how it runs
- Downtime means missed messages from customers or your team
- You'd rather spend your time using the bot than maintaining it
- You want predictable costs, not per-token billing anxiety
- You don't have Linux experience and followed this guide with difficulty
If you fall into the second category, managed platforms exist for exactly this reason. I built OpenClawUP after going through all of this myself — it handles deployment, monitoring, auto-updates, and wraps 6 AI models behind a single credit system with a real-time spending dashboard so you always know exactly what you're paying. But there are other options too: SimpleClaw, KiloClaw, and ClawHost all offer managed OpenClaw hosting at different price points.
The important thing is that you're using OpenClaw. Whether you self-host or use a managed platform, you're part of one of the most exciting open-source AI communities out there.
Questions? Reach me on Twitter/X or email: hi@openclawup.com. Happy to help with setup issues.