You don't need a Mac Mini or dedicated hardware to run a 24/7 AI agent. An AWS EC2 instance — or any cloud VPS — works just as well, costs less, and has the added benefit of being someone else's problem when the hardware fails.

This guide walks through a hardened OpenClaw deployment on AWS EC2 using Docker for container isolation and Tailscale for private network access. By the end, your agent will be running continuously, accessible only through your private Tailscale network, with no public ports exposed to the internet.

The same steps work on DigitalOcean, Hetzner, or Vultr if you're not on AWS.

What You'll Build

  • A hardened Ubuntu server with non-standard SSH configuration and key-only authentication
  • Docker running OpenClaw in an isolated container
  • Tailscale providing encrypted private access — no public ports for the application
  • A fully functional AI agent accessible from your browser, anywhere

Prerequisites

Cloud infrastructure:

  • AWS account with EC2 access
  • Ubuntu 24.04 LTS instance (minimum: 2 vCPU, 4GB RAM, 15GB storage)
  • Your .pem key pair file saved locally
  • SSH access as the default ubuntu user

API keys:

Accounts:


Phase 1: Server Hardening

Do this before installing anything else. A misconfigured server with OpenClaw on it is worse than no server.

Create a Dedicated User

SSH into your server as the default Ubuntu user:

ssh -i "your-key.pem" ubuntu@<YOUR-EC2-IP>

Update the system and create a dedicated non-root user for OpenClaw:

sudo apt update && sudo apt upgrade -y
sudo adduser openclaw
sudo usermod -aG sudo openclaw

Running the application as a dedicated user follows the principle of least privilege — if something goes wrong, the blast radius is contained to this user's permissions.

Copy SSH Keys to the New User

The default AWS .pem key only authenticates the ubuntu user. You need to copy it to your new user before disabling root login, or you'll lock yourself out.

While still logged in as ubuntu:

sudo mkdir -p /home/openclaw/.ssh
sudo cp /home/ubuntu/.ssh/authorized_keys /home/openclaw/.ssh/
sudo chown -R openclaw:openclaw /home/openclaw/.ssh
sudo chmod 700 /home/openclaw/.ssh
sudo chmod 600 /home/openclaw/.ssh/authorized_keys

The permission values (700 for directory, 600 for the keys file, owned by the user) are not optional. SSH will silently reject login if any of these are wrong.

Configure the Firewall (Two Layers)

