forked from openclaw/openclaw
-
Notifications
You must be signed in to change notification settings - Fork 378
Expand file tree
/
Copy pathdocker-deploy-prebuilt.sh
More file actions
executable file
·275 lines (233 loc) · 8.69 KB
/
Copy pathdocker-deploy-prebuilt.sh
File metadata and controls
executable file
·275 lines (233 loc) · 8.69 KB
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#!/usr/bin/env bash
# Openclaw 中文版 Docker 一键部署脚本(使用预构建镜像)
# 用法: ./docker-deploy-prebuilt.sh [docker-image-name]
# 示例: ./docker-deploy-prebuilt.sh jiulingyun803/openclaw-cn:latest
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 自动检测 docker-compose 文件(支持 .yml 和 .yaml)
detect_compose_file() {
local dir="$1"
if [[ -f "$dir/docker-compose.yml" ]]; then
echo "$dir/docker-compose.yml"
elif [[ -f "$dir/docker-compose.yaml" ]]; then
echo "$dir/docker-compose.yaml"
else
echo "$dir/docker-compose.yml" # 默认值,如果都不存在则用 .yml
fi
}
COMPOSE_FILE="$(detect_compose_file "$ROOT_DIR")"
# 为额外的 compose 配置文件选择合适的扩展名(与主文件保持一致)
COMPOSE_EXT="${COMPOSE_FILE##*.}" # 获取主文件的扩展名
EXTRA_COMPOSE_FILE="$ROOT_DIR/docker-compose.extra.$COMPOSE_EXT"
# 默认使用官方预构建镜像,但可通过参数覆盖
IMAGE_NAME="${1:-${OPENCLAW_IMAGE:-jiulingyun803/openclaw-cn:latest}}"
EXTRA_MOUNTS="${OPENCLAW_EXTRA_MOUNTS:-}"
HOME_VOLUME_NAME="${OPENCLAW_HOME_VOLUME:-}"
require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "❌ 缺少依赖: $1" >&2
exit 1
fi
}
print_header() {
echo ""
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ Openclaw 中文版 Docker 部署脚本 (预构建镜像) ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo ""
}
print_step() {
local step_num=$1
local step_name=$2
echo "📍 步骤 $step_num: $step_name"
}
print_success() {
echo "✅ $1"
}
print_error() {
echo "❌ $1" >&2
}
require_cmd docker
if ! docker compose version >/dev/null 2>&1; then
print_error "Docker Compose 不可用(请尝试: docker compose version)"
exit 1
fi
print_header
print_step 1 "检查 Docker 环境"
docker --version
docker compose version
print_success "Docker 环境检查完成"
print_step 2 "创建配置和工作区目录"
OPENCLAW_CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}"
OPENCLAW_WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$HOME/clawd}"
mkdir -p "$OPENCLAW_CONFIG_DIR"
mkdir -p "$OPENCLAW_WORKSPACE_DIR"
# 确保目录权限正确
# 如果以 root 运行(在容器或具有 sudo 的系统上),设置权限以允许 node 用户访问
if [[ $EUID -eq 0 ]]; then
chmod 755 "$OPENCLAW_CONFIG_DIR"
chmod 755 "$OPENCLAW_WORKSPACE_DIR"
# 尝试改变所有权为 1000:1000(Docker node 用户的标准 UID/GID)
# 这在大多数 Linux 系统上有效,但在 macOS 上会被忽略
chown -R 1000:1000 "$OPENCLAW_CONFIG_DIR" 2>/dev/null || true
chown -R 1000:1000 "$OPENCLAW_WORKSPACE_DIR" 2>/dev/null || true
fi
print_success "目录已创建"
export OPENCLAW_CONFIG_DIR
export OPENCLAW_WORKSPACE_DIR
export OPENCLAW_GATEWAY_PORT="${OPENCLAW_GATEWAY_PORT:-18789}"
export OPENCLAW_BRIDGE_PORT="${OPENCLAW_BRIDGE_PORT:-18790}"
export OPENCLAW_GATEWAY_BIND="${OPENCLAW_GATEWAY_BIND:-lan}"
export OPENCLAW_IMAGE="$IMAGE_NAME"
export OPENCLAW_DOCKER_APT_PACKAGES="${OPENCLAW_DOCKER_APT_PACKAGES:-}"
# 生成网关令牌
if [[ -z "${OPENCLAW_GATEWAY_TOKEN:-}" ]]; then
print_step 3 "生成网关令牌"
if command -v openssl >/dev/null 2>&1; then
OPENCLAW_GATEWAY_TOKEN="$(openssl rand -hex 32)"
else
OPENCLAW_GATEWAY_TOKEN="$(python3 - <<'PY'
import secrets
print(secrets.token_hex(32))
PY
)"
fi
fi
export OPENCLAW_GATEWAY_TOKEN
COMPOSE_FILES=("$COMPOSE_FILE")
COMPOSE_ARGS=()
# 生成额外的 compose 配置文件(用于挂载和卷)
write_extra_compose() {
local home_volume="$1"
shift
local -a mounts=("$@")
local mount
cat >"$EXTRA_COMPOSE_FILE" <<'YAML'
services:
openclaw-cn-gateway:
volumes:
YAML
if [[ -n "$home_volume" ]]; then
printf ' - %s:/home/node\n' "$home_volume" >>"$EXTRA_COMPOSE_FILE"
printf ' - %s:/home/node/.openclaw\n' "$OPENCLAW_CONFIG_DIR" >>"$EXTRA_COMPOSE_FILE"
printf ' - %s:/home/node/clawd\n' "$OPENCLAW_WORKSPACE_DIR" >>"$EXTRA_COMPOSE_FILE"
fi
for mount in "${mounts[@]}"; do
printf ' - %s\n' "$mount" >>"$EXTRA_COMPOSE_FILE"
done
cat >>"$EXTRA_COMPOSE_FILE" <<'YAML'
openclaw-cn-cli:
volumes:
YAML
if [[ -n "$home_volume" ]]; then
printf ' - %s:/home/node\n' "$home_volume" >>"$EXTRA_COMPOSE_FILE"
printf ' - %s:/home/node/.openclaw\n' "$OPENCLAW_CONFIG_DIR" >>"$EXTRA_COMPOSE_FILE"
printf ' - %s:/home/node/clawd\n' "$OPENCLAW_WORKSPACE_DIR" >>"$EXTRA_COMPOSE_FILE"
fi
for mount in "${mounts[@]}"; do
printf ' - %s\n' "$mount" >>"$EXTRA_COMPOSE_FILE"
done
if [[ -n "$home_volume" && "$home_volume" != *"/"* ]]; then
cat >>"$EXTRA_COMPOSE_FILE" <<YAML
volumes:
${home_volume}:
YAML
fi
}
# 解析额外的挂载
IFS_OLD="$IFS"
IFS=',' read -ra EXTRA_MOUNTS_ARRAY <<<"${EXTRA_MOUNTS:-}"
IFS="$IFS_OLD"
if [[ -n "$HOME_VOLUME_NAME" || ${#EXTRA_MOUNTS_ARRAY[@]} -gt 0 ]]; then
write_extra_compose "$HOME_VOLUME_NAME" "${EXTRA_MOUNTS_ARRAY[@]}"
COMPOSE_FILES+=("$EXTRA_COMPOSE_FILE")
fi
# 构建 docker compose 命令参数
for f in "${COMPOSE_FILES[@]}"; do
COMPOSE_ARGS+=("-f" "$f")
done
# 构建环境变量文件
print_step 4 "准备环境配置"
ENV_FILE="$ROOT_DIR/.env"
cat >"$ENV_FILE" <<EOF
# Openclaw 中文版 Docker 环境配置
# 生成于: $(date)
OPENCLAW_CONFIG_DIR=$OPENCLAW_CONFIG_DIR
OPENCLAW_WORKSPACE_DIR=$OPENCLAW_WORKSPACE_DIR
OPENCLAW_GATEWAY_PORT=$OPENCLAW_GATEWAY_PORT
OPENCLAW_BRIDGE_PORT=$OPENCLAW_BRIDGE_PORT
OPENCLAW_GATEWAY_BIND=$OPENCLAW_GATEWAY_BIND
OPENCLAW_IMAGE=$OPENCLAW_IMAGE
OPENCLAW_GATEWAY_TOKEN=$OPENCLAW_GATEWAY_TOKEN
OPENCLAW_DOCKER_APT_PACKAGES=$OPENCLAW_DOCKER_APT_PACKAGES
EOF
print_success "环境配置已保存到 .env"
# 拉取预构建镜像
print_step 5 "拉取预构建 Docker 镜像"
echo "📥 镜像: $IMAGE_NAME"
if docker pull "$IMAGE_NAME" 2>&1; then
print_success "镜像拉取成功"
else
print_error "镜像拉取失败"
echo ""
echo "可能的原因:"
echo " 1. 网络连接问题 - 检查你的网络"
echo " 2. 镜像不存在 - 检查镜像名称是否正确(推荐使用 jiulingyun803/openclaw-cn:latest)"
echo " 3. 权限问题 - 如果是私有镜像,需要 'docker login'"
echo ""
exit 1
fi
# 运行 onboard 向导
print_step 6 "运行配置向导(可选)"
echo "提示: 如果已配置过,可以跳过此步"
read -p "是否运行配置向导? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "🚀 启动配置向导..."
docker compose "${COMPOSE_ARGS[@]}" run --rm openclaw-cn-cli onboard
print_success "配置向导完成"
else
echo "⏭️ 跳过配置向导"
fi
# 启动网关
print_step 7 "启动网关服务"
echo "🚀 启动 Docker Compose 服务..."
docker compose "${COMPOSE_ARGS[@]}" up -d openclaw-cn-gateway
# 等待网关启动
echo "⏳ 等待网关启动(约 5 秒)..."
sleep 5
# 验证网关
print_step 8 "验证网关状态"
if docker compose "${COMPOSE_ARGS[@]}" ps openclaw-cn-gateway | grep -q "Up"; then
print_success "网关已启动"
else
print_error "网关启动失败"
echo "📋 查看日志:"
docker compose "${COMPOSE_ARGS[@]}" logs openclaw-cn-gateway
exit 1
fi
# 显示完成信息
echo ""
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ ✅ 部署完成! ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo ""
echo "📋 配置信息:"
echo " 配置目录: $OPENCLAW_CONFIG_DIR"
echo " 工作目录: $OPENCLAW_WORKSPACE_DIR"
echo " 镜像名称: $OPENCLAW_IMAGE"
echo " 网关地址: http://127.0.0.1:$OPENCLAW_GATEWAY_PORT"
echo " 网关令牌: $OPENCLAW_GATEWAY_TOKEN"
echo ""
echo "🌐 后续步骤:"
echo " 1. 在浏览器中打开: http://127.0.0.1:$OPENCLAW_GATEWAY_PORT"
echo " 2. 在设置中粘贴网关令牌"
echo " 3. 配置 AI 提供商和消息渠道"
echo ""
echo "📝 常用命令:"
echo " 查看日志: docker compose -f $COMPOSE_FILE logs -f openclaw-cn-gateway"
echo " 停止服务: docker compose -f $COMPOSE_FILE down"
echo " 重启服务: docker compose -f $COMPOSE_FILE restart openclaw-cn-gateway"
echo ""
echo "📚 更多信息: https://clawd.org.cn"
echo ""