Cloud Testing Guide

April 3, 2026 · View on GitHub

Run ClawMetry on a remote server and access it from anywhere.


Any Linux VM works: DigitalOcean, Hetzner, AWS EC2, GCP Compute Engine, etc.

1. Install

pip install clawmetry

2. Point to your OpenClaw workspace

If OpenClaw runs on the same machine, the dashboard auto-detects everything:

clawmetry --host 0.0.0.0 --port 8900

If your OpenClaw workspace is on a different machine, mount or sync it, then:

clawmetry --host 0.0.0.0 --workspace /path/to/openclaw/agent

3. Secure access

SSH tunnel (simplest):

# From your laptop:
ssh -L 8900:localhost:8900 user@your-server
# Then open http://localhost:8900

Reverse proxy (production):

Use nginx or Caddy with HTTPS and basic auth:

# /etc/nginx/sites-available/dashboard
server {
    listen 443 ssl;
    server_name dashboard.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/dashboard.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dashboard.yourdomain.com/privkey.pem;

    # SSE needs long timeouts
    proxy_read_timeout 600s;
    proxy_buffering off;

    location / {
        auth_basic "Dashboard";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://127.0.0.1:8900;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Or with Caddy (auto-HTTPS):

dashboard.yourdomain.com {
    basicauth * {
        admin \$2a\$14$... # caddy hash-password
    }
    reverse_proxy localhost:8900
}

Option 2: Google Cloud Run (Serverless)

Ideal if your OpenClaw metrics are sent via OTLP. Note: Cloud Run is stateless, so file-based features (logs, transcripts, memory) won't work unless you mount a volume.

1. Create a Dockerfile

FROM python:3.12-slim
RUN pip install clawmetry[otel]
EXPOSE 8900
CMD ["clawmetry", "--host", "0.0.0.0", "--port", "8900", "--no-debug"]

2. Deploy

gcloud run deploy clawmetry \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --port 8900 \
  --memory 512Mi

3. Send OTLP data

Point your OpenClaw config at the Cloud Run URL:

diagnostics:
  otel:
    endpoint: https://clawmetry-xxxxx.run.app

The Usage tab and health checks will work. For full features, use a VM with the workspace mounted.


Option 3: Docker (Anywhere)

docker run -d \
  --name clawmetry \
  -p 8900:8900 \
  -v /path/to/openclaw/agent:/workspace \
  python:3.12-slim \
  bash -c "pip install clawmetry && clawmetry --host 0.0.0.0 --workspace /workspace --no-debug"

For a proper image, create a Dockerfile:

FROM python:3.12-slim
RUN pip install clawmetry[otel]
EXPOSE 8900
ENTRYPOINT ["clawmetry"]
CMD ["--host", "0.0.0.0", "--no-debug"]
docker build -t clawmetry .
docker run -d -p 8900:8900 -v ~/openclaw-agent:/workspace clawmetry --workspace /workspace

Option 4: Railway / Render / Fly.io

These platforms support Docker or Python buildpacks.

Railway:

# railway.json
{
  "build": { "builder": "NIXPACKS" },
  "deploy": {
    "startCommand": "pip install clawmetry[otel] && clawmetry --host 0.0.0.0 --port $PORT --no-debug"
  }
}

Fly.io:

fly launch --image python:3.12-slim
# Then use the Dockerfile approach above

OTLP-Only Mode (Metrics Without Workspace)

If you just want cost/token dashboards without local file access, the dashboard works in "OTLP-only" mode:

clawmetry --host 0.0.0.0 --no-debug
# No workspace needed - just send OTLP data to it

Configure OpenClaw to send metrics:

diagnostics:
  otel:
    endpoint: http://your-dashboard-host:8900

You'll get: Usage tab (tokens, costs, model breakdown), health checks, and the Flow visualization. Tabs that need local files (Logs, Memory, Transcripts) will show empty states gracefully.


Troubleshooting

IssueFix
SSE streams disconnectSet proxy_read_timeout 600s and proxy_buffering off in nginx
Empty tabs on Cloud RunExpected - mount a volume or use OTLP-only mode
Port already in use--port 9000 or OPENCLAW_DASHBOARD_PORT=9000
High memory on long runsMetrics auto-cap at ~10K entries per category. Use --metrics-file to persist across restarts

Local Development Testing

Quick iteration with make test-fast

The fastest way to test before pushing:

# Terminal 1: start the server
make dev

# Terminal 2: run API tests against it
make test-fast

This skips E2E Playwright tests and runs only the API suite — typically completes in a few seconds.

Full local test run

make test        # runs test-api + test-e2e
make test-api    # API tests only
make test-e2e    # E2E browser tests only (requires Playwright)
make lint        # syntax check + ruff warnings

How the CI matrix works

Every PR triggers a 4-job pipeline:

  1. lint — Python syntax check + ruff (runs in ~10s, must pass before anything else)
  2. api-tests — API test suite on a 4-runner matrix:
    • ubuntu-latest × Python 3.9 and 3.11
    • macos-latest × Python 3.11
    • windows-latest × Python 3.11
  3. e2e-tests — Playwright browser tests on Linux only (continue-on-error: true while stabilising)
  4. pip-install — Smoke test that pip install . works and --help runs on all 3 OS platforms

The matrix uses fail-fast: false so a failure on one platform doesn't cancel others — you get the full picture in one CI run.

Platform notes

  • iMessage tests gracefully skip on Linux/Windows (the endpoint returns {"note": "iMessage is only available on macOS"})
  • Windows server startup uses PowerShell (pwsh) with Invoke-WebRequest for health-check polling
  • conftest.py uses sys.executable instead of hardcoded python3 for cross-platform subprocess launch