Skip to content

The "Persistent Sandbox" Architecture

Goal: Provide friends/family with a robust, persistent OpenClaw environment on a VPS (via Coolify) that feels like a full Linux VM but runs safely in a Docker container.

Core Concept

Use Docker volumes to persist package managers (brew, uv, npm) so user installations survive container updates/restarts. No inbound ports required.

Key Components

  1. Package Managers (Persisted):

    • Homebrew (Linuxbrew): System tools (ffmpeg, jq, gh).
    • uv (Astral): Python environment, virtualenvs, and toolchain.
    • npm (Global): Node.js CLI tools (cdk, vercel, firebase-tools).
  2. Volumes Strategy:

    • workspace: User code/projects.
    • data: Agent memory/config.
    • brew: /home/linuxbrew/.linuxbrew (The "System Binaries").
    • npm: /root/.npm-global (Global node modules).
    • uv: /root/.uv_cache (Python build cache).
  3. Networking:

    • Outbound Only: Connects to Relay Network via WebSocket.
    • No Inbound Ports: Safe behind firewall. No subdomain/SSL config needed.
    • Web Previews: User handles via cloudflared or ngrok (installed via brew).

Implementation (Docker Compose)

Paste this into Coolify for each user (e.g., agent-henry).

yaml
services:
  agent-henry:
    image: ghcr.io/openclaw/openclaw:latest
    user: root
    restart: unless-stopped
    environment:
      - OPENCLAW_GATEWAY_TOKEN=henry-secret-token
      # PATH: Prioritize persisted user binaries
      - PATH=/root/.npm-global/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      # CONFIG: Tell tools where to persist
      - NPM_CONFIG_PREFIX=/root/.npm-global
      - UV_CACHE_DIR=/root/.uv_cache
    volumes:
      # --- DATA (The "Hard Drive") ---
      - henry_workspace:/root/.openclaw/workspace  # Code
      - henry_data:/root/.openclaw                 # Agent Brain
      
      # --- TOOLS (The "App Store") ---
      - henry_brew:/home/linuxbrew/.linuxbrew      # Brew (ffmpeg, etc)
      - henry_npm:/root/.npm-global                # NPM Global (cdk, etc)
      - henry_uv:/root/.uv_cache                   # UV Cache (python speed)

    # Startup Script: Fix permissions & ensure uv is installed
    command: >
      /bin/bash -c "
      mkdir -p /root/.npm-global/bin &&
      chown -R root:root /home/linuxbrew /root/.npm-global &&
      if ! command -v uv &> /dev/null; then curl -LsSf https://astral.sh/uv/install.sh | sh; fi &&
      openclaw gateway start --host"

volumes:
  henry_workspace:
  henry_data:
  henry_brew:
  henry_npm:
  henry_uv:

Released under the MIT License.