Skip to Content

OpenClaw Docker VPS Deploy: Run Your Own AI Agent Gateway in Under 30 Minutes

Deploy OpenClaw on any VPS using Docker Compose — get a production-ready AI agent gateway with automatic HTTPS, persistent storage, and zero local dependencies.

OpenClaw is the open-source AI agent platform that lets you run autonomous agents from Telegram, Slack, or a web UI — all connected to the LLM provider of your choice. The managed version is convenient, but self-hosting gives you full control over your data, your models, and your agent logic. This OpenClaw Docker VPS deploy guide shows you how to go from a fresh server to a production-ready gateway in under 30 minutes, using Docker Compose, Nginx, and Let's Encrypt TLS.

Related reads:

Prerequisites

Before you start, make sure you have:

  • A VPS running Ubuntu 22.04 LTS or Debian 12 (both are well-tested)
  • Minimum 2 vCPU, 4 GB RAM, 40 GB SSD (8 GB RAM recommended for production with multiple agents)
  • A non-root sudo user on the server
  • A domain or subdomain with an A record pointing to your VPS IP
  • SSH access and basic familiarity with the Linux terminal
  • API keys for at least one LLM provider (Anthropic, OpenAI, or a local endpoint via Ollama)

Firewall note: OpenClaw's gateway defaults to port 3000 internally. We'll bind it to localhost and expose only HTTPS through Nginx. No ports need to be open beyond 22 (SSH), 80, and 443.

What Is OpenClaw and Why Self-Host It?

OpenClaw is an open-source AI agent runtime that connects to messaging channels (Telegram, Slack, webchat), executes tool calls, manages memory, and routes requests to LLM providers. Unlike closed platforms, you control the entire stack: which models to use, which tools to enable, where data lives, and how agents behave.

Why Docker on a VPS?

  • No dependency hell — Docker bundles Node.js, Python, and system libraries. Your host stays clean.
  • Reproducible deploys — the same Compose file works on your laptop, a test VPS, and production.
  • Easy updates — pull a new image, recreate the container, done. No package manager conflicts.
  • Isolated state — config, memory, and agent files live in named volumes that survive container restarts.
  • Always-on — a VPS runs 24/7, so your agents respond to webhooks and scheduled tasks even when your laptop is closed.

Self-hosting also insulates you from third-party policy changes. When platform decisions shift — and they do — your deployment stays online because you control the infrastructure. For context on why this matters, see our coverage of Microsoft's own OpenClaw-like agent efforts and the broader enterprise AI agent landscape.

Step 1: Prepare Your VPS

Start with a clean server. Update packages, configure the firewall, and create a dedicated user for running OpenClaw.

System Updates and Firewall

# SSH into your server
ssh your-user@your-server-ip

# Update system packages
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git ufw

# Configure firewall — only SSH, HTTP, and HTTPS
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo ufw status

Create a Dedicated User (Recommended)

# Create a dedicated user for OpenClaw
sudo useradd -m -s /bin/bash openclaw
sudo usermod -aG sudo openclaw
sudo su - openclaw

Running OpenClaw under a dedicated user limits blast radius if something goes wrong. It's a small step that pays off in production.

Step 2: Install Docker and Docker Compose

Don't install Docker from Ubuntu's default apt repo — it's usually outdated. Use Docker's official install script.

Install Docker Engine

# Download and run the official Docker installer
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Add your user to the docker group
sudo usermod -aG docker $USER
newgrp docker

Verify the Installation

# Check versions
docker --version
docker compose version

# Run the hello-world test
docker run hello-world

If hello-world completes without errors, Docker is installed correctly and you're ready to move on.

Step 3: Deploy OpenClaw with Docker Compose

This is the core of the OpenClaw Docker VPS deploy. We'll define the full stack — OpenClaw gateway, PostgreSQL database, and Redis cache — in a single Compose file.

Create the Project Directory

# Create and enter the project directory
mkdir -p ~/openclaw && cd ~/openclaw

Write the docker-compose.yml

cat > docker-compose.yml <<'EOF'
version: '3.9'

