Download Dockerfile from ted1990/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 5.42 kB
-
https://huggingface.co/spaces/ted1990/openclaw/resolve/main/Dockerfile
- Command line
-
hf download hf://spaces/ted1990/openclaw/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/ted1990/openclaw/resolve/main/Dockerfile
5.42 kB
| # 核心镜像:Node 22 slim | |
| FROM node:22-slim | |
| RUN apt-get update && apt-get install -y --no-install-recommends tini \ | |
| && rm -rf /var/lib/apt/lists/* | |
| 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/* | |
| RUN pip3 install --no-cache-dir huggingface_hub --break-system-packages | |
| RUN update-ca-certificates | |
| RUN npm install -g openclaw@latest --unsafe-perm | |
| RUN mkdir -p /home/node/.openclaw && chown -R node:node /home/node/.openclaw | |
| ENV PORT=7860 \ | |
| OPENCLAW_GATEWAY_MODE=local \ | |
| HOME=/home/node | |
| # sync.py(备份排除 openclaw.json,防止旧配置污染) | |
| RUN echo 'import os, sys, tarfile\n\ | |
| from huggingface_hub import HfApi, hf_hub_download\n\ | |
| from datetime import datetime, timedelta\n\ | |
| \n\ | |
| api = HfApi()\n\ | |
| repo_id = os.getenv("HF_DATASET")\n\ | |
| token = os.getenv("HF_TOKEN")\n\ | |
| DATA_DIR = os.path.expanduser("~/.openclaw")\n\ | |
| \n\ | |
| def restore():\n\ | |
| try:\n\ | |
| print(f"--- [SYNC] 启动恢复流程, 目标仓库: {repo_id} ---")\n\ | |
| if not repo_id or not token:\n\ | |
| print("--- [SYNC] 跳过恢复: 未配置 HF_DATASET 或 HF_TOKEN ---")\n\ | |
| return False\n\ | |
| files = api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token)\n\ | |
| now = datetime.now()\n\ | |
| for i in range(5):\n\ | |
| day = (now - timedelta(days=i)).strftime("%Y-%m-%d")\n\ | |
| name = f"backup_{day}.tar.gz"\n\ | |
| if name in files:\n\ | |
| print(f"--- [SYNC] 发现备份文件: {name}, 正在下载... ---")\n\ | |
| path = hf_hub_download(repo_id=repo_id, filename=name, repo_type="dataset", token=token)\n\ | |
| with tarfile.open(path, "r:gz") as tar:\n\ | |
| tar.extractall(path=DATA_DIR)\n\ | |
| print(f"--- [SYNC] 恢复成功! 数据已覆盖至 {DATA_DIR} ---")\n\ | |
| return True\n\ | |
| print("--- [SYNC] 未找到最近 5 天的备份包 ---")\n\ | |
| except Exception as e:\n\ | |
| print(f"--- [SYNC] 恢复异常: {e} ---")\n\ | |
| \n\ | |
| def backup():\n\ | |
| try:\n\ | |
| targets = ["sessions", "workspace", "agents", "memory"]\n\ | |
| existing = [t for t in targets if os.path.exists(os.path.join(DATA_DIR, t))]\n\ | |
| if not existing:\n\ | |
| print("--- [SYNC] 没有需要备份的数据,跳过备份 ---")\n\ | |
| return\n\ | |
| day = datetime.now().strftime("%Y-%m-%d")\n\ | |
| name = f"backup_{day}.tar.gz"\n\ | |
| print(f"--- [SYNC] 正在执行全量备份: {name} ---")\n\ | |
| with tarfile.open(name, "w:gz") as tar:\n\ | |
| for target in existing:\n\ | |
| tar.add(os.path.join(DATA_DIR, target), arcname=target)\n\ | |
| api.upload_file(path_or_fileobj=name, path_in_repo=name, repo_id=repo_id, repo_type="dataset", token=token)\n\ | |
| print(f"--- [SYNC] 备份上传成功! ---")\n\ | |
| os.remove(name)\n\ | |
| except Exception as e:\n\ | |
| print(f"--- [SYNC] 备份失败: {e} ---")\n\ | |
| \n\ | |
| if __name__ == "__main__":\n\ | |
| if len(sys.argv) > 1 and sys.argv[1] == "backup":\n\ | |
| backup()\n\ | |
| else:\n\ | |
| restore()\n\ | |
| ' > /usr/local/bin/sync.py | |
| # 入口脚本 | |
| RUN printf '#!/bin/bash\nset -e\n\n\ | |
| : "${OPENAI_API_BASE:?OPENAI_API_BASE not set}"\n\ | |
| : "${OPENAI_API_KEY:?OPENAI_API_KEY not set}"\n\ | |
| : "${MODEL:?MODEL not set}"\n\ | |
| : "${OPENCLAW_GATEWAY_PASSWORD:?OPENCLAW_GATEWAY_PASSWORD not set}"\n\n\ | |
| DATA_DIR="$HOME/.openclaw"\n\ | |
| mkdir -p "$DATA_DIR"/{sessions,workspace,agents/main/sessions}\n\n\ | |
| python3 /usr/local/bin/sync.py restore\n\n\ | |
| # 恢复后强制覆写 openclaw.json,防止旧配置污染\n\ | |
| cat > "$DATA_DIR/openclaw.json" <<JSON\n\ | |
| {\n\ | |
| "models": {\n\ | |
| "providers": {\n\ | |
| "openai-compat": {\n\ | |
| "baseUrl": "$OPENAI_API_BASE",\n\ | |
| "apiKey": "$OPENAI_API_KEY",\n\ | |
| "api": "openai-completions",\n\ | |
| "models": [{ "id": "$MODEL", "name": "Model", "contextWindow": 128000 }]\n\ | |
| }\n\ | |
| }\n\ | |
| },\n\ | |
| "agents": { "defaults": { "model": { "primary": "openai-compat/$MODEL" } } },\n\ | |
| "gateway": {\n\ | |
| "mode": "local",\n\ | |
| "bind": "lan",\n\ | |
| "port": $PORT,\n\ | |
| "trustedProxies": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],\n\ | |
| "auth": { "mode": "token", "token": "$OPENCLAW_GATEWAY_PASSWORD" },\n\ | |
| "controlUi": {\n\ | |
| "allowInsecureAuth": true,\n\ | |
| "dangerouslyDisableDeviceAuth": true,\n\ | |
| "allowedOrigins": ["https://ted1990-openclaw.hf.space"]\n\ | |
| }\n\ | |
| }\n\ | |
| }\n\ | |
| JSON\n\n\ | |
| chmod 700 "$DATA_DIR"\n\ | |
| chmod 600 "$DATA_DIR/openclaw.json"\n\n\ | |
| echo ""\n\ | |
| echo "--- [CONFIG] openclaw.json 已生成 ---"\n\ | |
| echo "--- [CONFIG] API Base: $OPENAI_API_BASE ---"\n\ | |
| echo "--- [CONFIG] Model: $MODEL ---"\n\ | |
| echo ""\n\n\ | |
| (while true; do sleep 10800; python3 /usr/local/bin/sync.py backup; done) &\n\n\ | |
| (\n\ | |
| sleep 8\n\ | |
| echo ""\n\ | |
| echo "================================================="\n\ | |
| echo "✅ OpenClaw 已就绪!请使用以下完整 URL 访问:"\n\ | |
| echo "🔗 https://ted1990-openclaw.hf.space/#token=${OPENCLAW_GATEWAY_PASSWORD}"\n\ | |
| echo "================================================="\n\ | |
| ) &\n\n\ | |
| exec openclaw gateway run --port $PORT\n' > /usr/local/bin/start-openclaw && chmod +x /usr/local/bin/start-openclaw | |
| USER node | |
| EXPOSE 7860 | |
| ENTRYPOINT ["/usr/bin/tini", "--"] | |
| CMD ["/usr/local/bin/start-openclaw"] |