File size: 9,480 Bytes
020c337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
---
title: OpenClaw HF Space
emoji: 🦞
colorFrom: blue
colorTo: indigo
sdk: docker
sdk_version: 29.0.4
app_port: 7860
app_file: mian.py
pinned: false
---

# OpenClaw HF Space 部署工具(中文版)

> **Languages:** [English](./README.md) · [简体中文](./README_zh.md)
> **部署指南:** [English](./DEPLOY_GUIDE.md) · [中文部署指南](./DEPLOY_GUIDE_zh.md)

本项目提供在 Hugging Face Space 上部署 OpenClaw 的完整解决方案。

## 功能特性

- 基于 `ubuntu:24.04` 构建 OpenClaw 容器镜像
- 默认通过 BT Panel(宝塔面板)管理服务,端口 `7860`
- OpenClaw Gateway 运行在独立端口 `18789`(默认)
- 默认使用第三方 OpenAI 兼容接口(`base_url + api_key`),通过环境变量注入
- OpenClaw 配置和工作目录存储在 `/root/.openclaw`
- 启动时自动从 Hugging Face Dataset 恢复状态
- 通过 `cron` 定时备份 OpenClaw 数据到 Hugging Face Dataset
- 预装工具:`python3``uv``vim``neovim``chromium`(Chrome for Testing)、`gh``hf``opencode``codex``claude`(Claude Code CLI)、`@larksuite/cli``sshx`
- 内置 DDNS-GO,支持动态 DNS 更新(非关键功能,安装失败不影响构建)

## 项目结构

- `Dockerfile`: Space 运行时镜像
- `scripts/openclaw-entrypoint.sh`: 主启动流程(恢复、配置生成、cron 设置、gateway 启动)
- `scripts/hf-entrypoint.sh`: HF Spaces 容器入口(管理 supervisord + PM2)
- `scripts/supervisord.conf`: Supervisord 配置,管理 cron 和 openclaw-gateway
- `openclaw_hf/backup.py`: 备份/恢复实现
- `scripts/openclaw-backup-cron.sh`: Cron 备份任务入口
- `scripts/openclaw-restore.sh`: 启动恢复入口
- `scripts/openclaw-gateway-restart`: 重启 openclaw-gateway 进程
- `scripts/bt_install_panel.sh`: BT Panel 安装脚本
- `scripts/bootstrap-hf.sh`: 交互式引导脚本(macOS/Linux)
- `scripts/bootstrap-hf.ps1`: 交互式引导脚本(Windows PowerShell)
- `tests/test_backup.py`: 备份模块单元测试
- `tests/test_entrypoint_config.py`: Gateway 配置生成行为单元测试

## 必填变量(Space Settings)

在 Hugging Face Space 的 `Settings -> Variables and secrets` 中配置:

- 变量: `OPENCLAW_BACKUP_DATASET_REPO`: 备份目标 Dataset,格式 `username/dataset-name`
- 密钥: `HF_TOKEN`: 用于向 Dataset 写入备份(必须对该 Dataset 有写权限)
- 密钥: `OPENCLAW_GATEWAY_TOKEN`: Gateway 令牌(建议填写;留空则自动生成 32 位随机值)
- 密钥: `OPENCLAW_GATEWAY_PASSWORD`: Gateway 密码(可选;留空则自动生成 16 位随机值)

使用 `./scripts/bootstrap-hf.sh``./scripts/bootstrap-hf.ps1` 时,这些值会自动配置到目标 Space。

## BT Panel 变量

- `BT_PANEL_PORT`(默认: `7860`): BT Panel 监听端口
- `BT_PANEL_USERNAME`(默认: `btadmin`): BT Panel 用户名,**必须以小写字母开头,只能包含小写字母和数字,长度 3-32 位**
- `BT_PANEL_PASSWORD`: BT Panel 密码,留空则使用默认随机密码

## 可选 LLM 变量(全有或全无)

只有在需要 OpenClaw 预配置自定义第三方模型时才设置这三个:

- 变量: `OPENCLAW_LLM_BASE_URL`: 第三方 base URL(如 OpenAI 兼容的 `/v1`- 变量: `OPENCLAW_LLM_MODEL`: 第三方模型 ID
- 密钥: `OPENCLAW_LLM_API_KEY`: 第三方 API key

三者任一缺失则跳过自定义模型生成,此时仍可在容器内通过 `sshx` 配置 LLM。

## 常用可选变量

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `OPENCLAW_VERSION` | `latest` | OpenClaw 版本,用于 Docker 安装步骤 |
| `OPENCLAW_GATEWAY_PORT` | `18789` | Gateway 监听端口(避免与 BT Panel 的 7860 冲突) |
| `OPENCLAW_GATEWAY_BIND` | `lan` | Gateway 绑定方式(`lan`/`local`) |
| `OPENCLAW_STATE_DIR` | `/root/.openclaw` | OpenClaw 状态目录 |
| `OPENCLAW_USER` | `root` | Gateway 和 cron 任务的运行时用户 |
| `OPENCLAW_GROUP` | `root` | 运行时用户组 |
| `OPENCLAW_CONFIG_PATH` | `/root/.openclaw/openclaw.json` | Gateway 配置文件路径 |
| `OPENCLAW_WORKSPACE_DIR` | `/root/.openclaw/workspace` | 工作目录 |
| `OPENCLAW_BACKUP_CRON` | `*/30 * * * *` | 备份 cron 表达式(默认每 30 分钟) |
| `OPENCLAW_BACKUP_SOURCE_DIR` | `/root/.openclaw` | 备份/恢复基础目录 |
| `OPENCLAW_BACKUP_ROOT_*_DIR` | 各有默认值 | 额外备份目录(config、codex、claude、agents、ssh、npm、lark-cli) |
| `OPENCLAW_BACKUP_PATH_PREFIX` | `backups` | 备份路径前缀 |
| `OPENCLAW_BACKUP_KEEP_COUNT` | `24` | 保留的最新备份数量 |
| `OPENCLAW_SSHX_AUTO_START` | `false` | 设为 `true` 启动时自动后台运行 `sshx` |
| `OPENCLAW_GATEWAY_AUTH_MODE` | `token` | 认证模式(`token`/`password`) |
| `OPENCLAW_GATEWAY_CONTROLUI_ALLOW_INSECURE_AUTH` | `false` | 允许不安全认证 |
| `OPENCLAW_GATEWAY_CONTROLUI_DANGEROUSLY_DISABLE_DEVICE_AUTH` | `false` | 禁用设备配对(**强烈不建议在公网开启**) |

## 快速部署

从仓库根目录运行交互式引导脚本:

```bash
./scripts/bootstrap-hf.sh
```

```powershell
powershell -ExecutionPolicy ByPass -File .\scripts\bootstrap-hf.ps1
```

`bootstrap-hf.sh` / `bootstrap-hf.ps1` 会执行以下操作:

1. 检查/安装 `hf` CLI
2. 解析 HF 认证状态(未登录则提示输入 `HF_TOKEN` 并登录;已登录则询问是否使用当前用户)
3. 询问 `space_name``dataset_name``OPENCLAW_VERSION`、Gateway 令牌/密码及可选 LLM 配置
4. 自动生成 `OPENCLAW_GATEWAY_TOKEN`(32 位)和 `OPENCLAW_GATEWAY_PASSWORD`(16 位)
5. 创建私有 Space + Dataset 并上传仓库
6. 自动配置 Space 的 `Variables and secrets`
7. 显示部署设置并要求确认
8. 输出 Hugging Face Space 页面地址、应用地址和 `/healthz` 健康检查地址

如自动生成了令牌/密码,脚本结束时会自动显示。

## Hugging Face Space 保活策略

Space 保活策略取决于硬件套餐:

- 免费 `cpu-basic`:Space 在不活跃后进入休眠(约 48 小时),无法配置为永久运行
- 付费硬件:Space 默认持续运行。在 `Settings -> Hardware` 中将 `Sleep time` 设为 `Never` 可实现真正的 24/7 可用性
- 付费硬件节能模式:设置自定义 `Sleep time`(如 `3600` 秒),实现自动休眠和自动唤醒

Space URL 构成:

- Space Repo ID 格式: `<owner>/<space_name>`(示例: `username/openclaw-hf`- 公开运行时地址: `https://<owner>-<space_name>.hf.space`
- 健康检查地址: `https://<owner>-<space_name>.hf.space/healthz`

定时健康检查保持活跃:

```bash
*/12 * * * * HF_TOKEN=hf_xxx /path/to/repo/scripts/check-space-health.sh username/openclaw-hf >/dev/null || true
```

注意:
- 私有 Space 的 `https://<owner>-<space_name>.hf.space/healthz` 返回 Hub 404,这是正常的访问控制行为
- 私有 Space 请求需要包含 `Authorization: Bearer <HF_TOKEN>`

## 备份/恢复流程

- **启动恢复**:容器启动时从 Dataset 获取 `latest-backup.json` 来定位最新备份并恢复:
  - `openclaw-state` -> `OPENCLAW_BACKUP_SOURCE_DIR`(默认 `/root/.openclaw`  - `root-config` -> `OPENCLAW_BACKUP_ROOT_CONFIG_DIR`(默认 `/root/.config`  - `root-codex` -> `OPENCLAW_BACKUP_ROOT_CODEX_DIR`(默认 `/root/.codex`  - `root-claude` -> `OPENCLAW_BACKUP_ROOT_CLAUDE_DIR`(默认 `/root/.claude`  - `root-agents` -> `OPENCLAW_BACKUP_ROOT_AGENTS_DIR`(默认 `/root/.agents`  - `root-ssh` -> `OPENCLAW_BACKUP_ROOT_SSH_DIR`(默认 `/root/.ssh`  - `root-env` -> `OPENCLAW_BACKUP_ROOT_ENV_DIR`(默认 `/root/.env.d`  - `root-npm` -> `OPENCLAW_BACKUP_ROOT_NPM_DIR`(默认 `/root/.npm`  - `root-lark-cli` -> `OPENCLAW_BACKUP_ROOT_LARK_CLI_DIR`(默认 `/root/.lark-cli`- **定时备份**:根据 `OPENCLAW_BACKUP_CRON` 执行
- **关机备份**:容器收到停止信号时,执行最后一次备份后再退出
- **保留策略**:上传后只保留最新的 `OPENCLAW_BACKUP_KEEP_COUNT`(默认 24 个)带时间戳的备份归档,自动删除更旧的

## 在容器内使用 sshx

`sshx` 已预装在镜像中。

1. 通过环境变量自动启动:
   ```bash
   OPENCLAW_SSHX_AUTO_START=true
   ```
   启用后入口脚本会在后台启动 `sshx`,输出直接发送到容器 stdout/stderr

2. 在容器内手动启动:
   ```bash
   sshx
   ```

3. 通过 OpenClaw 终端/工具启动:
   ```bash
   nohup sshx >/proc/1/fd/1 2>/proc/1/fd/2 &
   ```

4. 使用完毕后及时关闭:
   ```bash
   pgrep -fa sshx
   pkill -TERM -f '(^|/)sshx($| )'
   ```

## 本地测试

```bash
python3 -m unittest discover -s tests -p 'test_*.py'
```

## CI/CD`main` 分支提交 Pull Request 后,GitHub Actions CI 会自动运行(`.github/workflows/pr-ci.yml`):
- 单元测试:`python3 -m unittest discover -s tests -p 'test_*.py'`
- Docker 镜像构建:`docker build`(通过 Buildx),使用 `OPENCLAW_VERSION=latest`

## 架构说明

容器启动顺序:

```
PID 1 (bt-panel)
└── supervisord
    ├── cron
    └── openclaw-gateway (via openclaw-entrypoint.sh)
        └── node hf-server.js (PID 1 替代)
```

进程管理使用 **Supervisord** 而非 PM2,原因:
- Supervisord 是为"进程管理者"设计的,适合 PID 1 下运行
- 信号传递正确,SIGTERM 能正确传递给子进程
- 相比 PM2 更轻量,职责单一

## License

MIT. See `LICENSE`.