services:
  openclaw:
    image: openclaw/openclaw:latest
    container_name: openclaw_gateway
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://openclaw:${DB_PASSWORD}@db:5432/openclaw
      - REDIS_URL=redis://redis:6379
      - OPENCLAW_SECRET=${OPENCLAW_SECRET}
      - OPENCLAW_HOST=https://${DOMAIN}
    depends_on:
      - db
      - redis
    volumes:
      - openclaw_data:/app/data

  db:
    image: postgres:16-alpine
    container_name: openclaw_db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=openclaw
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=openclaw
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    container_name: openclaw_redis
    restart: unless-stopped
    volumes:
      - redis_data:/data

volumes:
  openclaw_data:
  postgres_data:
  redis_data:
EOF

Key design decisions here:

  • The gateway binds to 127.0.0.1:3000 — not exposed to the internet. Nginx handles public access.
  • PostgreSQL 16 and Redis 7 use Alpine images for minimal footprint.
  • Named volumes persist data across container restarts and recreations.

Create the .env File

cat > .env <<'EOF'
DB_PASSWORD=change_this_to_a_strong_password
OPENCLAW_SECRET=$(openssl rand -hex 32)
DOMAIN=openclaw.yourdomain.com
EOF

# Lock down permissions
chmod 600 .env

Security note: Never commit .env to Git. Add it to .gitignore immediately. For team deployments, use a secrets manager or Docker secrets instead of plain files.

Start the Stack

# Start all services in detached mode
docker compose up -d

# Verify all containers are running
docker compose ps

# Tail the gateway logs
docker compose logs -f openclaw

All three containers should show Up status. The gateway is now running but only accessible from localhost — we'll fix that with Nginx next.

Step 4: Set Up Nginx as a Reverse Proxy with TLS

Never expose OpenClaw directly on port 3000. Nginx sits in front, terminates TLS, and proxies requests to the container.

Install Nginx and Certbot

sudo apt install -y nginx certbot python3-certbot-nginx
sudo systemctl enable nginx
sudo systemctl start nginx

Create the Nginx Site Config

# Create the site configuration
sudo tee /etc/nginx/sites-available/openclaw <<'EOF'
server {
    listen 80;
    server_name openclaw.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 86400s;
    }
}
EOF

# Enable the site
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Issue a TLS Certificate

# Request a Let's Encrypt certificate
sudo certbot --nginx -d openclaw.yourdomain.com --non-interactive --agree-tos -m [email protected]

# Verify auto-renewal works
sudo certbot renew --dry-run

Certbot automatically edits your Nginx config to add HTTPS and sets up auto-renewal. Your OpenClaw instance is now accessible securely at https://openclaw.yourdomain.com.

Step 5: Post-Install Configuration

The server is up. Now make it production-ready with database migrations, admin accounts, and LLM provider setup.

Run Database Migrations

OpenClaw ships with a migration command. Run it once after the first boot:

docker compose exec openclaw openclaw db migrate

Create Your Admin Account

docker compose exec openclaw openclaw admin create \
  --email [email protected] \
  --password your_secure_password

Configure LLM Provider API Keys

Add your API keys to the .env file and restart the stack:

# Add to your .env file
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx
OPENAI_API_KEY=sk-xxxxxxxxxxxx

# Restart to pick up new environment variables
docker compose down && docker compose up -d

Enable Automatic Container Restarts

The restart: unless-stopped policy in the Compose file handles container-level restarts. To survive full server reboots, enable Docker's systemd service:

sudo systemctl enable docker
sudo systemctl status docker

Step 6: Connect a Messaging Channel

OpenClaw shines when you can talk to it from anywhere. Telegram is the easiest channel to set up on a VPS.

Telegram Bot Setup

  • Message @BotFather on Telegram and run /newbot
  • Follow the prompts to name your bot and get a token
  • Copy the bot token for the next step

Register the Bot with OpenClaw

# Add the Telegram channel
docker compose exec openclaw openclaw channels add \
  --channel telegram \
  --token "YOUR_BOT_TOKEN"

