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"]