Skip to content
Go back

Setting Up OpenClaw on AWS: A Simple Linux Box (Not a Rabbit Hole)

DRAFT
Published: Feb 10, 2026
Vancouver, Canada

You just want OpenClaw running on a Linux box. Twenty minutes, tops.

Instead, you’re three hours in. Your EC2 instance has no public IP. The browser-based terminal is so laggy you can’t tell if commands succeeded. Someone suggested Pinocchio. Another person mentioned Tailscale. You’re reading about SSH tunnels. You’re down a rabbit hole when all you needed was a simple Linux box with SSH access.

This guide provides the straightforward path: a properly configured EC2 instance, OpenClaw installed, and two clear alternatives for when AWS isn’t the right fit.

Prerequisites

You need:

  • An AWS account
  • A terminal (macOS/Linux built-in, Windows WSL2)
  • 20 minutes

You don’t need:

  • A DevOps degree
  • WSL/PuTTY expertise
  • Prior AWS experience

Step 1: Launch EC2 with Public IP (The Critical Fix)

This is where most setups break. EC2 instances don’t get public IPs by default in some VPC configurations. Without a public IP, you can’t SSH in from your machine.

Using AWS Console

  1. Navigate to EC2 > Launch Instance
  2. Name: openclaw-gateway
  3. AMI: Ubuntu Server 24.04 LTS
  4. Instance type: t3.medium (4GB RAM minimum)
  5. Create a new key pair:
    • Name: openclaw-key
    • Type: RSA
    • Format: .pem (or .ppk for PuTTY)
    • Download and save to ~/.ssh/openclaw-key.pem
  6. Network settings (CRITICAL):
    • Auto-assign public IP: Enable
    • Create new security group or select existing
  7. Storage: 20GB gp3 (default is fine)
  8. Launch instance

Using AWS CLI

$ aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t3.medium \
  --key-name openclaw-key \
  --security-group-ids sg-xxxxx \
  --associate-public-ip-address \
  --block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=openclaw-gateway}]'
(This example is complete, it can be run "as is")

Wait 60 seconds for the instance to initialize. Get the public IP:

$ aws ec2 describe-instances \
  --instance-ids i-xxxxx \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text

Step 2: Configure Security Group

Your EC2 instance needs two ports open:

  • Port 22 (SSH)
  • Port 18789 (OpenClaw gateway)

AWS Console

  1. EC2 > Security Groups > Select your group
  2. Inbound rules > Edit inbound rules
  3. Add rules:
TypePortSourceDescription
SSH22My IPSSH access
Custom TCP18789My IPOpenClaw gateway

AWS CLI

$ MY_IP=$(curl -s https://checkip.amazonaws.com)
$ aws ec2 authorize-security-group-ingress \
  --group-id sg-xxxxx \
  --ip-permissions \
    IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges="[{CidrIp=${MY_IP}/32,Description='SSH access'}]" \
    IpProtocol=tcp,FromPort=18789,ToPort=18789,IpRanges="[{CidrIp=${MY_IP}/32,Description='OpenClaw gateway'}]"
(This example is complete, it can be run "as is")

Step 3: SSH into Instance

Set key permissions and connect:

$ chmod 400 ~/.ssh/openclaw-key.pem
$ ssh -i ~/.ssh/openclaw-key.pem ubuntu@<PUBLIC_IP>

You should see:

Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-1018-aws x86_64)
ubuntu@ip-xxx-xx-xx-xx:~$

Step 4: Install Node 22

Ubuntu’s default Node is too old. Use NodeSource:

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

Verify versions:

$ node --version
# v22.x.x
$ npm --version
# 10.x.x

Step 5: Install OpenClaw

Global install (recommended for gateway mode):

$ sudo npm install -g openclaw@latest

Verify installation:

$ openclaw --version
# openclaw/x.x.x
$ ls -la ~/.openclaw/
# Should show workspace/ directory

Step 6: Configure AWS Bedrock Access

OpenClaw works with multiple LLM providers. For AWS deployments, Bedrock is simplest because it uses IAM roles instead of API keys.

Create IAM Role

$ aws iam create-role --role-name EC2-Bedrock-Access \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

$ aws iam attach-role-policy --role-name EC2-Bedrock-Access \
  --policy-arn arn:aws:iam::aws:policy/AmazonBedrockFullAccess

$ aws iam create-instance-profile --instance-profile-name EC2-Bedrock-Access
$ aws iam add-role-to-instance-profile \
  --instance-profile-name EC2-Bedrock-Access \
  --role-name EC2-Bedrock-Access
(This example is complete, it can be run "as is")

Attach to EC2 Instance

$ aws ec2 associate-iam-instance-profile \
  --instance-id i-xxxxx \
  --iam-instance-profile Name=EC2-Bedrock-Access

Configure OpenClaw for Bedrock

On your EC2 instance, edit ~/.openclaw/openclaw.json:

{
  "models": {
    "bedrockDiscovery": {
      "enabled": true,
      "region": "us-east-1"
    },
    "providers": {
      "amazon-bedrock": {
        "baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
        "api": "bedrock-converse-stream",
        "auth": "aws-sdk",
        "models": [
          {
            "id": "anthropic.claude-opus-4-5-20251101-v1:0",
            "name": "Claude Opus 4.5 (Bedrock)",
            "reasoning": true,
            "input": ["text", "image"],
            "contextWindow": 200000,
            "maxTokens": 8192
          }
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "model": { "primary": "amazon-bedrock/anthropic.claude-opus-4-5-20251101-v1:0" }
    }
  }
}
(This example is complete, it can be run "as is")

Set environment variables:

$ echo 'export AWS_PROFILE=default' >> ~/.bashrc
$ echo 'export AWS_REGION=us-east-1' >> ~/.bashrc
$ source ~/.bashrc

Verify model discovery:

$ openclaw models list
# Should show Bedrock models

Step 7: Start Gateway and Test

Launch the gateway:

$ openclaw gateway --port 18789

You should see:

OpenClaw Gateway starting on port 18789
Health endpoint: http://localhost:18789/health

Test health endpoint from another terminal:

$ curl http://<PUBLIC_IP>:18789/health
{"status":"ok","version":"x.x.x"}

Run Gateway in Background with tmux

For persistent operation:

$ sudo apt-get install -y tmux
$ tmux new -s openclaw
$ openclaw gateway --port 18789
# Press Ctrl+b, then d to detach

Reattach later:

$ tmux attach -t openclaw

Step 8: WhatsApp Pairing

Pair your WhatsApp number:

$ openclaw channels login

A QR code appears in the terminal. Open WhatsApp on your phone:

  1. Settings > Linked Devices
  2. Link a Device
  3. Scan the QR code

Within seconds, you should see:

WhatsApp paired successfully
Session saved to ~/.openclaw/sessions/

Configure allowlist in ~/.openclaw/openclaw.json:

{
  "channels": {
    "whatsapp": {
      "allowFrom": ["+15555550123"]
    }
  }
}
(This example is complete, it can be run "as is")

Restart the gateway and send a test message from your allowlisted number.

Alternative Paths

Pinocchio: Desktop GUI

If you just want to experiment locally without server setup:

When to use:

  • Local-only testing
  • No remote access needed
  • Prefer GUI over CLI

Setup:

  1. Download from pinocchio.ai
  2. Install on macOS/Windows
  3. Built-in model management

Limitations:

  • Runs on your laptop (battery drain)
  • No remote access
  • Can’t run 24/7

Tailscale: No Public IP

If your EC2 instance is in a private subnet or you can’t modify security groups:

When to use:

  • Corporate VPN restrictions
  • Private subnet deployments
  • Zero-trust networking

Setup:

$ curl -fsSL https://tailscale.com/install.sh | sh
$ sudo tailscale up
# Visit the auth URL in browser

On your local machine:

$ tailscale ssh ubuntu@openclaw-gateway

Benefits:

  • No public IP needed
  • Encrypted mesh network
  • Works through NAT

Trade-offs:

  • Extra dependency
  • Learning curve
  • Another service to manage

Common Issues

Connection Refused on Port 18789

Check if gateway is running:

$ ps aux | grep openclaw
$ lsof -i :18789

Check security group allows your current IP:

$ curl -s https://checkip.amazonaws.com
# Compare with security group rules

Node Version Too Old

Ubuntu 24.04 default Node is v18. OpenClaw requires v22+:

$ node --version
# If < 22, reinstall from NodeSource
$ curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Gemini API Doesn’t Work

Gemini API has quota limits and rate issues. Use Bedrock instead:

$ openclaw config set agents.defaults.model.primary "amazon-bedrock/anthropic.claude-opus-4-5-20251101-v1:0"

SSH Key Permission Denied

Key must be read-only for owner:

$ chmod 400 ~/.ssh/openclaw-key.pem

WhatsApp QR Code Not Scanning

Make sure your terminal supports Unicode characters. If using SSH, enable X11 forwarding or use Tailscale for better terminal support.

Conclusion

You now have:

  • An EC2 instance with SSH access
  • OpenClaw gateway running on port 18789
  • AWS Bedrock for LLM inference (no API keys)
  • WhatsApp channel paired
  • tmux session for persistent operation

The core lesson: the best solution isn’t the most clever. It’s the one that works in 20 minutes.

Next steps:

  • Configure agent workspace (~/.openclaw/workspace/AGENTS.md)
  • Enable heartbeats for proactive behavior
  • Add more channels (Telegram, Discord)
  • Read OpenClaw: Architecture of a Local Agent for design details

The rabbit hole was never necessary. You just needed a Linux box with SSH.

Content Attribution: 100% by Alpha
  • 100% by Alpha: Original draft and core concepts