Send a message to your bot on Telegram. OpenClaw will respond, confirming the channel is wired up and your agent gateway is live.

Tips, Gotchas, and Troubleshooting

Problem: Container Won't Start

Check logs first. The most common causes are missing environment variables, port conflicts, or the database not being ready.

# View all container logs
docker compose logs

# Tail a specific service
docker compose logs -f openclaw
docker compose logs -f db

Problem: Port 3000 Already in Use

Something else is bound to port 3000. Find it and kill it, or change the host port in your Compose file:

# Find what's using port 3000
sudo lsof -i :3000

# Change the port mapping in docker-compose.yml if needed:
# ports:
#   - "127.0.0.1:3001:3000"

Problem: Database Connection Refused

Make sure the db service is fully healthy before OpenClaw tries to connect. Check Postgres readiness:

# Check if postgres is accepting connections
docker compose exec db pg_isready -U openclaw

# If the db container is restarting, check its logs
docker compose logs -f db

Problem: Nginx 502 Bad Gateway

This almost always means the OpenClaw container isn't running or isn't listening on port 3000 inside the container. Check:

# Verify all services are Up
docker compose ps

# Test from the server
curl http://127.0.0.1:3000/healthz

# Check Nginx config syntax
sudo nginx -t

Problem: TLS Certificate Issues

Let's Encrypt validates by hitting port 80 on your domain. Make sure DNS resolves correctly before running Certbot:

# Check DNS resolution from your machine
dig +short openclaw.yourdomain.com

# Test certificate renewal
sudo certbot renew --dry-run

Problem: Out of Memory

If containers are getting OOM-killed, check resource usage. On a 2 GB VPS, add swap:

# Add a 2GB swap file
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

Pro Tips

  • Pin image versions in production. The :latest tag auto-updates on pull, which can introduce breaking changes. Pin to a specific version like openclaw/openclaw:1.4.2 once you're stable.
  • Back up your database daily. PostgreSQL holds your agent config, memory, and credentials. A simple pg_dump cron job is enough for most setups.
  • Monitor with Uptime Kuma. It's lightweight, Docker-native, and takes 5 minutes to set up on the same VPS.
  • Rate-limit Nginx if you're exposing OpenClaw to the public internet. A simple limit_req_zone directive prevents abuse.
  • Use a managed database for HA. Self-hosting Postgres is fine for small deployments, but for serious production use, consider a managed Postgres service.
  • Keep an eye on the ecosystem. As Microsoft and others build OpenClaw-like agents, the space is evolving fast. Self-hosting keeps you independent of platform shifts.

Wrapping Up

A complete OpenClaw Docker VPS deploy gives you a self-hosted AI agent gateway that you control entirely. No cloud platform surprises, no data leaving your infrastructure, and full freedom to extend and customize. With Docker Compose, you get reproducible deploys, isolated state, and clean updates. With Nginx and Let's Encrypt, you get production-grade TLS termination without the complexity.

The setup is straightforward: prepare your VPS, install Docker, define the Compose stack, configure Nginx with TLS, run migrations, and connect your first messaging channel. From there, iterate — add more LLM providers, enable custom tools, or scale to multiple agent instances.

Start with the Compose file in this guide, verify your health endpoints, and send your first message through Telegram. Once you see your agent responding from a server you own, you'll understand why teams are moving their AI infrastructure off managed platforms.

Need Help Scaling OpenClaw for Your Team?

This guide covers a solid single-node production deployment. If you're looking at multi-node setups, enterprise SSO integration, custom agent pipelines, or managed OpenClaw hosting for your organization — the architecture gets more involved. The sysbrix team designs and deploys production AI agent infrastructure for teams who need reliability without the ops overhead.

Talk to Us About Enterprise OpenClaw Deployment →

n8n Coolify Deployment: Self-Host Workflow Automation Without the DevOps Headache
Deploy n8n on Coolify with PostgreSQL, Redis, and queue mode — get production-ready workflow automation with automatic HTTPS and zero manual server config.