File size: 5,044 Bytes
4a36dc5
 
 
95f8d64
0bebd3a
4a36dc5
7e66266
 
4a36dc5
7e66266
fc0eb94
4a36dc5
7e66266
0bebd3a
4a36dc5
7e66266
 
 
 
4a36dc5
7e66266
 
 
 
 
4a36dc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7e66266
4a36dc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e70eee
4a36dc5
 
 
74558ee
 
4a36dc5
 
74558ee
4a36dc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7e66266
fc0eb94
 
4a36dc5
 
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# 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

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