Download Dockerfile from york/cbot: direct link, hf CLI and curl.
- Browser
- Download file 7.29 kB
-
https://huggingface.co/spaces/york/cbot/resolve/main/Dockerfile
- Command line
-
hf download hf://spaces/york/cbot/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/york/cbot/resolve/main/Dockerfile
7.29 kB
| FROM node:22-slim | |
| # 1. Install system dependencies, python, and browser requirements | |
| RUN apt-get update && apt-get install -y \ | |
| git \ | |
| curl \ | |
| zip \ | |
| unzip \ | |
| tar \ | |
| xz-utils \ | |
| bzip2 \ | |
| python3 \ | |
| python3-pip \ | |
| libglib2.0-0 \ | |
| libnss3 \ | |
| libnspr4 \ | |
| libatk1.0-0 \ | |
| libatk-bridge2.0-0 \ | |
| libcups2 \ | |
| libdrm2 \ | |
| libxkbcommon0 \ | |
| libxcomposite1 \ | |
| libxdamage1 \ | |
| libxrandr2 \ | |
| libgbm1 \ | |
| libgtk-3-0 \ | |
| libasound2 \ | |
| libpango-1.0-0 \ | |
| libcairo2 \ | |
| rsync \ | |
| && npx playwright install-deps chromium \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # 2. Install OpenClaw and browser tools | |
| RUN npm install -g openclaw@latest agent-browser pdfnano | |
| # 3. Install Hugging Face Hub (Python) | |
| RUN pip3 install --no-cache-dir --break-system-packages huggingface_hub | |
| # 4. Install Chromium and link it for OpenClaw | |
| RUN agent-browser install chromium && \ | |
| ln -s $(find /root/.cache/ms-playwright -name chrome -type f | grep -v "shell" | head -n 1) /usr/bin/google-chrome | |
| # 5. Create directory structure | |
| RUN mkdir -p /root/.openclaw/agents/main/agent \ | |
| /root/.openclaw/agents/main/sessions \ | |
| /root/.openclaw/credentials \ | |
| /root/.openclaw/workspace | |
| ENV PORT=7860 | |
| ENV OPENCLAW_GATEWAY_MODE=local | |
| EXPOSE 7860 | |
| # 6. Startup script | |
| RUN cat > /usr/local/bin/start-openclaw << 'EOF' | |
| #!/bin/bash | |
| set -e | |
| OPENCLAW_DIR="/root/.openclaw" | |
| HF_TMP="/tmp/hf-restore" | |
| # DNS | |
| echo "nameserver 1.1.1.1" > /etc/resolv.conf 2>/dev/null || true | |
| echo "nameserver 8.8.8.8" >> /etc/resolv.conf 2>/dev/null || true | |
| # --- RESTORE FROM HF DATASET --- | |
| if [[ -n "$HF_DATASET_TOKEN" && -n "$HF_DATASET" ]]; then | |
| echo "[HF] Restoring dataset: $HF_DATASET" | |
| rm -rf "$HF_TMP" | |
| mkdir -p "$HF_TMP" | |
| python3 << 'EOP' | |
| import os | |
| from huggingface_hub import snapshot_download | |
| snapshot_download( | |
| repo_id=os.environ["HF_DATASET"], | |
| repo_type="dataset", | |
| local_dir="/tmp/hf-restore", | |
| allow_patterns=["data/**"], | |
| token=os.environ["HF_DATASET_TOKEN"] | |
| ) | |
| print("[HF] Download complete") | |
| EOP | |
| # CRITICAL FIX: merge data/* into live OpenClaw dir | |
| if [ -d "$HF_TMP/data" ]; then | |
| rsync -a "$HF_TMP/data/" "$OPENCLAW_DIR/" | |
| echo "[HF] Data merged into OpenClaw workspace" | |
| fi | |
| fi | |
| # --- GENERATE CONFIG ONLY IF MISSING --- | |
| if [ ! -f "$OPENCLAW_DIR/openclaw.json" ]; then | |
| echo "[CFG] Generating initial openclaw.json" | |
| if [ -z "$GEMINI_APIKEY" ]; then | |
| echo "ERROR: GEMINI_APIKEY not set" | |
| exit 1 | |
| fi | |
| cat > "$OPENCLAW_DIR/openclaw.json" << EOC | |
| { | |
| "env": { | |
| "GOOGLE_API_KEY": "${GEMINI_APIKEY}", | |
| "GEMINI_API_KEY": "${GEMINI_APIKEY}", | |
| "GOOGLE_GENERATIVE_AI_API_KEY": "${GEMINI_APIKEY}", | |
| "TELEGRAM_BOT_TOKEN": "${TELEGRAM_BOT_TOKEN}" | |
| }, | |
| "gateway": { | |
| "mode": "local", | |
| "bind": "lan", | |
| "port": 7860, | |
| "trustedProxies": ["0.0.0.0/0"], | |
| "auth": { | |
| "mode": "token", | |
| "token": "${OPENCLAW_GATEWAY_PASSWORD}" | |
| }, | |
| "controlUi": { "allowInsecureAuth": true } | |
| }, | |
| "models": { | |
| "providers": { | |
| "nvidia": { | |
| "baseUrl": "https://integrate.api.nvidia.com/v1", | |
| "apiKey": "${NVIDIA_NIM_API_KEY}", | |
| "api": "openai-completions", | |
| "models": [ | |
| { "id": "deepseek-ai/deepseek-r1-distill-qwen-7b", "name": "Deepseek R1 Distill Qwen 7b", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "deepseek-ai/deepseek-v3.2", "name": "Deepseek v3.2", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "openai/gpt-oss-120b", "name": "GPT OSS 120b", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "openai/gpt-oss-20b", "name": "GPT OSS 20b", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "qwen/qwen2.5-7b-instruct", "name": "Qwen 2.5 7B Instruct", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "qwen/qwen2.5-coder-32b-instruct", "name": "Qwen 2.5 Coder 32B", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "qwen/qwen2.5-coder-7b-instruct", "name": "Qwen 2.5 Coder 7B", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "mistralai/mistral-large-2-instruct", "name": "Mistral Large 2 Instruct", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "databricks/dbrx-instruct", "name": "DBRX Instruct", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "mistralai/mistral-7b-instruct-v0.3", "name": "Mistral 7B Instruct v0.3", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "minimaxai/minimax-m2.1", "name": "MiniMax M2.1", "contextWindow": 200000, "maxTokens": 8192 }, | |
| { "id": "z-ai/glm4.7", "name": "GLM 4.7", "contextWindow": 200000, "maxTokens": 8192 } | |
| ] | |
| } | |
| } | |
| }, | |
| "agents": { | |
| "defaults": { | |
| "model": { | |
| "primary": "google/gemini-3-flash-preview", | |
| "fallbacks": [ | |
| "google/gemini-3-pro-preview", | |
| "google/gemini-2.0-flash", | |
| "google/gemini-2.5-flash", | |
| "google/gemini-2.5-pro", | |
| "google/gemini-3-flash-preview" | |
| ] | |
| }, | |
| "models": { | |
| "google/gemini-3-pro-preview": {}, | |
| "google/gemini-2.0-flash": {}, | |
| "google/gemini-2.5-flash": {}, | |
| "google/gemini-2.5-pro": {}, | |
| "google/gemini-3-flash-preview": {}, | |
| "nvidia/deepseek-ai/deepseek-r1-distill-qwen-7b": {}, | |
| "nvidia/deepseek-ai/deepseek-v3.2": {}, | |
| "nvidia/openai/gpt-oss-120b": {}, | |
| "nvidia/openai/gpt-oss-20b": {}, | |
| "nvidia/qwen/qwen2.5-7b-instruct": {}, | |
| "nvidia/qwen/qwen2.5-coder-32b-instruct": {}, | |
| "nvidia/qwen/qwen2.5-coder-7b-instruct": {}, | |
| "nvidia/mistralai/mistral-large-2-instruct": {}, | |
| "nvidia/mistralai/mistral-7b-instruct-v0.3": {}, | |
| "nvidia/databricks/dbrx-instruct": {}, | |
| "nvidia/minimaxai/minimax-m2.1": {}, | |
| "nvidia/z-ai/glm4.7": {} | |
| }, | |
| "workspace": "/root/.openclaw/workspace", | |
| "compaction": { "mode": "safeguard" }, | |
| "maxConcurrent": 4, | |
| "subagents": { "maxConcurrent": 8 } | |
| } | |
| }, | |
| "commands": { | |
| "native": "auto", | |
| "nativeSkills": "auto", | |
| "restart": true | |
| }, | |
| "plugins": { | |
| "entries": { | |
| "telegram": { | |
| "enabled": true | |
| }, | |
| "whatsapp": { | |
| "enabled": false | |
| }, | |
| "discord": { | |
| "enabled": false | |
| }, | |
| "qwen-portal-auth": { | |
| "enabled": false | |
| } | |
| } | |
| }, | |
| "channels": { | |
| "telegram": { | |
| "enabled": true, | |
| "allowFrom": ["${TELEGRAM_USER}"] | |
| } | |
| } | |
| } | |
| EOC | |
| fi | |
| chmod -R 700 "$OPENCLAW_DIR" | |
| # --- BACKUP LOOP (EVERY 5 MINUTES) --- | |
| if [[ -n "$HF_DATASET_TOKEN" && -n "$HF_DATASET" ]]; then | |
| ( | |
| while true; do | |
| sleep 300 | |
| echo "[HF] Backup running" | |
| python3 << 'EOP' | |
| import os | |
| from huggingface_hub import HfApi | |
| api = HfApi(token=os.environ["HF_DATASET_TOKEN"]) | |
| api.upload_folder( | |
| repo_id=os.environ["HF_DATASET"], | |
| repo_type="dataset", | |
| folder_path="/root/.openclaw", | |
| path_in_repo="data", | |
| ignore_patterns=[ | |
| "openclawd.json", | |
| "agents/**/sessions/**", | |
| "workspace/node_modules/**", | |
| "browser/**", | |
| "workspace/.cache/**", | |
| "*.key", | |
| ".env" | |
| ] | |
| ) | |
| print("[HF] Backup complete") | |
| EOP | |
| done | |
| ) & | |
| fi | |
| exec openclaw gateway run --port 7860 | |
| EOF | |
| RUN chmod +x /usr/local/bin/start-openclaw | |
| CMD ["/usr/local/bin/start-openclaw"] |