cbot / Dockerfile
amangs's picture
Update Dockerfile
ce99dce verified
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/*
ARG TELEGRAM_BOT_APIBASE
ENV TELEGRAM_BOT_APIBASE=${TELEGRAM_BOT_APIBASE}
# 2. Install OpenClaw and browser tools
RUN npm install -g openclaw@latest agent-browser pdfnano @google/gemini-cli
# Force patch Telegram API URL using environment variable
RUN echo "TELEGRAM_BOT_APIBASE=$TELEGRAM_BOT_APIBASE"
RUN find /usr/local/lib/node_modules/openclaw -type f -name "*.js" -exec sed -i "s|api.telegram.org|${TELEGRAM_BOT_APIBASE}|g" {} +
# 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": {
"port": 7860,
"mode": "local",
"bind": "lan",
"controlUi": {
"allowedOrigins": [
"http://localhost:7860",
"http://127.0.0.1:7860",
"https://amangs-cbot.hf.space"
],
"allowInsecureAuth": true,
"dangerouslyDisableDeviceAuth": true
},
"auth": {
"mode": "token"
}
},
"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 1800
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"]