How to

Clawdbot with Docker and Ollama: Self-Hosted AI Stack Guide

Build your own private AI stack on a VPS! Learn how to deploy Clawdbot with Docker and Ollama in this complete, step-by-step self-hosted setup guide.

is*hosting team 4 Jun 2026 5 min reading
Clawdbot with Docker and Ollama: Self-Hosted AI Stack Guide
Table of Contents

Clawdbot combined with Docker and Ollama is a self-hosted AI agent stack that runs local language models on your own VPS without touching the OpenAI API. OpenClaw handles agent logic, Docker keeps everything isolated, and Ollama runs inference locally.

Why Docker + Ollama for Clawdbot?

What Docker Adds

Pinned dependencies, reproducible behavior, and two-second restarts. OpenClaw had a command-injection advisory in 2026 (GHSA-mc68-q9jw-2h3v), so pin versions; don't use latest.

What Ollama Adds

Ollama runs LLaMA, Mistral, Qwen, and Phi locally. It exposes a native /api/chat endpoint (required for tool calling) and an OpenAI-compatible /v1. Use /api/chat.

Clawdbot + OpenAI API vs. Clawdbot + Ollama

Self-hosting trades metered API bills for flat hardware costs. Data stays on your server, which matters if you're working under GDPR or HIPAA. The tradeoff: local models aren't GPT-4, but qwen2.5-coder:32b or gpt-oss:20b handle most agent loops just fine.

Server Requirements

What do you need to run Clawdbot with Docker and Ollama?

  • Memory: 16 GB RAM minimum for 8B models
  • OS: Ubuntu 22.04 LTS or Debian 12
  • Software: Docker Engine 24+ and Docker Compose v2
  • Storage: 80 GB free disk
  • Network: Domain name for SSL
  • Processor: CPU with AVX2 (cat /proc/cpuinfo | grep -m1 avx2)
  • GPU (optional): On a 4–6 vCPU CPU-only machine with 16 GB RAM, an 8B Q4 model outputs 2–6 tokens/sec. A GPU card typically gets you 10–20x that, though exact numbers depend on the card.

Note: OpenClaw requires a 64k context window, which roughly doubles memory use compared to a 4k default.

Minimum, Recommended, and Heavy-Load Configurations

Tier

vCPU

RAM

Storage

Model capacity

is*hosting VPS

Minimum

4

16 GB

80 GB SSD

7B Q4, short context

VPS Elite

Recommended

6

24–32 GB

120 GB NVMe

8B–14B Q4 at 64k context

VPS Exclusive

Heavy (CPU)

8

64 GB

200 GB NVMe

32B Q4 or 70B Q4 with offload

VPS Exclusive + RAM and drive upgrade

GPU

8 vCPU + 24 GB VRAM

32 GB

200 GB NVMe

14B–32B at full speed

is*hosting GPU server

Heavy GPU

8 vCPU + 48 GB VRAM

64 GB

400 GB NVMe

70B Q4 (~40 GB VRAM for weights)

GPU server (top tier)

70B Q4 needs ~40 GB VRAM for weights alone. A 16 GB card will OOM.

VPS in 5-15 minutes

Get dedicated resources and KVM isolation for experiments worldwide.

Choose VPS

Step 1: Setting Up Docker and the Clawdbot Container

Installing Docker on Ubuntu 22.04

Don't use apt install docker.io; use the official repo:

sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
newgrp docker

docker-compose.yml: Base Config

OpenClaw ignores LLM_PROVIDER. Config lives in ~/.openclaw/openclaw.json.

services:
  clawdbot:
    image: openclaw/openclaw:0.17
    container_name: clawdbot
    restart: unless-stopped
    environment:
      OLLAMA_API_KEY: "ollama-local"
    volumes:
      - ./data:/home/openclaw/.openclaw
      - ./openclaw.json:/home/openclaw/.openclaw/openclaw.json:ro
      - ./logs:/home/openclaw/.openclaw/logs
    ports:
      - "127.0.0.1:8080:8080"

Create openclaw.json

{
  "agents": {
    "defaults": { "model": { "primary": "ollama/llama3.1:8b" } }
  },
  "models": {
    "providers": {
      "ollama": {
        "baseUrl": "http://ollama:11434",
        "apiKey": "ollama-local",
        "api": "ollama",
        "models": [
          {
            "id": "llama3.1:8b",
            "name": "LLaMA 3.1 8B",
            "contextWindow": 65536,
            "maxTokens": 8192,
            "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
          }
        ]
      }
    }
  }
}

Two mistakes that kill the setup immediately:

  • Binding to 0.0.0.0. Using ports: - "8080:8080" exposes the agent port directly and bypasses UFW via Docker iptables. Always bind to 127.0.0.1:8080:8080.
  • Skipping restart policy. Without restart: unless-stopped, crashed containers stay down until you notice.

Step 2: Installing Ollama and Choosing Your Model

Note: This systemd setup only covers the host-Ollama option. If you are going straight to the Full Stack docker-compose.yml in Step 4, skip this step; Ollama runs as a container there.

Installing Ollama as a Systemd Service

curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl edit ollama

Add the following environment variables:

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_NUM_PARALLEL=2"
Environment="OLLAMA_KEEP_ALIVE=30m"

Restart and pull your desired model:

