Elysiadev11 commited on
Commit
77dc4cf
Β·
verified Β·
1 Parent(s): 066d383

Upload start-openclaw.sh with huggingface_hub

Browse files
Files changed (1) hide show
  1. start-openclaw.sh +52 -151
start-openclaw.sh CHANGED
@@ -1,68 +1,59 @@
1
  #!/bin/bash
2
 
3
  # ─────────────────────────────────────────────────────────────
4
- # start-openclaw.sh β€” OpenClaw + code-server + tmux
5
  # ─────────────────────────────────────────────────────────────
6
 
7
  set +e
8
 
9
- echo "===== OpenClaw + VS Code Startup ====="
10
 
11
- # ── TRAP: Backup saat container mati ─────────────────────────
12
- trap 'echo ">>> [TRAP] Container stopping β€” final backup..."; python3 /app/sync.py backup; echo ">>> [TRAP] Done."' EXIT SIGTERM SIGINT
 
 
 
 
13
 
14
- # ── 1. Direktori ──────────────────────────────────────────────
15
- mkdir -p /root/.openclaw/agents/main/sessions
16
- mkdir -p /root/.openclaw/credentials
17
- mkdir -p /root/.openclaw/sessions
18
- mkdir -p /root/.openclaw/browsers
19
- mkdir -p /home/coder/workspace
20
- mkdir -p /root/.config/code-server
21
- echo ">>> Directories ready."
22
 
23
- # ── 2. Restore backup ─────────────────────────────────────────
24
- python3 /app/sync.py restore
25
- echo ">>> Restore done."
26
 
27
- # ── 3. Fix DNS ────────────────────────────────────────────────
28
  echo "nameserver 1.1.1.1" >> /etc/resolv.conf
29
  echo "nameserver 8.8.8.8" >> /etc/resolv.conf
30
  echo "nameserver 8.8.4.4" >> /etc/resolv.conf
31
  echo ">>> DNS fixed."
32
 
33
- # ── 4. Chromium ──────────────────────────────────────────────
34
- export PLAYWRIGHT_BROWSERS_PATH=/root/.openclaw/browsers
35
- CHROMIUM_PATH=$(find /root/.openclaw/browsers -name "chrome" -type f 2>/dev/null | head -1)
36
 
37
  if [ -z "$CHROMIUM_PATH" ]; then
38
- echo ">>> Installing Chromium..."
39
  OPENCLAW_NM=$(npm root -g 2>/dev/null)/openclaw/node_modules/playwright-core/cli.js
40
- if timeout 180 node "$OPENCLAW_NM" install chromium; then
41
  echo ">>> Chromium OK"
42
  else
43
  echo ">>> WARN: Chromium install failed"
44
  fi
45
- CHROMIUM_PATH=$(find /root/.openclaw/browsers -name "chrome" -type f 2>/dev/null | head -1)
 
46
  else
47
- echo ">>> Chromium found: $CHROMIUM_PATH"
48
  fi
49
 
50
- # ── 5. Bersihkan Variabel ────────────────────────────────────
51
- CLEAN_BASE=$(echo "$OPENAI_API_BASE" \
52
- | sed "s|/chat/completions||g" \
53
- | sed "s|/v1/|/v1|g" \
54
- | sed "s|/v1$|/v1|g")
55
-
56
  ALLOW_ID_SAFE=${TELEGRAM_ALLOW_ID:-0}
57
 
