openclaw / Dockerfile
Tea78's picture
Update Dockerfile
091bd36 verified
# OpenClaw on Hugging Face Spaces - 修复版
# 复制此内容到 HF Space 的 Dockerfile 中
FROM node:22-slim
# 1. 基础依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
git openssh-client build-essential python3 python3-pip \
g++ make ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*
# 2. 安装 Hugging Face Hub
RUN pip3 install --no-cache-dir huggingface_hub --break-system-packages
RUN npx skills add https://github.com/CortexReach/memory-lancedb-pro-skill --skill memory-lancedb-pro
# 3. Git 配置
RUN update-ca-certificates && \
git config --global http.sslVerify false && \
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
# 4. 安装 OpenClaw
RUN npm install -g openclaw@latest --unsafe-perm
# 5. 环境变量预设
ENV PORT=7860 \
OPENCLAW_GATEWAY_MODE=local \
HOME=/root \
NODE_ENV=production
# 6. 同步脚本 - 修复多行格式
RUN cat > /usr/local/bin/sync.py << 'SYNC_EOF'
import os, sys, tarfile
from huggingface_hub import HfApi, hf_hub_download
from datetime import datetime, timedelta
api = HfApi()
repo_id = os.getenv("HF_DATASET", "")
token = os.getenv("HF_TOKEN", "")
def restore():
if not repo_id or not token:
print("No HF_DATASET or HF_TOKEN, skipping restore")
return False
try:
files = api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token)
now = datetime.now()
for i in range(5):
day = (now - timedelta(days=i)).strftime("%Y-%m-%d")
name = f"backup_{day}.tar.gz"
if name in files:
path = hf_hub_download(repo_id=repo_id, filename=name, repo_type="dataset", token=token)
with tarfile.open(path, "r:gz") as tar:
tar.extractall(path="/root/.openclaw/")
print(f"Restored from {name}")
return True
print("No backup found")
except Exception as e:
print(f"Restore warning: {e}")
return False
def backup():
if not repo_id or not token:
return
try:
day = datetime.now().strftime("%Y-%m-%d")
name = f"backup_{day}.tar.gz"
with tarfile.open(name, "w:gz") as tar:
if os.path.exists("/root/.openclaw/sessions"):
tar.add("/root/.openclaw/sessions", arcname="sessions")
if os.path.exists("/root/.openclaw/openclaw.json"):
tar.add("/root/.openclaw/openclaw.json", arcname="openclaw.json")
api.upload_file(path_or_fileobj=name, path_in_repo=name, repo_id=repo_id, repo_type="dataset", token=token)
print(f"Backup {name} done")
os.remove(name)
except Exception as e:
print(f"Backup warning: {e}")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "backup":
backup()
else:
restore()
SYNC_EOF
RUN chmod +x /usr/local/bin/sync.py
# 7. 启动脚本 - 修复多行格式
RUN cat > /usr/local/bin/start-openclaw << 'START_EOF'
#!/bin/bash
set -e
mkdir -p /root/.openclaw/sessions
# 尝试恢复数据(可选)
python3 /usr/local/bin/sync.py restore || true
# 准备 API 配置
CLEAN_BASE="${OPENAI_API_BASE:-https://integrate.api.nvidia.com/v1}"
CLEAN_BASE=$(echo "$CLEAN_BASE" | sed 's|/chat/completions||g' | sed 's|/v1/|/v1|g' | sed 's|/v1$|/v1|')
# 生成令牌(如果没设置)
GATEWAY_TOKEN="${OPENCLAW_GATEWAY_TOKEN:-$(openssl rand -hex 16)}"
MODEL_NAME="${MODEL:-moonshotai/kimi-k2.5}"
# 创建 OpenClaw 配置
cat > /root/.openclaw/openclaw.json <<OPENCLAW_CONFIG
{
"models": {
"providers": {
"nvidia": {
"baseUrl": "$CLEAN_BASE",
"apiKey": "$OPENAI_API_KEY",
"api": "openai-completions",
"models": [{
"id": "$MODEL_NAME",
"name": "Kimi K2.5",
"contextWindow": 256000
}]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "nvidia/$MODEL_NAME"
},
"workspace": "~/.openclaw/workspace"
}
},
"gateway": {
"mode": "local",
"bind": "lan",
"port": $PORT,
"trustedProxies": ["0.0.0.0/0", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
"auth": {
"mode": "token",
"token": "11a5ab55f38849f99e3923378d2a3f262b76c006033c1f17"
},
"remote": {
"token": "11a5ab55f38849f99e3923378d2a3f262b76c006033c1f17"
},
"controlUi": {
"allowInsecureAuth": true,
"dangerouslyAllowHostHeaderOriginFallback": true,
"dangerouslyDisableDeviceAuth": true
}
},
"session": {
"store": "/root/.openclaw/sessions/sessions.json"
}
}
OPENCLAW_CONFIG
echo "========================================"
echo "OpenClaw Gateway Starting..."
echo "Model: $MODEL_NAME"
echo "Port: $PORT"
echo "========================================"
# 后台备份循环(每6小时)
(while true; do
sleep 21600
python3 /usr/local/bin/sync.py backup || true
done) &
# 启动网关
openclaw doctor --fix || true
exec openclaw gateway run --port $PORT
START_EOF
RUN chmod +x /usr/local/bin/start-openclaw
EXPOSE 7860
CMD ["/usr/local/bin/start-openclaw"]