# 核心镜像选择 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 \ && rm -rf /var/lib/apt/lists/* # 2. 安装 HF 数据交互工具 RUN pip3 install --no-cache-dir huggingface_hub --break-system-packages # 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. 安装飞书频道插件(预装) RUN npm install -g @openclaw/feishu --unsafe-perm # 6. 环境变量预设 ENV PORT=7860 \ OPENCLAW_GATEWAY_MODE=local \ HOME=/root # 7. Python 同步引擎 (sync.py) - 增强版(json配置+压缩数据,直接覆盖配置) RUN echo 'import os, sys, tarfile\n\ from huggingface_hub import HfApi, hf_hub_download\n\ from datetime import datetime, timedelta\n\ import json\n\ import shutil\n\ \n\ api = HfApi()\n\ repo_id = os.getenv("HF_DATASET")\n\ token = os.getenv("HF_TOKEN")\n\ OPENCLAW_DIR = "/root/.openclaw"\n\ \n\ BACKUP_FILES = [\n\ "agents",\n\ "credentials",\n\ "openclaw.json",\n\ "workspace/IDENTITY.md",\n\ "workspace/USER.md",\n\ "workspace/SOUL.md",\n\ "workspace/AGENTS.md",\n\ "workspace/TOOLS.md",\n\ "workspace/MEMORY.md",\n\ "workspace/skills",\n\ ]\n\ \n\ def restore():\n\ try:\n\ files = api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token)\n\ now = datetime.now()\n\ restored = False\n\ for i in range(5):\n\ day = (now - timedelta(days=i)).strftime("%Y-%m-%d")\n\ config_name = f"backup_{day}_config.json"\n\ data_name = f"backup_{day}_data.tar.gz"\n\ \n\ # 1. 恢复数据包(如果存在)\n\ if data_name in files:\n\ data_path = hf_hub_download(repo_id=repo_id, filename=data_name, repo_type="dataset", token=token)\n\ with tarfile.open(data_path, "r:gz") as tar:\n\ tar.extractall(path=OPENCLAW_DIR)\n\ print(f"Restored data from {data_name}")\n\ restored = True\n\ \n\ # 2. 恢复配置文件(如果存在),直接覆盖现有配置\n\ if config_name in files:\n\ config_path = hf_hub_download(repo_id=repo_id, filename=config_name, repo_type="dataset", token=token)\n\ target_config_path = os.path.join(OPENCLAW_DIR, "openclaw.json")\n\ # 确保目标目录存在\n\ os.makedirs(os.path.dirname(target_config_path), exist_ok=True)\n\ shutil.copy2(config_path, target_config_path)\n\ print(f"Restored config from {config_name} (overwritten)")\n\ restored = True\n\ \n\ if restored:\n\ print("Restore completed.")\n\ return True\n\ \n\ print("No backup found in last 5 days")\n\ return False\n\ except Exception as e:\n\ print(f"Restore Error: {e}")\n\ return False\n\ \n\ def backup():\n\ try:\n\ day = datetime.now().strftime("%Y-%m-%d")\n\ config_name = f"backup_{day}_config.json"\n\ data_name = f"backup_{day}_data.tar.gz"\n\ \n\ # 1. 备份配置文件(直接上传 JSON,不压缩)\n\ config_path = os.path.join(OPENCLAW_DIR, "openclaw.json")\n\ if os.path.exists(config_path):\n\ with open(config_path, "rb") as f:\n\ api.upload_file(\n\ path_or_fileobj=f,\n\ path_in_repo=config_name,\n\ repo_id=repo_id,\n\ repo_type="dataset",\n\ token=token\n\ )\n\ print(f"Config backup {config_name} uploaded.")\n\ \n\ # 2. 备份其他文件(打包为 tar.gz)\n\ with tarfile.open(data_name, "w:gz") as tar:\n\ for f in BACKUP_FILES:\n\ if f == "openclaw.json":\n\ continue # 已单独处理\n\ path = os.path.join(OPENCLAW_DIR, f)\n\ if os.path.exists(path):\n\ tar.add(path, arcname=f)\n\ print(f"Backed up: {f}")\n\ if os.path.exists(data_name):\n\ api.upload_file(\n\ path_or_fileobj=data_name,\n\ path_in_repo=data_name,\n\ repo_id=repo_id,\n\ repo_type="dataset",\n\ token=token\n\ )\n\ print(f"Data backup {data_name} uploaded.")\n\ \n\ print(f"Backup {day} completed.")\n\ except Exception as e:\n\ print(f"Backup Error: {e}")\n\ \n\ if __name__ == "__main__":\n\ if len(sys.argv) > 1 and sys.argv[1] == "backup": backup()\n\ else: restore()' > /usr/local/bin/sync.py #RK|# 8. 启动控制逻辑 RUN cat > /usr/local/bin/start-openclaw << 'SCRIPT' #!/bin/bash set -e mkdir -p /root/.openclaw/sessions # 阶段 1: 清理可能存在的重复插件(使用全局 npm 安装的版本) rm -rf /root/.openclaw/extensions/feishu # 阶段 2: 执行启动前恢复(会清理旧的 feishu 配置) python3 /usr/local/bin/sync.py restore # 处理地址逻辑 CLEAN_BASE=$(echo "$OPENAI_API_BASE" | sed "s|/chat/completions||g" | sed "s|/v1/|/v1|g" | sed "s|/v1$|/v1|g") # 阶段 3: 仅当配置文件不存在时才生成默认配置 if [ ! -f /root/.openclaw/openclaw.json ]; then echo "No existing openclaw.json found, generating default configuration..." cat > /root/.openclaw/openclaw.json <