File size: 5,612 Bytes
35e3473
 
01e197e
35e3473
 
89fb578
856c871
 
 
01e197e
89fb578
35e3473
 
01e197e
35e3473
 
01e197e
35e3473
 
 
 
eb76166
35e3473
856c871
 
35e3473
01e197e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35e3473
 
 
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
FROM node:22-slim

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    git openssh-client build-essential python3 python3-pip \
    g++ make ca-certificates curl chromium tzdata \
    libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
    libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
    libgbm1 libasound2 libpangocairo-1.0-0 libpango-1.0-0 \
    && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    && rm -rf /var/lib/apt/lists/*

# Install Python packages
RUN pip3 install --no-cache-dir huggingface_hub --break-system-packages

# Git and CA config
RUN update-ca-certificates && \
    git config --global http.sslVerify false && \
    git config --global url."https://github.com/".insteadOf ssh://git@github.com/

ENV HOME=/root
ENV PORT=7860 \
    OPENCLAW_GATEWAY_MODE=local \
    OPENCLAW_BROWSER_PATH=/usr/bin/chromium

# Install OpenClaw
RUN npm install -g openclaw@latest zod --unsafe-perm

# Generate sync.py using a Heredoc to avoid syntax/escaping issues
RUN cat <<'EOF' > /usr/local/bin/sync.py
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():
    try:
        print(f"--- [SYNC] Start recovery process, target repository: {repo_id} ---")
        if repo_id and token:
            files = api.list_repo_files(repo_id=repo_id, repo_type="dataset", token=token)
            now = datetime.now()
            found = False
            for i in range(5):
                day = (now - timedelta(days=i)).strftime("%Y-%m-%d")
                name = f"backup_{day}.tar.gz"
                if name in files:
                    print(f"--- [SYNC] Backup file found: {name}, Downloading... ---")
                    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"--- [SYNC] Recovery successful! ---")
                    found = True
                    break
            if not found:
                print("--- [SYNC] No backup packages found for the last 5 days---")
        else:
            print("--- [SYNC] Skip recovery: HF_DATASET or HF_TOKEN not configured ---")

        # Clean up .lock files
        count = 0
        for root, dirs, fs in os.walk("/root/.openclaw/"):
            for f in fs:
                if f.endswith(".lock"):
                    try:
                        os.remove(os.path.join(root, f))
                        count += 1
                    except: pass
        if count > 0:
            print(f"--- [SYNC] {count} residual lock files cleaned up---")
        return True
    except Exception as e:
        print(f"--- [SYNC] Recovery Exception: {e} ---")

def backup():
    try:
        day = datetime.now().strftime("%Y-%m-%d")
        name = f"backup_{day}.tar.gz"
        print(f"--- [SYNC] Performing a full backup: {name} ---")
        def lock_filter(tarinfo):
            if tarinfo.name.endswith(".lock"): return None
            return tarinfo
        with tarfile.open(name, "w:gz") as tar:
            for target in ["sessions", "workspace", "agents", "memory", "plugins", "openclaw.json"]:
                full_path = f"/root/.openclaw/{target}"
                if os.path.exists(full_path):
                    tar.add(full_path, arcname=target, filter=lock_filter)
        if repo_id and token:
            api.upload_file(path_or_fileobj=name, path_in_repo=name, repo_id=repo_id, repo_type="dataset", token=token)
            print("--- [SYNC] Backup upload successful! ---")
    except Exception as e:
        print(f"--- [SYNC] Backup failed: {e} ---")

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "backup":
        backup()
    else:
        restore()
EOF

# Create startup script
RUN cat <<'EOF' > /usr/local/bin/start-openclaw
#!/bin/bash
set -e
mkdir -p /root/.openclaw/{sessions,workspace,plugins,agents/main/sessions,credentials}
ln -s /root/.openclaw/workspace /root/.openclaw/memory || true
chmod 700 /root/.openclaw || true

python3 /usr/local/bin/sync.py restore || true

export OPENCLAW_GATEWAY_TOKEN="${OPENCLAW_GATEWAY_PASSWORD}"
CLEAN_BASE=$(echo "${OPENAI_API_BASE}" | sed "s|/chat/completions||g" | sed "s|/v1/|/v1|g" | sed "s|/v1$|/v1|g")

cat > /root/.openclaw/openclaw.json <<EOC
{
  "models": {
    "mode": "merge",
    "providers": {
      "zai": {
        "baseUrl": "${CLEAN_BASE}",
        "apiKey": "${OPENAI_API_KEY}",
        "api": "openai-completions",
        "models": [
          {"id": "glm-4.7", "name": "GLM-4.7 Coding", "contextWindow": 200000, "maxTokens": 8192},
          {"id": "glm-5", "name": "GLM-5", "contextWindow": 200000, "maxTokens": 8192}
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "model": {"primary": "zai/glm-4.7"},
      "workspace": "~/.openclaw/workspace"
    }
  },
  "gateway": {
    "mode": "local", "bind": "lan", "port": ${PORT},
    "trustedProxies": ["0.0.0.0/0"],
    "auth": { "mode": "token", "token": "${OPENCLAW_GATEWAY_PASSWORD}" },
    "controlUi": { "allowInsecureAuth": true }
  }
}
EOC

(while true; do sleep 10800; python3 /usr/local/bin/sync.py backup || true; done) &

openclaw doctor --fix || true
exec openclaw gateway run --port ${PORT}
EOF

RUN chmod +x /usr/local/bin/start-openclaw

EXPOSE 7860
CMD ["/usr/local/bin/start-openclaw"]