{"id":187,"date":"2026-05-10T00:00:00","date_gmt":"2026-05-10T00:00:00","guid":{"rendered":"https:\/\/local.paioclawblog.com\/openclaw-docker-setup\/"},"modified":"2026-05-10T00:00:00","modified_gmt":"2026-05-10T00:00:00","slug":"openclaw-docker-setup","status":"publish","type":"post","link":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/","title":{"rendered":"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup)"},"content":{"rendered":"\n<div>\n<p><strong>Meta Description:<\/strong> Install OpenClaw with Docker in 5 minutes. Drop-in docker-compose.yml, env file structure, volume mounts for memory persistence, and WhatsApp\/Telegram socket mapping explained.<\/p>\n<div><\/div>\n<p>Docker turns &#8220;works on my machine&#8221; into &#8220;works everywhere.&#8221; One command, your AI agent is running. No dependency hell. No version conflicts. No &#8220;but it worked yesterday.&#8221;<\/p>\n<p>OpenClaw in Docker means you can spin up an instance in 5 minutes, tear it down just as fast, and move it between servers without reconfiguring anything.<\/p>\n<p>This guide covers the drop-in docker-compose setup, environment file structure, volume mounts for memory persistence, and the gotcha around mapping WhatsApp\/Telegram sockets that trips up first-timers.<\/p>\n<p>By the end, you&#8217;ll have OpenClaw running in a container with persistent memory and messaging integrations working.<\/p>\n<h2 id=\"why-docker-for-openclaw\">Why Docker for OpenClaw<\/h2>\n<p><strong>The traditional install:<\/strong><\/p>\n<ul>\n<li>Install Node.js (specific version)<\/li>\n<li>Install dependencies (hope nothing breaks)<\/li>\n<li>Configure environment<\/li>\n<li>Set up system services<\/li>\n<li>Debug path issues<\/li>\n<li>Repeat on every server<\/li>\n<\/ul>\n<p><strong>The Docker install:<\/strong><\/p>\n<ul>\n<li>Pull image<\/li>\n<li>Run container<\/li>\n<li>Done<\/li>\n<\/ul>\n<p><strong>Benefits:<\/strong><\/p>\n<p><strong>Isolation:<\/strong> OpenClaw and dependencies contained. Won&#8217;t conflict with other apps on your server.<\/p>\n<p><strong>Portability:<\/strong> Same container runs on your laptop, VPS, or cloud. No environment differences.<\/p>\n<p><strong>Reproducibility:<\/strong> Everyone gets identical setup. No &#8220;works for me&#8221; bugs.<\/p>\n<p><strong>Rollback:<\/strong> Bad update? Revert to previous image instantly.<\/p>\n<p><strong>Scaling:<\/strong> Need 5 instances? Copy the docker-compose, change ports, run.<\/p>\n<p><strong>The tradeoff:<\/strong> Slightly more disk space (image overhead) and marginal performance cost (containerization). For most users, worth it.<\/p>\n<h2 id=\"prerequisites\">Prerequisites<\/h2>\n<p><strong>Install Docker:<\/strong><\/p>\n<p><strong>Ubuntu\/Debian:<\/strong><\/p>\n<div><pre><code>curl -fsSL https:\/\/get.docker.com -o get-docker.sh\nsudo sh get-docker.sh\nsudo usermod -aG docker $USER\nnewgrp docker\n<\/code><\/pre><\/div>\n<p><strong>macOS:<\/strong>\nDownload Docker Desktop from docker.com<\/p>\n<p><strong>Windows:<\/strong>\nDownload Docker Desktop from docker.com (requires WSL2)<\/p>\n<p><strong>Verify:<\/strong><\/p>\n<div><pre><code>docker --version\ndocker-compose --version\n<\/code><\/pre><\/div>\n<p>Should show Docker 20+ and Docker Compose 2+.<\/p>\n<h2 id=\"the-5-minute-setup\">The 5-Minute Setup<\/h2>\n<h3>Step 1: Create Project Directory<\/h3>\n<div><pre><code>mkdir openclaw-docker\ncd openclaw-docker\n<\/code><\/pre><\/div>\n<h3>Step 2: Create docker-compose.yml<\/h3>\n<p>Create <code>docker-compose.yml<\/code>:<\/p>\n<div><pre><code>version: '3.8'\n\nservices:\n  openclaw:\n    image: openclaw\/openclaw:latest\n    container_name: openclaw\n    restart: unless-stopped\n    \n    env_file:\n      - .env\n    \n    volumes:\n      # Memory persistence\n      - .\/data:\/app\/data\n      \n      # Configuration\n      - .\/config:\/app\/config\n      \n      # Logs\n      - .\/logs:\/app\/logs\n      \n      # WhatsApp socket (important!)\n      - .\/whatsapp:\/app\/.wwebjs_auth\n      \n      # Telegram session\n      - .\/telegram:\/app\/telegram-sessions\n    \n    ports:\n      - \"3000:3000\"\n    \n    # Optional: expose web UI\n    # - \"8080:8080\"\n    \n    networks:\n      - openclaw-net\n\nnetworks:\n  openclaw-net:\n    driver: bridge\n<\/code><\/pre><\/div>\n<p><strong>What this does:<\/strong><\/p>\n<ul>\n<li><strong>image:<\/strong> Pulls official OpenClaw Docker image<\/li>\n<li><strong>restart:<\/strong> Auto-restart if container crashes<\/li>\n<li><strong>env_file:<\/strong> Loads environment variables from .env<\/li>\n<li><strong>volumes:<\/strong> Maps local directories to container (data persists)<\/li>\n<li><strong>ports:<\/strong> Exposes OpenClaw API (and optionally web UI)<\/li>\n<\/ul>\n<h3>Step 3: Create .env File<\/h3>\n<p>Create <code>.env<\/code>:<\/p>\n<div><pre><code># Core Configuration\nNODE_ENV=production\nOPENCLAW_API_KEY=your-secret-api-key-here\n\n# Telegram\nTELEGRAM_ENABLED=true\nTELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11\nTELEGRAM_PHONE_NUMBER=+15551234567\n\n# WhatsApp\nWHATSAPP_ENABLED=true\nWHATSAPP_SESSION_NAME=openclaw-session\n\n# Discord\nDISCORD_ENABLED=false\nDISCORD_BOT_TOKEN=your-discord-bot-token\n\n# Slack\nSLACK_ENABLED=false\nSLACK_BOT_TOKEN=xoxb-your-slack-token\nSLACK_APP_TOKEN=xapp-your-app-token\n\n# Google Calendar\nGOOGLE_CALENDAR_ENABLED=false\nGOOGLE_CLIENT_ID=your-google-client-id\nGOOGLE_CLIENT_SECRET=your-google-secret\n\n# Memory Backend\nMEMORY_BACKEND=sqlite\nMEMORY_DB_PATH=\/app\/data\/memory.db\n\n# Logging\nLOG_LEVEL=info\nLOG_FILE=\/app\/logs\/openclaw.log\n<\/code><\/pre><\/div>\n<p><strong>Security note:<\/strong> Add <code>.env<\/code> to <code>.gitignore<\/code>. Never commit tokens.<\/p>\n<h3>Step 4: Create Directory Structure<\/h3>\n<div><pre><code>mkdir -p data config logs whatsapp telegram\n<\/code><\/pre><\/div>\n<h3>Step 5: Start OpenClaw<\/h3>\n<div><pre><code>docker-compose up -d\n<\/code><\/pre><\/div>\n<p><strong>What happens:<\/strong><\/p>\n<ol>\n<li>Docker pulls openclaw\/openclaw:latest image (if not cached)<\/li>\n<li>Creates container from image<\/li>\n<li>Mounts volumes<\/li>\n<li>Loads .env<\/li>\n<li>Starts OpenClaw in background (-d flag)<\/li>\n<\/ol>\n<p><strong>Check status:<\/strong><\/p>\n<div><pre><code>docker-compose ps\n<\/code><\/pre><\/div>\n<p>Should show:<\/p>\n<div><pre><code>NAME                COMMAND             STATUS              PORTS\nopenclaw            \"node index.js\"     Up 10 seconds       0.0.0.0:3000-&gt;3000\/tcp\n<\/code><\/pre><\/div>\n<p><strong>View logs:<\/strong><\/p>\n<div><pre><code>docker-compose logs -f\n<\/code><\/pre><\/div>\n<p>You should see:<\/p>\n<div><pre><code>[INFO] OpenClaw starting...\n[INFO] Telegram bot connected\n[INFO] WhatsApp initializing...\n[INFO] Agent ready\n<\/code><\/pre><\/div>\n<h2 id=\"volume-mounts-explained\">Volume Mounts Explained<\/h2>\n<p><strong>Why volumes matter:<\/strong> Containers are ephemeral. When container stops, data inside vanishes. Volumes persist data on host machine.<\/p>\n<h3>Critical Volumes<\/h3>\n<p><strong>.\/data \u2192 \/app\/data<\/strong><\/p>\n<ul>\n<li>Memory database (conversations, user context)<\/li>\n<li>Agent state<\/li>\n<li>Cached data<\/li>\n<\/ul>\n<p><strong>Without this:<\/strong> Every restart = fresh agent with no memory.<\/p>\n<p><strong>.\/config \u2192 \/app\/config<\/strong><\/p>\n<ul>\n<li>Custom skills<\/li>\n<li>Agent configuration<\/li>\n<li>Workflow definitions<\/li>\n<\/ul>\n<p><strong>.\/whatsapp \u2192 \/app\/.wwebjs_auth<\/strong><\/p>\n<ul>\n<li>WhatsApp session data<\/li>\n<li>QR code auth persistence<\/li>\n<li>Message encryption keys<\/li>\n<\/ul>\n<p><strong>Without this:<\/strong> Re-scan QR code every restart.<\/p>\n<p><strong>.\/telegram \u2192 \/app\/telegram-sessions<\/strong><\/p>\n<ul>\n<li>Telegram session files<\/li>\n<li>Auth tokens<\/li>\n<\/ul>\n<p><strong>Without this:<\/strong> Re-authenticate every restart.<\/p>\n<h3>View Volume Data<\/h3>\n<div><pre><code>ls -la data\/\n# Shows memory.db, cache files\n\nls -la whatsapp\/\n# Shows WhatsApp session\n<\/code><\/pre><\/div>\n<h2 id=\"the-whatsapptelegram-socket-gotcha\">The WhatsApp\/Telegram Socket Gotcha<\/h2>\n<p><strong>The problem:<\/strong> WhatsApp uses a persistent WebSocket connection. When container restarts, connection breaks. Session must be remounted.<\/p>\n<h3>WhatsApp Volume Mapping<\/h3>\n<p><strong>Correct:<\/strong><\/p>\n<div><pre><code>volumes:\n  - .\/whatsapp:\/app\/.wwebjs_auth\n<\/code><\/pre><\/div>\n<p><strong>Maps the ENTIRE .wwebjs_auth directory<\/strong>, not just session file.<\/p>\n<p><strong>Why this matters:<\/strong> WhatsApp stores:<\/p>\n<ul>\n<li>Session credentials<\/li>\n<li>Message keys<\/li>\n<li>Media cache<\/li>\n<li>Browser session data<\/li>\n<\/ul>\n<p><strong>If volume is missing:<\/strong> You&#8217;ll re-scan QR code on every restart.<\/p>\n<h3>First-Time WhatsApp Setup<\/h3>\n<p><strong>Start container:<\/strong><\/p>\n<div><pre><code>docker-compose up\n<\/code><\/pre><\/div>\n<p><strong>Watch logs:<\/strong><\/p>\n<div><pre><code>docker-compose logs -f openclaw\n<\/code><\/pre><\/div>\n<p>You&#8217;ll see:<\/p>\n<div><pre><code>[WhatsApp] QR Code:\n\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584 \u2588\u2580\u2588 \u2588\u2584\u2584\u2580\u2584\u2580\u2580 \u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\n\u2588\u2588\u2588\u2588 \u2588   \u2588 \u2588\u2580\u2580\u2580\u2588 \u2580 \u2580\u2588 \u2588   \u2588 \u2588\u2588\u2588\u2588\n\u2588\u2588\u2588\u2588 \u2588\u2584\u2584\u2584\u2588 \u2588\u2580 \u2588\u2580\u2580 \u2584 \u2588 \u2588\u2584\u2584\u2584\u2588 \u2588\u2588\u2588\u2588\n...\n<\/code><\/pre><\/div>\n<p><strong>Scan with WhatsApp mobile app:<\/strong><\/p>\n<ol>\n<li>Open WhatsApp on phone<\/li>\n<li>Settings \u2192 Linked Devices \u2192 Link a Device<\/li>\n<li>Scan QR code from terminal<\/li>\n<\/ol>\n<p><strong>Once connected:<\/strong><\/p>\n<div><pre><code>[WhatsApp] Client is ready!\n<\/code><\/pre><\/div>\n<p>Session is now saved in <code>.\/whatsapp\/<\/code> volume.<\/p>\n<p><strong>Test persistence:<\/strong><\/p>\n<div><pre><code>docker-compose restart\n<\/code><\/pre><\/div>\n<p><strong>Should NOT show QR code again.<\/strong> If it does, volume isn&#8217;t mounted correctly.<\/p>\n<h3>Telegram Session Persistence<\/h3>\n<p>Similar issue with Telegram. Session files must persist.<\/p>\n<p><strong>Correct volume:<\/strong><\/p>\n<div><pre><code>- .\/telegram:\/app\/telegram-sessions\n<\/code><\/pre><\/div>\n<p><strong>First-time auth:<\/strong><\/p>\n<div><pre><code>[Telegram] Enter phone number: +15551234567\n[Telegram] Enter code from Telegram: 12345\n<\/code><\/pre><\/div>\n<p>After auth, session saved to <code>.\/telegram\/<\/code> volume.<\/p>\n<p><strong>Subsequent restarts:<\/strong> No re-auth needed.<\/p>\n<h2 id=\"environment-file-structure\">Environment File Structure<\/h2>\n<p>The <code>.env<\/code> file controls everything. Understanding its structure helps you customize.<\/p>\n<h3>Section 1: Core Settings<\/h3>\n<div><pre><code>NODE_ENV=production\nOPENCLAW_API_KEY=your-secret-key\n<\/code><\/pre><\/div>\n<p><strong>NODE_ENV:<\/strong> <code>development<\/code> or <code>production<\/code><\/p>\n<ul>\n<li>Production: Optimized, less logging<\/li>\n<li>Development: More logs, hot reload<\/li>\n<\/ul>\n<p><strong>OPENCLAW_API_KEY:<\/strong> Used if you expose API endpoints. Generate random string:<\/p>\n<div><pre><code>openssl rand -base64 32\n<\/code><\/pre><\/div>\n<h3>Section 2: Messaging Channels<\/h3>\n<p>Each channel has <code>_ENABLED<\/code> flag:<\/p>\n<div><pre><code>TELEGRAM_ENABLED=true\nWHATSAPP_ENABLED=true\nDISCORD_ENABLED=false\n<\/code><\/pre><\/div>\n<p><strong>Set to <code>false<\/code> to disable<\/strong> without removing credentials.<\/p>\n<h3>Section 3: Memory Backend<\/h3>\n<div><pre><code>MEMORY_BACKEND=sqlite\nMEMORY_DB_PATH=\/app\/data\/memory.db\n<\/code><\/pre><\/div>\n<p><strong>Options:<\/strong><\/p>\n<ul>\n<li><code>sqlite<\/code>: File-based (default, simple)<\/li>\n<li><code>postgres<\/code>: External database (production)<\/li>\n<li><code>redis<\/code>: In-memory (fast, requires Redis)<\/li>\n<\/ul>\n<p><strong>For Docker, SQLite is fine<\/strong> unless you need multi-container setup.<\/p>\n<h3>Section 4: Logging<\/h3>\n<div><pre><code>LOG_LEVEL=info\nLOG_FILE=\/app\/logs\/openclaw.log\n<\/code><\/pre><\/div>\n<p><strong>LOG_LEVEL options:<\/strong><\/p>\n<ul>\n<li><code>error<\/code>: Only errors<\/li>\n<li><code>warn<\/code>: Warnings and errors<\/li>\n<li><code>info<\/code>: Normal operation (recommended)<\/li>\n<li><code>debug<\/code>: Verbose (for troubleshooting)<\/li>\n<\/ul>\n<h3>Hot Reloading Environment<\/h3>\n<p><strong>Change .env:<\/strong><\/p>\n<div><pre><code>nano .env\n# Edit values\n<\/code><\/pre><\/div>\n<p><strong>Restart container:<\/strong><\/p>\n<div><pre><code>docker-compose restart\n<\/code><\/pre><\/div>\n<p>Changes apply immediately (no rebuild needed).<\/p>\n<h2 id=\"building-custom-image\">Building Custom Image<\/h2>\n<p>Want to add custom skills or modify OpenClaw?<\/p>\n<h3>Create Dockerfile<\/h3>\n<p>Create <code>Dockerfile<\/code>:<\/p>\n<div><pre><code>FROM openclaw\/openclaw:latest\n\n# Copy custom skills\nCOPY .\/custom-skills \/app\/skills\/custom\n\n# Copy custom config\nCOPY .\/my-config.yml \/app\/config\/agent.yml\n\n# Install additional dependencies (if needed)\nRUN npm install some-extra-package\n\n# Expose any additional ports\nEXPOSE 9000\n\nCMD [\"node\", \"index.js\"]\n<\/code><\/pre><\/div>\n<h3>Build Image<\/h3>\n<div><pre><code>docker build -t openclaw-custom:v1 .\n<\/code><\/pre><\/div>\n<h3>Update docker-compose.yml<\/h3>\n<div><pre><code>services:\n  openclaw:\n    image: openclaw-custom:v1  # Use your custom image\n    build:\n      context: .\n      dockerfile: Dockerfile\n<\/code><\/pre><\/div>\n<h3>Rebuild and Run<\/h3>\n<div><pre><code>docker-compose up --build -d\n<\/code><\/pre><\/div>\n<h2 id=\"multi-container-setup\">Multi-Container Setup<\/h2>\n<p>Run multiple OpenClaw instances for different users\/use cases.<\/p>\n<h3>Create docker-compose-multi.yml<\/h3>\n<div><pre><code>version: '3.8'\n\nservices:\n  openclaw-personal:\n    image: openclaw\/openclaw:latest\n    container_name: openclaw-personal\n    env_file:\n      - .env.personal\n    volumes:\n      - .\/data-personal:\/app\/data\n      - .\/whatsapp-personal:\/app\/.wwebjs_auth\n    ports:\n      - \"3001:3000\"\n    networks:\n      - openclaw-net\n\n  openclaw-work:\n    image: openclaw\/openclaw:latest\n    container_name: openclaw-work\n    env_file:\n      - .env.work\n    volumes:\n      - .\/data-work:\/app\/data\n      - .\/whatsapp-work:\/app\/.wwebjs_auth\n    ports:\n      - \"3002:3000\"\n    networks:\n      - openclaw-net\n\nnetworks:\n  openclaw-net:\n    driver: bridge\n<\/code><\/pre><\/div>\n<p><strong>Run both:<\/strong><\/p>\n<div><pre><code>docker-compose -f docker-compose-multi.yml up -d\n<\/code><\/pre><\/div>\n<p><strong>Result:<\/strong> Two isolated OpenClaw instances, different configs, different messaging accounts.<\/p>\n<h2 id=\"backup-and-restore\">Backup and Restore<\/h2>\n<h3>Backup<\/h3>\n<p><strong>Stop container:<\/strong><\/p>\n<div><pre><code>docker-compose down\n<\/code><\/pre><\/div>\n<p><strong>Backup volumes:<\/strong><\/p>\n<div><pre><code>tar -czf openclaw-backup-$(date +%Y%m%d).tar.gz data\/ whatsapp\/ telegram\/ config\/ .env\n<\/code><\/pre><\/div>\n<p><strong>Restart:<\/strong><\/p>\n<div><pre><code>docker-compose up -d\n<\/code><\/pre><\/div>\n<h3>Restore<\/h3>\n<p><strong>Extract backup:<\/strong><\/p>\n<div><pre><code>tar -xzf openclaw-backup-20260508.tar.gz\n<\/code><\/pre><\/div>\n<p><strong>Start container:<\/strong><\/p>\n<div><pre><code>docker-compose up -d\n<\/code><\/pre><\/div>\n<p>All data restored (memory, sessions, config).<\/p>\n<h2 id=\"updating-openclaw\">Updating OpenClaw<\/h2>\n<h3>Pull Latest Image<\/h3>\n<div><pre><code>docker-compose pull\n<\/code><\/pre><\/div>\n<h3>Restart with New Image<\/h3>\n<div><pre><code>docker-compose up -d\n<\/code><\/pre><\/div>\n<p>Docker pulls new version, restarts container. <strong>Your data (in volumes) is preserved.<\/strong><\/p>\n<h3>Rollback if Needed<\/h3>\n<p><strong>Check image history:<\/strong><\/p>\n<div><pre><code>docker images openclaw\/openclaw\n<\/code><\/pre><\/div>\n<p><strong>Run specific version:<\/strong><\/p>\n<div><pre><code>services:\n  openclaw:\n    image: openclaw\/openclaw:v1.2.3  # Specific version\n<\/code><\/pre><\/div>\n<div><pre><code>docker-compose up -d\n<\/code><\/pre><\/div>\n<h2 id=\"health-checks\">Health Checks<\/h2>\n<p>Add health check to docker-compose.yml:<\/p>\n<div><pre><code>services:\n  openclaw:\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http:\/\/localhost:3000\/health\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n      start_period: 40s\n<\/code><\/pre><\/div>\n<p><strong>Check health:<\/strong><\/p>\n<div><pre><code>docker inspect --format='{{.State.Health.Status}}' openclaw\n<\/code><\/pre><\/div>\n<p>Should return: <code>healthy<\/code><\/p>\n<h2 id=\"common-docker-issues\">Common Docker Issues<\/h2>\n<h3>&#8220;Port already in use&#8221;<\/h3>\n<p><strong>Error:<\/strong><\/p>\n<div><pre><code>Error starting userland proxy: listen tcp 0.0.0.0:3000: bind: address already in use\n<\/code><\/pre><\/div>\n<p><strong>Cause:<\/strong> Another process using port 3000.<\/p>\n<p><strong>Fix 1 &#8211; Change port:<\/strong><\/p>\n<div><pre><code>ports:\n  - \"3001:3000\"  # Host port 3001 instead\n<\/code><\/pre><\/div>\n<p><strong>Fix 2 &#8211; Kill process:<\/strong><\/p>\n<div><pre><code>sudo lsof -ti:3000 | xargs kill\n<\/code><\/pre><\/div>\n<h3>&#8220;Volume mount permission denied&#8221;<\/h3>\n<p><strong>Error:<\/strong><\/p>\n<div><pre><code>permission denied while trying to connect to the Docker daemon socket\n<\/code><\/pre><\/div>\n<p><strong>Cause:<\/strong> User not in docker group.<\/p>\n<p><strong>Fix:<\/strong><\/p>\n<div><pre><code>sudo usermod -aG docker $USER\nnewgrp docker\n<\/code><\/pre><\/div>\n<h3>&#8220;Container keeps restarting&#8221;<\/h3>\n<p><strong>Check logs:<\/strong><\/p>\n<div><pre><code>docker-compose logs openclaw\n<\/code><\/pre><\/div>\n<p><strong>Common causes:<\/strong><\/p>\n<ul>\n<li>Missing required env vars (.env incomplete)<\/li>\n<li>Bad credentials (Telegram token expired)<\/li>\n<li>Port conflict<\/li>\n<\/ul>\n<h3>&#8220;WhatsApp QR code on every restart&#8221;<\/h3>\n<p><strong>Cause:<\/strong> Volume not mounted or wrong path.<\/p>\n<p><strong>Fix:<\/strong> Verify volume in docker-compose.yml:<\/p>\n<div><pre><code>volumes:\n  - .\/whatsapp:\/app\/.wwebjs_auth  # Must match OpenClaw's path\n<\/code><\/pre><\/div>\n<p><strong>Check directory exists:<\/strong><\/p>\n<div><pre><code>ls -la whatsapp\/\n<\/code><\/pre><\/div>\n<p>Should show session files after first QR scan.<\/p>\n<h2 id=\"resource-limits\">Resource Limits<\/h2>\n<p>Prevent OpenClaw from consuming all system resources.<\/p>\n<h3>Add Resource Constraints<\/h3>\n<div><pre><code>services:\n  openclaw:\n    deploy:\n      resources:\n        limits:\n          cpus: '1.0'      # Max 1 CPU core\n          memory: 1024M    # Max 1GB RAM\n        reservations:\n          cpus: '0.5'      # Reserve 0.5 core\n          memory: 512M     # Reserve 512MB\n<\/code><\/pre><\/div>\n<p><strong>Monitor usage:<\/strong><\/p>\n<div><pre><code>docker stats openclaw\n<\/code><\/pre><\/div>\n<p>Shows real-time CPU, memory, network, disk usage.<\/p>\n<h2 id=\"docker-compose-profiles\">Docker Compose Profiles<\/h2>\n<p>Run different configurations without multiple compose files.<\/p>\n<h3>Add Profiles<\/h3>\n<div><pre><code>services:\n  openclaw:\n    profiles: [\"production\"]\n    image: openclaw\/openclaw:latest\n    # ... rest of config\n\n  openclaw-dev:\n    profiles: [\"development\"]\n    image: openclaw\/openclaw:dev\n    volumes:\n      - .\/src:\/app\/src  # Mount source for hot reload\n    environment:\n      - NODE_ENV=development\n<\/code><\/pre><\/div>\n<p><strong>Run production:<\/strong><\/p>\n<div><pre><code>docker-compose --profile production up -d\n<\/code><\/pre><\/div>\n<p><strong>Run development:<\/strong><\/p>\n<div><pre><code>docker-compose --profile development up -d\n<\/code><\/pre><\/div>\n<h2 id=\"the-paioclaw-pre-built-image-alternative\">The PaioClaw Pre-Built Image Alternative<\/h2>\n<p><strong>Setup time so far:<\/strong> 5-10 minutes (Docker install, compose file, first QR scan).<\/p>\n<p><strong>What you&#8217;ve handled:<\/strong><\/p>\n<ul>\n<li>Docker installation<\/li>\n<li>docker-compose.yml creation<\/li>\n<li>.env configuration<\/li>\n<li>Volume mapping for persistence<\/li>\n<li>WhatsApp\/Telegram socket gotcha<\/li>\n<li>First-time authentication<\/li>\n<\/ul>\n<p><strong>Ongoing maintenance:<\/strong><\/p>\n<ul>\n<li>Image updates (pull, restart)<\/li>\n<li>Volume backups<\/li>\n<li>Resource monitoring<\/li>\n<li>Log rotation<\/li>\n<\/ul>\n<p><strong>PaioClaw pre-built image:<\/strong><\/p>\n<p>Docker image included, but fully managed:<\/p>\n<ol>\n<li>Pre-configured docker-compose<\/li>\n<li>Automatic volume setup<\/li>\n<li>One-click messaging auth<\/li>\n<li>Managed updates<\/li>\n<li>Built-in monitoring<\/li>\n<\/ol>\n<p><strong>Total time:<\/strong> 2 minutes (paste API key, scan QR).<\/p>\n<p><strong>Includes:<\/strong><\/p>\n<ul>\n<li>Pre-optimized image (smaller, faster)<\/li>\n<li>Automatic backup to cloud storage<\/li>\n<li>Resource optimization (CPU\/memory tuning)<\/li>\n<li>Health monitoring and auto-restart<\/li>\n<li>Log aggregation<\/li>\n<\/ul>\n<p><strong>Cost:<\/strong> Starts FREE, Smart $15\/month, Genius $25\/month.<\/p>\n<p><strong>When to DIY Docker:<\/strong><\/p>\n<ul>\n<li>You need full container control<\/li>\n<li>Custom image modifications<\/li>\n<li>Multi-instance orchestration<\/li>\n<li>Learning Docker\/containers<\/li>\n<\/ul>\n<p><strong>When to use PaioClaw:<\/strong><\/p>\n<ul>\n<li>You want Docker benefits without Docker expertise<\/li>\n<li>Automatic backups and monitoring<\/li>\n<li>Managed updates<\/li>\n<li>Support when things break<\/li>\n<\/ul>\n<p><strong>The honest truth:<\/strong> Docker setup is straightforward if you know Docker. If docker-compose.yml looks like hieroglyphics, PaioClaw handles the complexity.<\/p>\n<h2 id=\"the-bottom-line\">The Bottom Line<\/h2>\n<p>Docker makes OpenClaw portable, reproducible, and isolated. The setup is genuinely 5 minutes once you understand volume mounts and the WhatsApp\/Telegram socket gotcha.<\/p>\n<p><strong>Critical takeaways:<\/strong><\/p>\n<ul>\n<li>Volume mounts preserve data across restarts<\/li>\n<li>WhatsApp\/Telegram sessions MUST be in volumes<\/li>\n<li>.env file controls all configuration<\/li>\n<li>docker-compose makes management simple<\/li>\n<\/ul>\n<p>If you followed this guide, you now have OpenClaw running in Docker with persistent memory and working messaging integrations.<\/p>\n<p>Whether you manage your own Docker setup or use PaioClaw&#8217;s pre-built image depends on whether you want infrastructure control or infrastructure convenience.<\/p>\n<div><\/div>\n<p><strong>Want Docker without the YAML?<\/strong> PaioClaw&#8217;s managed Docker deployment handles compose files, volume mounts, backups, and monitoring automatically. One-click setup, zero Docker knowledge required. Starts FREE, Smart $15\/month, Genius $25\/month. <a href=\"https:\/\/paioclaw.ai\" target=\"_blank\" rel=\"noopener noreferrer\">Start free \u2192<\/a><\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>PaioClaw gives you a private, always-on AI assistant powered by your own API keys. No Docker, no command line \u2014 sign up and it&#8217;s ready in 60 seconds.<\/p>\n","protected":false},"author":0,"featured_media":188,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-187","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Install OpenClaw with Docker (The 5-Minute Containerized Setup) - PaioClaw<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup) - PaioClaw\" \/>\n<meta property=\"og:description\" content=\"PaioClaw gives you a private, always-on AI assistant powered by your own API keys. No Docker, no command line \u2014 sign up and it&#039;s ready in 60 seconds.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/\" \/>\n<meta property=\"og:site_name\" content=\"PaioClaw\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/paioclaw\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-10T00:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/paioclaw.ai\/blog\/wp-content\/uploads\/2026\/05\/openclaw-docker-setup.png\" \/>\n\t<meta property=\"og:image:width\" content=\"852\" \/>\n\t<meta property=\"og:image:height\" content=\"341\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@PaioClaw\" \/>\n<meta name=\"twitter:site\" content=\"@PaioClaw\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup)\",\"datePublished\":\"2026-05-10T00:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/\"},\"wordCount\":1235,\"publisher\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/openclaw-docker-setup.png\",\"articleSection\":[\"How to\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/\",\"url\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/\",\"name\":\"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup) - PaioClaw\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/openclaw-docker-setup.png\",\"datePublished\":\"2026-05-10T00:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#primaryimage\",\"url\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/openclaw-docker-setup.png\",\"contentUrl\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/openclaw-docker-setup.png\",\"width\":852,\"height\":341},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/openclaw-docker-setup\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/\",\"name\":\"PAIO Blog \u2014 Guides, tips, and updates\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#organization\",\"name\":\"PAIO\",\"url\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/local.paioclawblog.com\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/paioclaw_logo.webp\",\"contentUrl\":\"https:\\\/\\\/local.paioclawblog.com\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/paioclaw_logo.webp\",\"width\":128,\"height\":128,\"caption\":\"PAIO\"},\"image\":{\"@id\":\"https:\\\/\\\/paioclaw.ai\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/paioclaw\\\/\",\"https:\\\/\\\/x.com\\\/PaioClaw\",\"https:\\\/\\\/www.instagram.com\\\/paioclaw\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/paioclaw\",\"https:\\\/\\\/www.youtube.com\\\/@PaioClaw\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup) - PaioClaw","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/","og_locale":"en_US","og_type":"article","og_title":"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup) - PaioClaw","og_description":"PaioClaw gives you a private, always-on AI assistant powered by your own API keys. No Docker, no command line \u2014 sign up and it's ready in 60 seconds.","og_url":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/","og_site_name":"PaioClaw","article_publisher":"https:\/\/www.facebook.com\/paioclaw\/","article_published_time":"2026-05-10T00:00:00+00:00","og_image":[{"width":852,"height":341,"url":"https:\/\/paioclaw.ai\/blog\/wp-content\/uploads\/2026\/05\/openclaw-docker-setup.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_creator":"@PaioClaw","twitter_site":"@PaioClaw","twitter_misc":{"Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#article","isPartOf":{"@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/"},"author":{"name":"","@id":""},"headline":"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup)","datePublished":"2026-05-10T00:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/"},"wordCount":1235,"publisher":{"@id":"https:\/\/paioclaw.ai\/blog\/#organization"},"image":{"@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#primaryimage"},"thumbnailUrl":"https:\/\/paioclaw.ai\/blog\/wp-content\/uploads\/2026\/05\/openclaw-docker-setup.png","articleSection":["How to"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/","url":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/","name":"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup) - PaioClaw","isPartOf":{"@id":"https:\/\/paioclaw.ai\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#primaryimage"},"image":{"@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#primaryimage"},"thumbnailUrl":"https:\/\/paioclaw.ai\/blog\/wp-content\/uploads\/2026\/05\/openclaw-docker-setup.png","datePublished":"2026-05-10T00:00:00+00:00","breadcrumb":{"@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#primaryimage","url":"https:\/\/paioclaw.ai\/blog\/wp-content\/uploads\/2026\/05\/openclaw-docker-setup.png","contentUrl":"https:\/\/paioclaw.ai\/blog\/wp-content\/uploads\/2026\/05\/openclaw-docker-setup.png","width":852,"height":341},{"@type":"BreadcrumbList","@id":"https:\/\/paioclaw.ai\/blog\/openclaw-docker-setup\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/paioclaw.ai\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Install OpenClaw with Docker (The 5-Minute Containerized Setup)"}]},{"@type":"WebSite","@id":"https:\/\/paioclaw.ai\/blog\/#website","url":"https:\/\/paioclaw.ai\/blog\/","name":"PAIO Blog \u2014 Guides, tips, and updates","description":"","publisher":{"@id":"https:\/\/paioclaw.ai\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/paioclaw.ai\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/paioclaw.ai\/blog\/#organization","name":"PAIO","url":"https:\/\/paioclaw.ai\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/paioclaw.ai\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/local.paioclawblog.com\/wp-content\/uploads\/2026\/05\/paioclaw_logo.webp","contentUrl":"https:\/\/local.paioclawblog.com\/wp-content\/uploads\/2026\/05\/paioclaw_logo.webp","width":128,"height":128,"caption":"PAIO"},"image":{"@id":"https:\/\/paioclaw.ai\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/paioclaw\/","https:\/\/x.com\/PaioClaw","https:\/\/www.instagram.com\/paioclaw\/","https:\/\/www.linkedin.com\/company\/paioclaw","https:\/\/www.youtube.com\/@PaioClaw"]}]}},"_links":{"self":[{"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/posts\/187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/comments?post=187"}],"version-history":[{"count":0,"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/posts\/187\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/media\/188"}],"wp:attachment":[{"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/media?parent=187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/categories?post=187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/paioclaw.ai\/blog\/wp-json\/wp\/v2\/tags?post=187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}