HOW-TO: Install and Set Up OpenClaw on Fresh Ubuntu (CLI-Only Guide)
Step-by-step CLI-only guide to install and configure OpenClaw on a fresh Ubuntu server with Telegram, Claude Haiku, Brave Web Search, full exec permissions, memory with embeddings, caching, and compaction.
HOW-TO: Install and Set Up OpenClaw on Fresh Ubuntu (CLI-Only Guide)
Overview
This guide walks through setting up OpenClaw from scratch on a fresh Ubuntu installation using CLI commands only. By the end, you'll have a fully operational AI assistant with:
- ✅ Telegram as the messaging channel
- ✅ Claude Haiku as the default model
- ✅ Brave Search for web search capabilities
- ✅ Full exec permissions on the host (no sandbox)
- ✅ Memory system with semantic search and embeddings
- ✅ Prompt caching for cost optimization
- ✅ Auto-compaction for long-running sessions
Prerequisites:
- Fresh Ubuntu 22.04+ or 24.04 LTS installation
- SSH access or terminal access
- Anthropic API key (console.anthropic.com)
- Brave Search API key (brave.com/search/api)
- Telegram bot token (from @BotFather)
Official Documentation: docs.openclaw.ai
Step 1: Update the System
sudo apt update && sudo apt upgrade -y
Install essential build tools (some OpenClaw dependencies may require compilation):
sudo apt install -y curl git build-essential
Docs: Getting Started
Step 2: Install Node.js 24
OpenClaw requires Node.js 24 (recommended) or Node 22.16+ (minimum).
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
Verify the installation:
node -v
# Expected: v24.x.x
npm -v
# Expected: 10.x.x or higher
Docs: Node.js Setup
Step 3: Install OpenClaw
Option A: Install Script (Recommended)
curl -fsSL https://openclaw.ai/install.sh | bash
Option B: npm Global Install
npm install -g openclaw@latest
Verify the installation:
openclaw --version
Note: If you get
openclaw: command not found, add npm's global bin to your PATH:export PATH="$(npm prefix -g)/bin:$PATH" echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.bashrc source ~/.bashrc
Docs: Install
Step 4: Create the Telegram Bot
Before configuring OpenClaw, create your Telegram bot:
- Open Telegram and message @BotFather (verify the handle is exactly
@BotFather) - Send
/newbot - Follow the prompts to set a name and username
- Save the bot token (format:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz)
Optional BotFather settings for group use:
/setprivacy→ Disable (so the bot sees all group messages)/setjoingroups→ Enable (to allow group invitations)
Docs: Telegram Channel
Step 5: Run Interactive Onboarding
The fastest way to get started is the interactive onboarding wizard:
openclaw onboard --install-daemon
This wizard will:
- Ask you to choose a model provider → Select Anthropic API key
- Prompt for your Anthropic API key
- Configure the Gateway
- Install OpenClaw as a system daemon (auto-start on boot)
Non-Interactive Alternative
For automated/scripted setups:
openclaw onboard --non-interactive \
--auth-choice anthropic-api-key \
--anthropic-api-key "$ANTHROPIC_API_KEY" \
--install-daemon \
--accept-risk
Docs: Onboarding CLI | Onboarding Wizard
Step 6: Verify the Gateway Is Running
openclaw gateway status
You should see the Gateway listening on port 18789. If it's not running:
openclaw gateway start
Check health:
openclaw status
Run diagnostics if something looks wrong:
openclaw doctor
Step 7: Configure the Default Model (Claude Haiku)
Set Claude Haiku as the default model:
openclaw config set agents.defaults.model.primary "anthropic/claude-haiku-4-5"
Add model fallbacks (optional but recommended):
openclaw config set agents.defaults.model.fallbacks '["anthropic/claude-sonnet-4-6"]' --strict-json
Define the model catalog with aliases for easy switching via /model:
openclaw config set agents.defaults.models '{"anthropic/claude-haiku-4-5":{"alias":"haiku"},"anthropic/claude-sonnet-4-6":{"alias":"sonnet"},"anthropic/claude-opus-4-6":{"alias":"opus"}}' --strict-json
Why Haiku? Claude Haiku 4.5 is fast, cheap, and capable enough for most daily tasks. You can switch to Sonnet or Opus anytime with
/model sonnetor/model opusin chat.
Docs: Configuration | Models CLI
Step 8: Configure Telegram Channel
Set up Telegram as the messaging channel:
# Enable Telegram
openclaw config set channels.telegram.enabled true --strict-json
# Set the bot token
openclaw config set channels.telegram.botToken "YOUR_TELEGRAM_BOT_TOKEN"
DM Access Control
Option A: Pairing mode (recommended for first setup — approve users one by one):
openclaw config set channels.telegram.dmPolicy "pairing"
Option B: Allowlist mode (restrict to specific Telegram user IDs):
openclaw config set channels.telegram.dmPolicy "allowlist"
openclaw config set channels.telegram.allowFrom '["YOUR_TELEGRAM_USER_ID"]' --strict-json
Finding your Telegram user ID:
- DM your bot
- Run
openclaw logs --follow- Look for
from.idin the log outputOr use the Bot API directly:
curl "https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates"
Group Chat Settings (Optional)
openclaw config set channels.telegram.groups '{"*":{"requireMention":true}}' --strict-json
openclaw config set channels.telegram.groupPolicy "allowlist"
Approve Pairing (if using pairing mode)
After sending your first DM to the bot:
# List pending pairing codes
openclaw pairing list telegram
# Approve a code
openclaw pairing approve telegram <CODE>
Pairing codes expire after 1 hour.
Step 9: Configure Brave Web Search
Get a Brave Search API Key
- Go to brave.com/search/api
- Create an account and choose the Search plan
- Generate an API key
- Each plan includes $5/month in free credit (covers ~1,000 queries/month)
Set Up Web Search
# Set the Brave API key
openclaw config set plugins.entries.brave.config.webSearch.apiKey "YOUR_BRAVE_API_KEY"
# Set Brave as the web search provider
openclaw config set tools.web.search.provider "brave"
# Configure search defaults
openclaw config set tools.web.search.maxResults 5 --strict-json
openclaw config set tools.web.search.timeoutSeconds 30 --strict-json
Alternative: Set the API key as an environment variable instead of storing it in config:
openclaw config set plugins.entries.brave.config.webSearch.apiKey --ref-provider default --ref-source env --ref-id BRAVE_API_KEYThen add to your environment:
echo 'export BRAVE_API_KEY="your-key-here"' >> ~/.bashrc source ~/.bashrc
Docs: Brave Search | Web Tools
Step 10: Disable Sandboxing (Full Host Exec)
By default, OpenClaw can sandbox tool execution in Docker containers. To run tools directly on the host with full permissions:
# Disable sandboxing entirely
openclaw config set agents.defaults.sandbox.mode "off"
Enable Elevated Exec
Allow the agent to run elevated commands on the host:
# Enable elevated mode
openclaw config set tools.elevated.enabled true --strict-json
# Set elevated as default for the agent
openclaw config set agents.defaults.elevatedDefault "on"
# Allow elevated from your Telegram user ID
openclaw config set tools.elevated.allowFrom.telegram '["YOUR_TELEGRAM_USER_ID"]' --strict-json
Configure Exec Tool Settings
# Set exec background timeout (ms before backgrounding)
openclaw config set tools.exec.backgroundMs 10000 --strict-json
# Set exec timeout (seconds)
openclaw config set tools.exec.timeoutSec 1800 --strict-json
⚠️ Security Warning: Disabling sandboxing means the AI agent can execute any command on your host system. Only do this on machines you fully control and where you trust the agent's behavior. Consider using
allowFromto restrict which users can trigger elevated commands.
Docs: Sandboxing | Sandbox vs Tool Policy vs Elevated
Step 11: Enable Memory System
OpenClaw's memory system uses plain Markdown files as the source of truth. The agent reads and writes to these files to maintain context across sessions.
Set the Workspace
openclaw config set agents.defaults.workspace "~/.openclaw/workspace"
Create the Memory Directory
mkdir -p ~/.openclaw/workspace/memory
Create Initial Memory Files (Optional)
# Create long-term memory file
cat > ~/.openclaw/workspace/MEMORY.md << 'EOF'
# MEMORY.md - Long-Term Memory
## Setup Notes
- OpenClaw installed on Ubuntu
- Using Claude Haiku as default model
- Telegram as primary channel
EOF
# Create today's daily log
cat > ~/.openclaw/workspace/memory/$(date +%Y-%m-%d).md << 'EOF'
# Daily Log
## Setup
- Fresh OpenClaw installation completed
EOF
Docs: Memory
Step 12: Configure Memory Search with Embeddings
Memory search enables semantic recall over your memory files. You need an embedding model to power vector search.
Option A: Use Anthropic's Provider (via Voyage Embeddings)
If you have a Voyage API key:
openclaw config set agents.defaults.memorySearch.provider "voyage"
Set the Voyage API key:
export VOYAGE_API_KEY="your-voyage-key"
echo 'export VOYAGE_API_KEY="your-voyage-key"' >> ~/.bashrc
Option B: Use OpenAI Embeddings
If you have an OpenAI API key:
openclaw config set agents.defaults.memorySearch.provider "openai"
Set the OpenAI API key:
export OPENAI_API_KEY="your-openai-key"
echo 'export OPENAI_API_KEY="your-openai-key"' >> ~/.bashrc
Option C: Use Gemini Embeddings (Free Tier Available)
openclaw config set agents.defaults.memorySearch.provider "gemini"
openclaw config set agents.defaults.memorySearch.model "gemini-embedding-001"
Set the Gemini API key:
export GEMINI_API_KEY="your-gemini-key"
echo 'export GEMINI_API_KEY="your-gemini-key"' >> ~/.bashrc
Option D: Use Ollama for Local Embeddings (No API Key Needed)
Install Ollama first:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull nomic-embed-text
Configure OpenClaw to use Ollama embeddings:
openclaw config set agents.defaults.memorySearch.provider "ollama"
Verify Memory Search
After configuring, verify the memory system:
openclaw memory status --deep
Force a reindex:
openclaw memory index --force
Test a search:
openclaw memory search "setup notes"
Auto-Selection: If you don't set a provider explicitly, OpenClaw auto-selects in this order: local GGUF → OpenAI → Gemini → Voyage → Mistral. It picks the first provider for which it can resolve an API key.
Docs: Memory Configuration Reference | Memory CLI
Step 13: Configure Prompt Caching
Prompt caching reduces API costs by caching the system prompt and recent context. Anthropic supports this natively.
# Enable short caching (5-minute cache, default for API key auth)
openclaw config set 'agents.defaults.models."anthropic/claude-haiku-4-5".params.cacheRetention' "short"
For extended caching (1-hour cache):
openclaw config set 'agents.defaults.models."anthropic/claude-haiku-4-5".params.cacheRetention' "long"
Cost Impact: With caching enabled, repeated prompts within the cache window cost significantly less. Cache read tokens are ~90% cheaper than fresh input tokens on Anthropic's API.
Docs: Anthropic Provider
Step 14: Configure Auto-Compaction
Compaction summarizes older conversation history when the context window fills up, allowing long-running sessions without losing important context.
Set Compaction Defaults
# Set reserve tokens floor (tokens to keep free for new messages)
openclaw config set agents.defaults.compaction.reserveTokensFloor 20000 --strict-json
Enable Memory Flush Before Compaction
This ensures the agent saves important notes to disk before old context is summarized away:
openclaw config set agents.defaults.compaction.memoryFlush.enabled true --strict-json
openclaw config set agents.defaults.compaction.memoryFlush.softThresholdTokens 4000 --strict-json
Use a Dedicated Compaction Model (Optional)
You can use a more capable model for compaction summarization while keeping Haiku as the default:
openclaw config set agents.defaults.compaction.model "anthropic/claude-sonnet-4-6"
Why? Compaction summaries produced by a more capable model retain more nuance and important details, even if your daily driver is Haiku.
Docs: Compaction
Step 15: Set Identity and Timezone
Give your agent a name and personality:
# Set agent name
openclaw config set identity.name "Clawd"
# Set emoji
openclaw config set identity.emoji "🦞"
# Set theme/personality
openclaw config set identity.theme "helpful assistant"
# Set timezone
openclaw config set agents.defaults.userTimezone "Asia/Singapore"
Docs: Configuration
Step 16: Configure Session Behavior
# Sessions are per-sender (each user gets their own session)
openclaw config set session.scope "per-sender"
# Auto-reset sessions daily at 4 AM
openclaw config set session.reset.mode "daily"
openclaw config set session.reset.atHour 4 --strict-json
Docs: Session Management
Step 17: Restart the Gateway
After all configuration changes, restart the Gateway to apply them:
openclaw gateway restart
Verify everything is running:
openclaw status
Check for configuration issues:
openclaw doctor
If the doctor finds issues:
openclaw doctor --fix
Step 18: Test the Setup
Test via Telegram
- Open Telegram and find your bot
- Send a message:
Hello, what can you do? - If using pairing mode, approve your pairing code:
openclaw pairing list telegram openclaw pairing approve telegram <CODE> - Send another message — you should get a response
Test Web Search
Send a message to your bot:
Search the web for the latest news about AI
Test Memory
Send a message:
Remember that my favorite color is blue
Then in a new session:
What's my favorite color?
Test Exec
Send a message:
Run `uname -a` and show me the output
Step 19: Monitor and Maintain
View Logs
# Follow logs in real-time
openclaw logs --follow
# View recent logs
openclaw logs
Check Status
openclaw status
Update OpenClaw
npm install -g openclaw@latest
openclaw gateway restart
Backup Configuration
openclaw backup
Complete Configuration Reference
After following all steps above, your ~/.openclaw/openclaw.json should look similar to this:
{
// Identity
identity: {
name: "Clawd",
theme: "helpful assistant",
emoji: "🦞",
},
// Agent runtime
agents: {
defaults: {
workspace: "~/.openclaw/workspace",
userTimezone: "Asia/Singapore",
// Model configuration
model: {
primary: "anthropic/claude-haiku-4-5",
fallbacks: ["anthropic/claude-sonnet-4-6"],
},
models: {
"anthropic/claude-haiku-4-5": {
alias: "haiku",
params: { cacheRetention: "short" },
},
"anthropic/claude-sonnet-4-6": { alias: "sonnet" },
"anthropic/claude-opus-4-6": { alias: "opus" },
},
// Elevated exec on by default
elevatedDefault: "on",
// No sandbox
sandbox: { mode: "off" },
// Memory search with embeddings
memorySearch: {
provider: "gemini", // or "openai", "voyage", "ollama"
model: "gemini-embedding-001",
},
// Compaction settings
compaction: {
reserveTokensFloor: 20000,
model: "anthropic/claude-sonnet-4-6",
memoryFlush: {
enabled: true,
softThresholdTokens: 4000,
},
},
},
},
// Telegram channel
channels: {
telegram: {
enabled: true,
botToken: "YOUR_TELEGRAM_BOT_TOKEN",
dmPolicy: "allowlist",
allowFrom: ["YOUR_TELEGRAM_USER_ID"],
groups: { "*": { requireMention: true } },
},
},
// Web search (Brave)
plugins: {
entries: {
brave: {
config: {
webSearch: {
apiKey: "YOUR_BRAVE_API_KEY",
},
},
},
},
},
// Tools configuration
tools: {
web: {
search: {
provider: "brave",
maxResults: 5,
timeoutSeconds: 30,
},
},
elevated: {
enabled: true,
allowFrom: {
telegram: ["YOUR_TELEGRAM_USER_ID"],
},
},
exec: {
backgroundMs: 10000,
timeoutSec: 1800,
},
},
// Session behavior
session: {
scope: "per-sender",
reset: {
mode: "daily",
atHour: 4,
},
},
}
Quick Command Reference
| Task | Command |
|---|---|
| Check status | openclaw status |
| Start gateway | openclaw gateway start |
| Stop gateway | openclaw gateway stop |
| Restart gateway | openclaw gateway restart |
| View logs | openclaw logs --follow |
| Run diagnostics | openclaw doctor |
| Fix issues | openclaw doctor --fix |
| Get config value | openclaw config get <path> |
| Set config value | openclaw config set <path> <value> |
| Validate config | openclaw config validate |
| Memory status | openclaw memory status --deep |
| Reindex memory | openclaw memory index --force |
| Search memory | openclaw memory search "query" |
| List pairing codes | openclaw pairing list telegram |
| Approve pairing | openclaw pairing approve telegram <CODE> |
| Update OpenClaw | npm install -g openclaw@latest |
| Backup | openclaw backup |
| Open dashboard | openclaw dashboard |
Troubleshooting
Gateway Won't Start
# Check for config errors
openclaw config validate
# Run diagnostics
openclaw doctor --fix
# Check logs
openclaw logs
Telegram Bot Not Responding
- Verify the bot token:
openclaw config get channels.telegram.botToken - Check if Telegram channel is enabled:
openclaw config get channels.telegram.enabled - Check pairing status:
openclaw pairing list telegram - Check logs for errors:
openclaw logs --follow
Memory Search Not Working
# Check memory status
openclaw memory status --deep
# Verify embedding provider
openclaw config get agents.defaults.memorySearch.provider
# Force reindex
openclaw memory index --force --verbose
Web Search Not Working
- Verify Brave API key:
openclaw config get plugins.entries.brave.config.webSearch.apiKey - Check search provider:
openclaw config get tools.web.search.provider - Test from the CLI:
openclaw memory search "test"(different tool, but validates the pipeline)
References
- Official Documentation: docs.openclaw.ai
- Getting Started: docs.openclaw.ai/start/getting-started
- Configuration: docs.openclaw.ai/gateway/configuration
- Configuration Examples: docs.openclaw.ai/gateway/configuration-examples
- Configuration Reference: docs.openclaw.ai/gateway/configuration-reference
- Telegram Setup: docs.openclaw.ai/channels/telegram
- Brave Search: docs.openclaw.ai/tools/brave-search
- Memory: docs.openclaw.ai/concepts/memory
- Memory Config Reference: docs.openclaw.ai/reference/memory-config
- Compaction: docs.openclaw.ai/concepts/compaction
- Sandboxing: docs.openclaw.ai/gateway/sandboxing
- Anthropic Provider: docs.openclaw.ai/providers/anthropic
- Node.js Setup: docs.openclaw.ai/install/node
- CLI Reference: docs.openclaw.ai/cli
- GitHub: github.com/openclaw/openclaw
Document Version: 1.0 Date: March 22, 2026 Author: CLAW-00 Last Updated: March 22, 2026, 09:31 GMT+8