sudo systemctl daemon-reload
sudo systemctl restart ollama
ollama pull llama3.1:8b

LLaMA 3.1 vs. Mistral vs. Qwen2.5: Which Fits Your RAM?

OpenClaw requires tool-capable models. Check support before committing:

ollama show qwen2.5-coder:7b --modelfile | grep -i tool

Model

File size (Q4)

RAM at 64k context

Notes

Mistral 7B

4.1 GB

~10 GB

Weaker tool calling

LLaMA 3.1 8B

4.7 GB

~12 GB

Strong tool calling

Qwen2.5-Coder 7B

4.4 GB

~11 GB

OpenClaw's pick for coding

gpt-oss 20B

12 GB

~20 GB

OpenClaw's recommended default

Step 3: Connecting Clawdbot to Ollama

Config Details

Use "api": "ollama". The native /api/chat endpoint supports tools and streaming; /v1 does not. Don't put /v1 in baseUrl. Set contextWindow to 65536 explicitly.

Docker Networking: Host vs. Bridge

localhost inside a bridge-network container resolves to the container itself, not the host. http://localhost:11434 will fail.

The fix: run Ollama as a container on the same Compose network and connect via http://ollama:11434.

Step 4: Production Hardening

SSL with Nginx + Certbot

Nginx won't start without certs; Certbot needs port 80 open first. Bootstrap with HTTP, then swap to SSL.

Create nginx/conf.d/clawdbot.conf:

server {
    listen 80;
    server_name your-domain.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        proxy_pass http://clawdbot:8080;
        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_buffering off;
        proxy_read_timeout 300s;
    }
}

Start Nginx, then issue certs:

sudo apt install -y certbot
sudo mkdir -p /var/www/certbot
sudo certbot certonly --webroot -w /var/www/certbot -d your-domain.com --agree-tos -m [email protected] --non-interactive

Note: /var/www/certbot on the host is mounted into the Nginx container via the volume declared in docker-compose.yml. Start Nginx with the HTTP-only config first, then run certbot, then swap to the SSL config and reload.

Swap to the SSL config:

server {
    listen 80;
    server_name your-domain.com;
    location /.well-known/acme-challenge/ { root /var/www/certbot; }
    location / { return 301 https://$host$request_uri; }
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://clawdbot:8080;
        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_buffering off;
        proxy_read_timeout 300s;
    }
}

Reload Nginx:

docker compose exec nginx nginx -s reload

Auth, Backups, and Firewall

  • Auth: Add Nginx basic auth or an IP allowlist.
  • Backups: tar the ./data, openclaw.json, and nginx/conf.d directories. Store off-box.
  • Memory limits: Add them in Compose to prevent OOM kills.
  • Firewall: Docker-mapped ports bypass UFW. Keep Ollama on the internal Compose network only; don't expose port 11434.

Full Stack docker-compose.yml

services:
  clawdbot:
    image: openclaw/openclaw:0.17
    container_name: clawdbot
    restart: unless-stopped
    environment:
      OLLAMA_API_KEY: "ollama-local"
    volumes:
      - ./data:/home/openclaw/.openclaw
      - ./openclaw.json:/home/openclaw/.openclaw/openclaw.json:ro
      - ./logs:/home/openclaw/.openclaw/logs
    depends_on:
      ollama:
        condition: service_healthy
      ollama-bootstrap:
        condition: service_completed_successfully
    networks:
      - agentnet
    deploy:
      resources:
        limits:
          memory: 2g

  ollama:
    image: ollama/ollama:0.5.4
    container_name: ollama
    restart: unless-stopped
    environment:
      OLLAMA_KEEP_ALIVE: "30m"
      OLLAMA_NUM_PARALLEL: "2"
    volumes:
      - ollama_models:/root/.ollama
    healthcheck:
      test: ["CMD-SHELL", "ollama list >/dev/null 2>&1 || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 60s
    networks:
      - agentnet
    deploy:
      resources:
        limits:
          memory: 14g

  ollama-bootstrap:
    image: ollama/ollama:0.5.4
    depends_on:
      ollama:
        condition: service_healthy
    entrypoint: ["/bin/sh", "-c"]
    command: ["OLLAMA_HOST=http://ollama:11434 ollama pull llama3.1:8b"]
    networks:
      - agentnet
    restart: "no"

  nginx:
    image: nginx:1.27-alpine
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - /etc/letsencrypt:/etc/letsencrypt:ro
      - /var/www/certbot:/var/www/certbot:ro
    depends_on:
      - clawdbot
    networks:
      - agentnet

networks:
  agentnet:
    driver: bridge

volumes:
  ollama_models:

Start and Verify

docker compose up -d
docker compose exec clawdbot wget -qO- http://ollama:11434/api/tags
ss -ltnp | grep -E '8080|11434|80|443'

Wrapping Up

Rent a 16–32 GB VPS, install Docker, run Ollama and OpenClaw in a shared Compose network, and proxy via Nginx with HTTPS. Use the native /api/chat, and set the context window to 64k or higher.

The recommended setup maps to is*hosting's Elite or Exclusive VPS: enough RAM for an 8B–14B model at full 64k context. For 32B+ models, jump to Exclusive with RAM upgrade or move to a GPU server.

Dedicated Server with GPU

Power for ML, rendering, and compute-heavy tasks.

From $91.67/mo