First, add inbound rules in the AWS Security Group console:

  • Allow port 22/tcp (current SSH — your lifeline while making changes)
  • Allow port 2222/tcp (new SSH port you're about to configure)

Then configure the host-level firewall (UFW):

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 2222/tcp
sudo ufw enable

Test New User Login Before Locking Down SSH

This step is critical. Keep your current terminal open. Open a new terminal window and verify you can log in as the new user:

ssh -i "your-key.pem" openclaw@<YOUR-EC2-IP>

If this succeeds without a password prompt, proceed. If it fails, debug the SSH key permissions from Step 2 before continuing.

Harden SSH Configuration

Once you've confirmed key-based login works:

sudo vi /etc/ssh/sshd_config

Change these settings:

Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Ubuntu 24.04 gotcha: Ubuntu 24.04 uses systemd socket activation which holds port 22 open regardless of what's in sshd_config. You must explicitly disable the socket:

sudo systemctl stop ssh.socket
sudo systemctl disable ssh.socket
sudo systemctl restart ssh

Verify the change:

sudo ss -tulpn | grep ssh

You should see 0.0.0.0:2222, not 0.0.0.0:22.

Open a new terminal and test: ssh -p 2222 -i "your-key.pem" openclaw@<IP>

Only once that works, remove port 22 from UFW and the AWS Security Group:

sudo ufw delete allow 22/tcp

After this point, you can no longer use EC2 Instance Connect (browser SSH). All SSH must go through port 2222.


Phase 2: Install Docker and Tailscale

Install Docker

sudo apt install apt-transport-https ca-certificates curl software-properties-common -y

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y

# Allow openclaw user to run Docker without sudo
sudo usermod -aG docker ${USER}

Log out and reconnect for the group change to take effect. Verify Docker works:

docker run hello-world

Install Tailscale

Tailscale provides the secure access layer. Instead of exposing OpenClaw's web port (18789) to the public internet, Tailscale creates a private encrypted mesh network — only your authorized devices can reach the bot.

On your EC2 server:

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

Follow the authentication link to authorize your server on your Tailscale account.

On your local machine: install Tailscale from tailscale.com/download and sign in with the same account. Both devices are now on your private Tailnet.


Phase 3: Install OpenClaw

Clone and Prepare

git clone https://github.com/openclaw/openclaw.git
cd openclaw

# Remove any old config from previous experiments
sudo rm -rf ~/.openclaw

# Pre-create the config folder with correct permissions
mkdir -p /home/openclaw/.openclaw/workspace
sudo chmod -R 777 /home/openclaw/.openclaw
sudo chown -R openclaw:openclaw ~/openclaw
sudo chmod -R 775 ~/openclaw

Pre-creating the folder manually with correct ownership prevents the "Permission Denied" errors that appear when Docker tries to create it.

Run the Setup Script

cd ~/openclaw
./docker-setup.sh

When prompted, select these options specifically:

| Prompt | Selection | |--------|-----------| | Onboarding mode | Manual | | Setup | Local gateway (this machine) | | Workspace directory | Enter (accept default) | | Model/auth provider | Anthropic | | Anthropic API key | Your key | | Gateway port | 18789 | | Gateway bind | Tailnet | | Gateway auth | Token | | Tailscale exposure | Off | | Gateway token | Create a strong random token | | Chat channel | Telegram or WhatsApp | | Skills | No | | Hooks | Skip for Now |

Critical: Select "Off" for Tailscale exposure. Selecting "Serve" triggers proxy logic that causes crashes. Tailscale already handles your secure access — you don't need OpenClaw to configure it separately.

Enable HTTP Authentication

After setup completes, the container will be running but your browser will block access because you're connecting over HTTP. Since Tailscale already encrypts your traffic end-to-end, you can safely enable HTTP auth:

# Install jq in the container
docker compose exec -u root openclaw-gateway bash -c "apt update && apt install -y jq"

# Enable insecure auth (safe because Tailscale handles encryption)
docker compose exec -T openclaw-gateway bash -c '
jq ".gateway.controlUi.allowInsecureAuth = true" \
/home/node/.openclaw/openclaw.json > /home/node/.openclaw/tmp.json && \
mv /home/node/.openclaw/tmp.json /home/node/.openclaw/openclaw.json'

# Restart to apply
docker compose restart

This is safe because no ports are exposed to the public internet. "Insecure" here means HTTP rather than HTTPS — Tailscale already provides the encryption layer.


Phase 4: Access and Verify

Check Container Status

docker compose ps

Watch for 10 seconds. If the containers stay "Up," they're stable.

Get Your Tailscale IP

tailscale ip -4

This returns your private Tailscale address — something like 100.x.x.x.

Open the Web Interface

On your local machine (which must also have Tailscale running and connected), open:

http://<YOUR-TAILSCALE-IP>:18789

Enter the Gateway Token you created during setup. You should see the OpenClaw dashboard.

Your agent is now running on private cloud infrastructure, accessible only through your encrypted Tailscale network.


Ongoing Maintenance

Set API Spend Limits

OpenClaw agents can occasionally loop and burn through API credits. Set hard monthly limits before this happens:

A $20-30/month hard limit prevents surprise bills.

Back Up Agent Memory

OpenClaw stores long-term memory in Markdown files. If you lose the config directory, the bot loses everything it knows about your workflows and preferences.

tar -czvf memory_backup_$(date +%F).tar.gz ./openclaw/memory

Add this as a cron job for daily automated backups.

Monitor Logs

docker compose logs -f

The -f flag follows logs in real-time. Run this when debugging unexpected behavior.

Update OpenClaw

cd ~/openclaw
git pull
docker compose pull
docker compose up -d

What You've Built

At the end of this setup, you have:

  • Non-standard SSH port (2222) with key-only authentication
  • Dual-layer firewall (AWS Security Groups + UFW)
  • Docker containerization for clean isolation between OpenClaw and your host system
  • Tailscale private networking — no public ports for the application
  • A 24/7 AI agent accessible from any device on your Tailnet

The key security property: your bot's web interface (port 18789) is never exposed to the public internet. All access flows through your private Tailscale network.

Links:


Want this setup handled for you? Remote OpenClaw does the full server configuration, Docker setup, Tailscale integration, and initial hardening on your VPS of choice — without you needing to touch a command line. See the packages.