# ClawLama — TODO.AI.md ## Phase 1: Core Container (MVP) ### 1.1 Dockerfile - [ ] Create multi-stage Dockerfile with `debian:bookworm-slim` base - [ ] Stage 1 (builder): Install Node.js LTS via NodeSource `node_lts.x` apt repo with GPG key - [ ] Stage 1 (builder): Download latest Ollama binary from GitHub releases (`/releases/latest/download/ollama-linux-${TARGETARCH}`) - [ ] Stage 1 (builder): Install OpenClaw via `npm install -g openclaw@latest` - [ ] Stage 2 (runtime): Install Node.js LTS runtime (same repo method) - [ ] Stage 2 (runtime): Install `tini`, `procps`, `gettext-base`, `curl` - [ ] Stage 2 (runtime): Copy Ollama binary from builder - [ ] Stage 2 (runtime): Copy OpenClaw global npm install from builder - [ ] Stage 2 (runtime): Copy `rootfs/` overlay - [ ] Stage 2 (runtime): Create `clawlama` user/group, `/data/ollama`, `/data/workspace` dirs - [ ] Stage 2 (runtime): `chmod -R a-w /etc` for hard `/etc` write protection - [ ] Stage 2 (runtime): Set ENV defaults (all `CLAWLAMA_*` and `OLLAMA_*` vars) - [ ] Stage 2 (runtime): `VOLUME ["/data"]`, `EXPOSE 18789` - [ ] Stage 2 (runtime): `HEALTHCHECK` pointing to `/usr/local/bin/healthcheck.sh` - [ ] Stage 2 (runtime): `ENTRYPOINT ["tini", "--"]` + `CMD ["/usr/local/bin/entrypoint.sh"]` - [ ] Verify no `curl | sh` or `curl | bash` anywhere in Dockerfile ### 1.2 OpenClaw Config Template - [ ] Create `rootfs/etc/clawlama/openclaw.template.json` with `envsubst` placeholders - [ ] Include `models.providers.ollama` block with `baseUrl`, `apiKey: "ollama-local"`, `api: "openai-completions"` - [ ] Include model entry with `${CLAWLAMA_MODEL}`, `${CLAWLAMA_CONTEXT_WINDOW}`, `${CLAWLAMA_MAX_TOKENS}` - [ ] Include `agents.defaults` with `workspace: "/data/workspace"`, concurrency settings - [ ] Include `tools` block: `profile: "full"`, `exec.security: "full"`, `exec.ask: "off"`, `elevated.enabled: false` - [ ] Include `exec.applyPatch.workspaceOnly: true`, `fs.workspaceOnly: false` ### 1.3 TOOLS.md - [ ] Create `rootfs/etc/clawlama/TOOLS.md` with git restrictions (no commit, push, reset --hard) - [ ] Include filesystem restriction note (no writes to `/etc`) ### 1.4 Entrypoint Script - [ ] Create `rootfs/usr/local/bin/entrypoint.sh` (POSIX shell, `#!/bin/sh`) - [ ] Detect architecture (`uname -m` → amd64/arm64) - [ ] Detect CPU cores (`nproc` or `/proc/cpuinfo`) and available RAM - [ ] Set `OLLAMA_NUM_THREADS` if not already set (physical cores) - [ ] Detect SIMD capabilities (AVX/AVX2/AVX-512 on amd64, NEON on arm64) and log them - [ ] GPU detection: probe `nvidia-smi`, log GPU model + VRAM if found, log CPU-only if not - [ ] Print startup banner (arch, cores, RAM, GPU status, model, ports) - [ ] Generate `openclaw.json` from template via `envsubst` → `/data/workspace/.openclaw/openclaw.json` - [ ] Copy `TOOLS.md` to `/data/workspace/TOOLS.md` (only if not already present — don't overwrite user edits) - [ ] Handle multi-model support: parse `CLAWLAMA_MODELS` comma-separated list, generate multiple model entries - [ ] Handle Telegram integration: if `CLAWLAMA_TELEGRAM_BOT_TOKEN` set, inject channel config - [ ] Start Ollama in background: `ollama serve &`, capture PID - [ ] Wait for Ollama health: poll `curl -sf http://localhost:11434/` with retry loop (max ~60s) - [ ] Pull model if not cached: `ollama pull ${CLAWLAMA_MODEL}` - [ ] Start OpenClaw gateway in foreground: `openclaw gateway --port ${CLAWLAMA_OPENCLAW_PORT}` - [ ] Trap SIGTERM/SIGINT: forward to Ollama PID, wait for clean shutdown - [ ] Monitor Ollama background process: if it exits unexpectedly, exit entrypoint (trigger Docker restart) ### 1.5 Health Check Script - [ ] Create `rootfs/usr/local/bin/healthcheck.sh` - [ ] Check Ollama: `curl -sf http://localhost:11434/` or exit 1 - [ ] Check OpenClaw: `curl -sf http://localhost:${CLAWLAMA_OPENCLAW_PORT}/` or exit 1 - [ ] Both pass → exit 0 --- ## Phase 2: Build & Compose ### 2.1 Build Script - [ ] Create `scripts/build.sh` - [ ] Set up `docker buildx` builder (create if not exists) - [ ] Build + push multi-arch manifest: `docker buildx build --platform linux/amd64,linux/arm64 --push -t docker.io/casjaysdevdocker/clawlama:latest .` - [ ] Add optional `--load` mode for local testing (single arch) - [ ] Add build timestamp label ### 2.2 docker-compose.yml - [ ] Create `docker-compose.yml` with service definition - [ ] Volume mount: `clawlama-data:/data` - [ ] Port mapping: `18789:18789` - [ ] Restart policy: `unless-stopped` - [ ] Environment variables with defaults via `.env` file reference - [ ] GPU variant: commented-out `deploy.resources.reservations.devices` for NVIDIA ### 2.3 Environment Template - [ ] Create `.env.example` with all `CLAWLAMA_*` and `OLLAMA_*` vars with defaults and comments --- ## Phase 3: Utility Scripts ### 3.1 Backup Script - [ ] Create `scripts/backup.sh` - [ ] Tar `/data` volume contents to timestamped archive - [ ] Support custom output path argument - [ ] Print backup size and location ### 3.2 Restore Script - [ ] Create `scripts/restore.sh` - [ ] Restore from tar archive to `/data` volume - [ ] Validate archive before extracting - [ ] Warn if container is running --- ## Phase 4: Documentation ### 4.1 README.md - [ ] Project description and purpose - [ ] Quick start (CPU-only, GPU, custom model examples) - [ ] Environment variable reference table - [ ] Quantized model recommendations by RAM tier (8 GB / 16 GB / 32+ GB) - [ ] GPU setup guide (NVIDIA Container Toolkit prerequisite) - [ ] Multi-model configuration examples - [ ] Telegram integration setup - [ ] Volume and data persistence explanation - [ ] Backup/restore usage - [ ] Troubleshooting section (common issues, logs, health checks) - [ ] Security notes (don't expose gateway publicly, prompt injection surface) - [ ] Portainer/Dockge usage note - [ ] Override config via bind mount --- ## Phase 5: Validation ### 5.1 Success Criteria Verification - [ ] `docker pull` succeeds on amd64 - [ ] `docker pull` succeeds on arm64 - [ ] `docker run` brings up both services with zero manual intervention - [ ] Model auto-pulled on first run (CPU) - [ ] OpenClaw responds within 120s of container start - [ ] `CLAWLAMA_MODEL` change + restart pulls new model - [ ] Data persists across `docker stop && docker start` - [ ] Runs on x86_64 Linux VM - [ ] Runs on Apple Silicon Mac (Docker Desktop) - [ ] Runs on Raspberry Pi 5 (arm64) - [ ] `--gpus all` on NVIDIA host → GPU detected in logs - [ ] Without `--gpus` → CPU-only, no GPU errors in logs - [ ] Image size < 500 MB compressed (excluding models) ### 5.2 Edge Cases - [ ] First run with no pre-existing `/data` volume - [ ] Container restart with existing model cache (should skip pull) - [ ] Invalid `CLAWLAMA_MODEL` value → clear error message - [ ] Ollama crash during runtime → container exits, restart policy recovers - [ ] SIGTERM during model pull → clean shutdown - [ ] Low memory host (4 GB) with 7B model → functional but slow