File size: 5,424 Bytes
91747fb 0618e14 e485e52 0618e14 21effef e485e52 0618e14 25535d1 0618e14 e485e52 0618e14 21effef e485e52 0618e14 e485e52 61620ed 0618e14 be1f2e0 0618e14 e485e52 0618e14 e485e52 0618e14 e485e52 90a49b0 e485e52 0618e14 e485e52 21effef e485e52 be1f2e0 e485e52 f244765 e485e52 0618e14 e485e52 0618e14 21effef 90a49b0 046131e 90a49b0 be1f2e0 90a49b0 0618e14 046131e 90a49b0 21effef 8228f77 90a49b0 e485e52 90a49b0 046131e 21effef 046131e be1f2e0 046131e be1f2e0 336153d e485e52 0618e14 90a49b0 046131e 90a49b0 21effef 90a49b0 4a7fcd0 be1f2e0 046131e 90a49b0 0618e14 61620ed 0618e14 e485e52 0618e14 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | # 核心镜像: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"] |