Monday, April 06, 2026

Clawbert

This is my scratch pad for setting up and managing openclaw on my synology NAS using docker.


compose.yaml

services:
  openclaw-gateway:
#   image: ghcr.io/openclaw/openclaw:latest
    build: .
    container_name: openclaw-gateway
    hostname: clawbert-brain
    mac_address: 02:42:ac:12:34:56
    user: "1000:1000"
    environment:
      - TZ=America/Chicago
      - HOME=/home/node
      - OPENCLAW__GATEWAY__MODE=local
      - OPENCLAW_BROWSER_WS_ENDPOINT=ws://browserless:3000/?token=XXXX
      - HA_URL=http://10.0.0.114:8123
      - HA_TOKEN=XXXX
      - OPENCLAW_MAX_ITERATIONS=30
      - OPENCLAW_TOKEN=XXXX
    volumes:
      - /volume1/docker/openclaw/config:/home/node/.openclaw
      - /volume1/docker/openclaw/workspace:/home/node/.openclaw/workspace
      - /volume1/docker/openclaw/gog:/usr/local/bin/gog:ro
      - ./clawbert_config/machine-id:/etc/machine-id:ro
      - ./clawbert_config:/home/node/.config
      - ./gogcli_config:/home/node/.config/gogcli
    ports:
      - "18789:18789"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    networks:
      - openclaw-net
    command: ["node", "dist/index.js", "gateway", "--bind", "lan", "--allow-unconfigured"]
    restart: unless-stopped
    depends_on:
      - browserless

  openclaw-cli:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-cli
    user: "1000:1000"
    restart: "no"
    entrypoint: ["node", "dist/index.js"]
    volumes:
      - /volume1/docker/openclaw/config:/home/node/.openclaw
      - /volume1/docker/openclaw/workspace:/home/node/.openclaw/workspace

  browserless:
    image: ghcr.io/browserless/chromium:latest
    container_name: openclaw-browser
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      # Optional: Protect your browser so random internet scanners can't use it
      - TOKEN=XXXX
      - CONNECTION_TIMEOUT=6000000
      - MAX_CONCURRENT_SESSIONS=10
      - MAX_QUEUE_LENGTH=5
      - DEFAULT_BLOCK_ADS=true
      - HOST=browserless
    # CRITICAL: Chrome crashes without this shared memory setting
    shm_size: "2gb"
    networks:
      - openclaw-net
    cap_add:
      - SYS_ADMIN
    security_opt:
      - seccomp:unconfined

networks:
  openclaw-net:
    driver: bridge

Dockerfile V1.0

# 1. Start with the official OpenClaw image
FROM ghcr.io/openclaw/openclaw:latest

# 2. Switch to root to install system-level tools
USER root

# 3. Install Playwright OS dependencies AND the Google Cloud SDK
RUN apt-get update && apt-get install -y \
    libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 \
    libcups2 libdrm2 libxkbcommon0 libxcomposite1 \
    libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 \
    apt-transport-https ca-certificates gnupg curl \
    && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg \
    && echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
    && apt-get update \
    && apt-get install -y google-cloud-cli \
    && rm -rf /var/lib/apt/lists/*

# 4. Permanently install the official Google Workspace CLI
RUN npm install -g @googleworkspace/cli

RUN chown -R node:node /home/node

# 5. Drop back down to the secure node user for normal operation
USER node

Dockerfile V2.0

# --- STAGE 1: Build the Go binary using the latest compiler ---
FROM golang:latest AS builder
RUN go install github.com/steipete/gifgrep/cmd/gifgrep@latest

# --- STAGE 2: Build the OpenClaw image ---
# 1. Start with the official OpenClaw image
FROM ghcr.io/openclaw/openclaw:latest

# 2. Switch to root to install system-level tools
USER root

# 3. Add PIP global override (Debian 12+ protection bypass)
ENV PIP_BREAK_SYSTEM_PACKAGES=1

# 4. Install OS dependencies, Google SDK, GitHub CLI, and Core Tools
RUN apt-get update && apt-get install -y \
    libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 \
    libcups2 libdrm2 libxkbcommon0 libxcomposite1 \
    libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 \
    apt-transport-https ca-certificates gnupg curl \
    python3 python3-pip python3-venv \
    git golang jq wget unzip build-essential ripgrep \
    && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg \
    && echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
    && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
    && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
    && apt-get update \
    && apt-get install -y google-cloud-cli gh \
    && rm -rf /var/lib/apt/lists/*

# 5. Bake in Qwen's Python Wishlist
RUN pip3 install uv

# 6. The Global Graph: Feed the entire IT-approved and Stretch AI list to uv
# uv will resolve the entire dependency graph instantly before downloading a single file.
RUN uv pip install --system --break-system-packages --no-cache \
    setuptools \
    requests \
    beautifulsoup4 \
    aiofiles \
    "pydantic>=2.0" \
    python-docx \
    playwright \
    yfinance \
    markitdown \
    polars \
    duckdb \
    chromadb \
    agentlightning \
    browser-use \
    faster-whisper

# 7. Copy the compiled gifgrep binary from STAGE 1
COPY --from=builder /go/bin/gifgrep /usr/local/bin/gifgrep

# Install Rust globally for all users
ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path && \
    chmod -R a+w $RUSTUP_HOME $CARGO_HOME

# 8. Permanently install the official Google Workspace CLI
RUN npm install -g @googleworkspace/cli typescript ts-node

# 9. BAKE IN THE MEMORY ENGINE: Download Nomic to a safe directory
RUN mkdir -p /models && \
    wget https://huggingface.co/nomic-ai/nomic-embed-text-v1.5-GGUF/resolve/main/nomic-embed-text-v1.5.Q8_0.gguf -O /models/nomic-embed.gguf && \
    chown -R node:node /models

# 10. Fix permissions so the node user owns everything in their home directory
RUN chown -R node:node /home/node

# 11. Drop back down to the secure node user for normal operation
USER node

Updates

docker compose -p clawbert down
docker compose -p clawbert up -d --build --pull always
docker-compose run --rm openclaw-cli doctor --fix