58
- # ── 6. Password untuk code-server & gateway ──────────────────
59
- VSCODE_PASSWORD="${OPENCLAW_GATEWAY_PASSWORD:-openclaw}"
60
- echo ">>> code-server password set from OPENCLAW_GATEWAY_PASSWORD"
61
-
62
- # ── 7. Fungsi Auto-Fix JSON ──────────────────────────────────
63
  generate_safe_json() {
64
- echo ">>> [AUTO-FIX] Menulis ulang openclaw.json ke pengaturan aman..."
65
- cat > /root/.openclaw/openclaw.json <<JSONEOF
66
  {
67
  "models": {
68
  "providers": {
@@ -155,18 +146,20 @@ generate_safe_json() {
155
  JSONEOF
156
  }
157
 
158
- # Cek integritas JSON di awal
159
- echo ">>> Memeriksa integritas file openclaw.json..."
160
- if [ ! -f /root/.openclaw/openclaw.json ] || ! python3 -c 'import json; json.load(open("/root/.openclaw/openclaw.json"))' 2>/dev/null; then
 
161
  generate_safe_json
162
  else
163
- echo ">>> File openclaw.json yang valid ditemukan (Editan AI aman dijaga)."
164
  fi
165
 
166
- # ── 8. Start code-server ─────────────────────────────────────
167
  echo ">>> Starting code-server on port 8443..."
 
 
168
 
169
- # Write code-server config
170
  cat > /root/.config/code-server/config.yaml <<EOF
171
  bind-addr: 0.0.0.0:8443
172
  auth: password
@@ -174,26 +167,23 @@ password: ${VSCODE_PASSWORD}
174
  cert: false
175
  EOF
176
 
177
- # Start code-server in background
178
  code-server --bind-addr 0.0.0.0:8443 \
179
  --auth password \
180
  --disable-telemetry \
181
  --disable-update-check \
182
- /home/coder/workspace &
183
  CODE_SERVER_PID=$!
184
  echo ">>> code-server started (PID: $CODE_SERVER_PID)"
185
 
186
- # ── 9. Node.js reverse proxy (port 7860) ─────────────────────
187
- # /code/* β†’ code-server :8443 (strip /code prefix)
188
- # /tg-webhook β†’ telegram :8787
189
- # /* β†’ openclaw :7862
190
- # ─────────────────────────────────────────────────────────────
191
  node -e "
192
  const http = require('http');
193
  const net = require('net');
194
 
195
- process.on('uncaughtException', err => console.error('Proxy Exception:', err.message));
196
-
197
  function proxyHttp(req, res, targetPort, rewritePath) {
198
  const opts = {
199
  hostname: '127.0.0.1',
@@ -203,10 +193,8 @@ function proxyHttp(req, res, targetPort, rewritePath) {
203
  headers: { ...req.headers, host: req.headers.host },
204
  };
205
  const pr = http.request(opts, (r) => {
206
- // For code-server: rewrite Location headers
207
  const headers = { ...r.headers };
208
  if (targetPort === 8443 && headers.location) {
209
- // If code-server redirects to /, make it /code/
210
  if (headers.location === '/' || headers.location === '') {
211
  headers.location = '/code/';
212
  } else if (!headers.location.startsWith('/code') && headers.location.startsWith('/')) {
@@ -217,12 +205,11 @@ function proxyHttp(req, res, targetPort, rewritePath) {
217
  r.pipe(res, { end: true });
218
  });
219
  pr.on('error', (e) => {
220
- if (targetPort === 8443) {
221
- res.writeHead(200, { 'Content-Type': 'text/html' });
222
- res.end('<html style=\"background:#1e1e2e;color:#cdd6f4;font-family:sans-serif;text-align:center;padding-top:20%\"><body><h2>VS Code is starting up...</h2><p>Please refresh in a few seconds.</p></body></html>');
223
  } else {
224
- res.writeHead(200, { 'Content-Type': 'text/html' });
225
- res.end('<html style=\"background:#1e1e2e;color:#cdd6f4;font-family:sans-serif;text-align:center;padding-top:20%\"><body><h2>OpenClaw is warming up...</h2><p>Please refresh in a few seconds.</p></body></html>');
226
  }
227
  });
228
  req.pipe(pr, { end: true });
@@ -246,7 +233,6 @@ function proxyWs(req, socket, head, targetPort, rewritePath) {
246
 
247
  const server = http.createServer((req, res) => {
248
  if (req.url.startsWith('/code')) {
249
- // Strip /code prefix for code-server
250
  let newPath = req.url.replace(/^\/code\/?/, '/');
251
  if (newPath === '') newPath = '/';
252
  proxyHttp(req, res, 8443, newPath);
@@ -268,99 +254,14 @@ server.on('upgrade', (req, socket, head) => {
268
  });
269
 
270
  server.listen(7860, '0.0.0.0', () => {
271
- console.log('Proxy on port 7860 | /code/* -> 8443 | /tg-webhook -> 8787 | /* -> 7862');
272
  });
273
  " &
274
- echo ">>> Node.js reverse proxy started on port 7860."
275
-
276
- # ── 10. Backup otomatis setiap 1 Jam ─────────────────────────
277
- (
278
- sleep 60
279
- echo ">>> Initial backup (60s after startup)..."
280
- python3 /app/sync.py backup
281
-
282
- while true; do
283
- sleep 3600
284
- echo ">>> Scheduled backup..."
285
- python3 /app/sync.py backup
286
- done
287
- ) &
288
-
289
- # ── 11. Jalankan OpenClaw di tmux session ─────────────────────
290
- # User bisa attach dari VS Code terminal: tmux attach -t openclaw
291
- # ─────────────────────────────────────────────────────────────
292
- RESTART_COUNT=0
293
-
294
- # Create a helper script yang dipanggil di dalam tmux
295
- cat > /app/run-openclaw.sh <<'RUNCLAW'
296
- #!/bin/bash
297
- set +e
298
-
299
- echo ">>> Running openclaw doctor --fix..."
300
- openclaw doctor --fix
301
- DOC_EXIT=$?
302
 
303
- if [ $DOC_EXIT -ne 0 ]; then
304
- echo ">>> [WARNING] Doctor found fatal errors! Config will be regenerated on next restart."
305
- fi
306
-
307
- echo ">>> Starting OpenClaw gateway on port 7862..."
308
- exec openclaw gateway run --port 7862 2>&1 | grep --line-buffered -viE "pairing required|native approval handler|GatewayClientRequestError|security audit: device access upgrade requested"
309
- RUNCLAW
310
- chmod +x /app/run-openclaw.sh
311
-
312
- # Main loop: run OpenClaw in tmux, restart on crash
313
- while true; do
314
- RESTART_COUNT=$((RESTART_COUNT + 1))
315
-
316
- echo ">>> [Loop #$RESTART_COUNT] Running openclaw doctor --fix..."
317
- openclaw doctor --fix
318
- DOC_EXIT=$?
319
-
320
- # Kalau doctor gagal, auto-fix config
321
- if [ $DOC_EXIT -ne 0 ]; then
322
- echo ">>> [WARNING] OpenClaw Doctor menemukan error fatal! Auto-fix..."
323
- generate_safe_json
324
- openclaw doctor --fix
325
- fi
326
-
327
- echo ">>> [Loop #$RESTART_COUNT] Starting OpenClaw gateway in tmux session 'openclaw'..."
328
-
329
- # Kill existing tmux session if any
330
- tmux kill-session -t openclaw 2>/dev/null || true
331
-
332
- # Start OpenClaw inside tmux session
333
- tmux new-session -d -s openclaw -x 200 -y 50 \
334
- "openclaw gateway run --port 7862 2>&1 | grep --line-buffered -viE 'pairing required|native approval handler|GatewayClientRequestError|security audit: device access upgrade requested'; echo '>>> OpenClaw exited. Session will stay open.'; sleep infinity"
335
-
336
- echo ">>> OpenClaw running in tmux session 'openclaw'"
337
- echo ">>> Attach from VS Code terminal: tmux attach -t openclaw"
338
-
339
- # Monitor the tmux session - wait until openclaw process dies
340
- while true; do
341
- sleep 10
342
-
343
- # Check if openclaw gateway process is still running
344
- if ! pgrep -f "openclaw gateway" > /dev/null 2>&1; then
345
- echo ">>> [Loop #$RESTART_COUNT] OpenClaw gateway process died!"
346
- break
347
- fi
348
-
349
- # Also check if tmux session still exists
350
- if ! tmux has-session -t openclaw 2>/dev/null; then
351
- echo ">>> [Loop #$RESTART_COUNT] tmux session 'openclaw' ended!"
352
- break
353
- fi
354
- done
355
-
356
- echo ">>> [Loop #$RESTART_COUNT] Gateway stopped."
357
-
358
- # Auto-fix config on crash
359
- echo ">>> [CRITICAL] Gateway crashed! Restoring safe config..."
360
- generate_safe_json
361
 
362
- echo ">>> Backing up..."
363
- python3 /app/sync.py backup
364
- echo ">>> Restarting gateway in 5 seconds..."
365
- sleep 5
366
- done
 
1
  #!/bin/bash
2
 
3
  # ─────────────────────────────────────────────────────────────
4
+ # start-openclaw.sh β€” VS Code Proxy & OpenClaw Bucket Setup
5
  # ─────────────────────────────────────────────────────────────
6
 
7
  set +e
8
 
9
+ echo "===== VS Code Proxy & Storage Setup ====="
10
 
11
+ # ── 1. Setup Persistent Data Bucket (/data) ──────────────────
12
+ mkdir -p /data/.openclaw/agents/main/sessions
13
+ mkdir -p /data/.openclaw/credentials
14
+ mkdir -p /data/.openclaw/sessions
15
+ mkdir -p /data/.openclaw/browsers
16
+ mkdir -p /data/workspace
17
 
18
+ # Link persistent store ke /root agar terbaca OpenClaw default
19
+ ln -sfn /data/.openclaw /root/.openclaw
20
+
21
+ # Link workspace code-server untuk kemudahan akses
22
+ mkdir -p /home/coder
23
+ ln -sfn /data/workspace /home/coder/workspace
 
 
24
 
25
+ echo ">>> Persistent directories under /data ready."
 
 
26
 
27
+ # ── 2. Fix DNS ────────────────────────────────────────────────
28
  echo "nameserver 1.1.1.1" >> /etc/resolv.conf
29
  echo "nameserver 8.8.8.8" >> /etc/resolv.conf
30
  echo "nameserver 8.8.4.4" >> /etc/resolv.conf
31
  echo ">>> DNS fixed."
32
 
33
+ # ── 3. Chromium Persistent Install ──────────────────────────────
34
+ export PLAYWRIGHT_BROWSERS_PATH=/data/.openclaw/browsers
35
+ CHROMIUM_PATH=$(find /data/.openclaw/browsers -name "chrome" -type f 2>/dev/null | head -1)
36
 
37
  if [ -z "$CHROMIUM_PATH" ]; then
38
+ echo ">>> Installing Chromium to persistent storage /data..."
39
  OPENCLAW_NM=$(npm root -g 2>/dev/null)/openclaw/node_modules/playwright-core/cli.js
40
+ if timeout 300 node "$OPENCLAW_NM" install chromium; then
41
  echo ">>> Chromium OK"
42
  else
43
  echo ">>> WARN: Chromium install failed"
44
  fi
45
+ # Re-check path after install
46
+ CHROMIUM_PATH=$(find /data/.openclaw/browsers -name "chrome" -type f 2>/dev/null | head -1)
47
  else
48
+ echo ">>> Chromium found in persistent storage: $CHROMIUM_PATH"
49
  fi
50
 
51
+ # ── 4. OpenClaw Configuration ──────────────────────────────────
52
+ CLEAN_BASE=$(echo "$OPENAI_API_BASE" | sed "s|/chat/completions||g" | sed "s|/v1/|/v1|g" | sed "s|/v1$|/v1|g")
 
 
 
 
53
  ALLOW_ID_SAFE=${TELEGRAM_ALLOW_ID:-0}
54
 
 
 
 
 
 
55
  generate_safe_json() {
56
+ cat > /data/.openclaw/openclaw.json <<JSONEOF
 
57
  {
58
  "models": {
59
  "providers": {
 
146
  JSONEOF
147
  }
148
 
149
+ # Cek integritas JSON
150
+ echo ">>> Checking /data/.openclaw/openclaw.json..."
151
+ if [ ! -f /data/.openclaw/openclaw.json ] || ! python3 -c 'import json; json.load(open("/data/.openclaw/openclaw.json"))' 2>/dev/null; then
152
+ echo ">>> Generating /data/.openclaw/openclaw.json..."
153
  generate_safe_json
154
  else
155
+ echo ">>> Valid openclaw.json found in /data. Keeping it intact."
156
  fi
157
 
158
+ # ── 5. Start code-server ─────────────────────────────────────
159
  echo ">>> Starting code-server on port 8443..."
160
+ mkdir -p /root/.config/code-server
161
+ VSCODE_PASSWORD="${OPENCLAW_GATEWAY_PASSWORD:-openclaw}"
162
 
 
163
  cat > /root/.config/code-server/config.yaml <<EOF
164
  bind-addr: 0.0.0.0:8443
165
  auth: password
 
167
  cert: false
168
  EOF
169
 
 
170
  code-server --bind-addr 0.0.0.0:8443 \
171
  --auth password \
172
  --disable-telemetry \
173
  --disable-update-check \
174
+ /data/workspace &
175
  CODE_SERVER_PID=$!
176
  echo ">>> code-server started (PID: $CODE_SERVER_PID)"
177
 
178
+ # ── 6. Node.js Reverse Proxy ─────────────────────────────────
179
+ # Routes:
180
+ # /code/* β†’ 8443 (VS Code)
181
+ # /tg-webhook β†’ 8787 (OpenClaw Telegram)
182
+ # /* β†’ 7862 (OpenClaw UI)
183
  node -e "
184
  const http = require('http');
185
  const net = require('net');
186
 
 
 
187
  function proxyHttp(req, res, targetPort, rewritePath) {
188
  const opts = {
189
  hostname: '127.0.0.1',
 
193
  headers: { ...req.headers, host: req.headers.host },
194
  };
195
  const pr = http.request(opts, (r) => {
 
196
  const headers = { ...r.headers };
197
  if (targetPort === 8443 && headers.location) {
 
198
  if (headers.location === '/' || headers.location === '') {
199
  headers.location = '/code/';
200
  } else if (!headers.location.startsWith('/code') && headers.location.startsWith('/')) {
 
205
  r.pipe(res, { end: true });
206
  });
207
  pr.on('error', (e) => {
208
+ res.writeHead(502);
209
+ if (targetPort === 7862) {
210
+ res.end('<h1>OpenClaw Gateway</h1><p>The UI is not reachable. You must start OpenClaw manually via the VS Code terminal (available at /code/).</p>');
211
  } else {
212
+ res.end('502 Bad Gateway');
 
213
  }
214
  });
215
  req.pipe(pr, { end: true });
 
233
 
234
  const server = http.createServer((req, res) => {
235
  if (req.url.startsWith('/code')) {
 
236
  let newPath = req.url.replace(/^\/code\/?/, '/');
237
  if (newPath === '') newPath = '/';
238
  proxyHttp(req, res, 8443, newPath);
 
254
  });
255
 
256
  server.listen(7860, '0.0.0.0', () => {
257
+ console.log('Proxy routing: /code -> VSCode (8443), /tg-webhook -> Telegram (8787), /* -> OpenClaw (7862)');
258
  });
259
  " &
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
 
261
+ echo "============================================="
262
+ echo "READY! Open HF space at \`/code/\` to access VS Code,"
263
+ echo "then start openclaw manually from the terminal."
264
+ echo "============================================="
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
 
266
+ # Keep container running
267
+ sleep infinity