openclaw / start.sh
arfandi7322's picture
Enable two-way root data sync
88c5bc9
#!/usr/bin/env bash
set -euo pipefail
export PROXY_PORT="${PROXY_PORT:-7860}"
export OPENCLAW_PORT="${OPENCLAW_PORT:-8080}"
export PORT="${OPENCLAW_PORT}"
export HOST="0.0.0.0"
export OPENCLAW_HOST="0.0.0.0"
export OPENCLAW_PORT
export SYNC_INTERVAL="${SYNC_INTERVAL:-300}"
export PLAYWRIGHT_BROWSERS_PATH="${PLAYWRIGHT_BROWSERS_PATH:-/ms-playwright}"
export TELEGRAM_API_ROOT="${TELEGRAM_API_ROOT:-https://tg-relay.markdevil11.workers.dev}"
export OPENCLAW_TELEGRAM_API_ROOT="${OPENCLAW_TELEGRAM_API_ROOT:-${TELEGRAM_API_ROOT}}"
configure_dns() {
if [ -w /etc/resolv.conf ]; then
cat > /etc/resolv.conf <<'EOF'
nameserver 1.1.1.1
nameserver 1.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
options timeout:2 attempts:3 rotate
EOF
echo "DNS configured with Cloudflare and Google resolvers."
else
echo "WARN: /etc/resolv.conf is not writable; keeping existing DNS."
fi
}
mkdir -p /root/workspace
configure_dns
/app/sync-root-data.sh restore
mkdir -p /root/.openclaw
generate_openclaw_config() {
local clean_base
clean_base="$(printf '%s' "${OPENAI_API_BASE:-}" | sed 's|/chat/completions||g' | sed 's|/v1/|/v1|g' | sed 's|/v1$|/v1|g')"
local allow_id
allow_id="${TELEGRAM_ALLOW_ID:-0}"
cat > /root/.openclaw/openclaw.json <<JSONEOF
{
"models": {
"providers": {
"kilo_gateway": {
"baseUrl": "https://api.kilo.ai/api/gateway",
"apiKey": "anonymous",
"api": "openai-completions",
"models": [
{ "id": "kilo-auto/free", "name": "Kilo Auto Free", "contextWindow": 128000, "maxTokens": 16000 }
]
},
"nvidia": {
"baseUrl": "${clean_base}",
"apiKey": "${OPENAI_API_KEY:-}",
"api": "openai-completions",
"models": [
{ "id": "${MODEL:-gpt-5.5}", "name": "${MODEL:-gpt-5.5}", "contextWindow": 128000 },
{ "id": "${VISION_MODEL:-${MODEL:-gpt-5.5}}", "name": "Nvidia Vision", "contextWindow": 128000, "input": ["text", "image"] }
]
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "nvidia/${MODEL:-gpt-5.5}",
"fallbacks": ["kilo_gateway/kilo-auto/free"]
},
"imageModel": {
"primary": "nvidia/${VISION_MODEL:-${MODEL:-gpt-5.5}}"
}
}
},
"commands": { "restart": true },
"browser": {
"enabled": true,
"headless": true,
"noSandbox": true,
"defaultProfile": "openclaw",
"ssrfPolicy": { "dangerouslyAllowPrivateNetwork": true },
"profiles": {
"openclaw": {
"cdpPort": 18800,
"color": "0088FF"
}
}
},
"channels": {
"telegram": {
"enabled": true,
"botToken": "${TELEGRAM_BOT_TOKEN:-}",
"dmPolicy": "allowlist",
"allowFrom": [${allow_id}],
"apiRoot": "${TELEGRAM_API_ROOT}",
"webhookUrl": "https://elysiadev11-openclaw.hf.space/tg-webhook",
"webhookSecret": "${OPENCLAW_GATEWAY_PASSWORD:-}",
"webhookPath": "/tg-webhook",
"webhookHost": "0.0.0.0",
"webhookPort": 8787,
"streaming": {
"mode": "partial"
}
}
},
"gateway": {
"mode": "local",
"bind": "lan",
"port": ${OPENCLAW_PORT},
"trustedProxies": ["0.0.0.0/0"],
"auth": { "mode": "token", "token": "${OPENCLAW_GATEWAY_PASSWORD:-}" },
"http": {
"endpoints": {
"chatCompletions": { "enabled": true }
}
},
"controlUi": {
"enabled": true,
"allowInsecureAuth": true,
"dangerouslyDisableDeviceAuth": true,
"dangerouslyAllowHostHeaderOriginFallback": true
}
}
}
JSONEOF
}
config_is_complete() {
python3 - <<'PY'
import json
from pathlib import Path
path = Path('/root/.openclaw/openclaw.json')
if not path.exists():
raise SystemExit(1)
try:
data = json.loads(path.read_text())
except Exception:
raise SystemExit(1)
required_paths = [
('models', 'providers'),
('models', 'providers', 'kilo_gateway'),
('models', 'providers', 'nvidia'),
('agents', 'defaults'),
('browser',),
('gateway',),
('gateway', 'controlUi'),
('channels', 'telegram'),
]
for parts in required_paths:
cur = data
for part in parts:
if not isinstance(cur, dict) or part not in cur:
raise SystemExit(1)
cur = cur[part]
raise SystemExit(0)
PY
}
if ! config_is_complete; then
echo "Generating full /root/.openclaw/openclaw.json before OpenClaw startup..."
generate_openclaw_config
else
echo "Complete /root/.openclaw/openclaw.json found; keeping it."
fi
python3 - <<'PY'
import json
import os
from pathlib import Path
path = Path('/root/.openclaw/openclaw.json')
api_root = os.environ.get('TELEGRAM_API_ROOT', 'https://tg-relay.markdevil11.workers.dev')
if not path.exists():
raise SystemExit(0)
try:
data = json.loads(path.read_text())
except Exception as exc:
print(f'WARN: cannot update Telegram apiRoot in openclaw.json: {exc}')
raise SystemExit(0)
channels = data.setdefault('channels', {})
telegram = channels.setdefault('telegram', {})
old = telegram.get('apiRoot')
browser = data.get('browser')
if isinstance(browser, dict):
browser.pop('requirePairing', None)
agents = data.get('agents')
defaults = agents.get('defaults') if isinstance(agents, dict) else None
if isinstance(defaults, dict):
defaults.pop('llm', None)
if old != api_root:
telegram['apiRoot'] = api_root
print(f'Updated Telegram apiRoot: {old!r} -> {api_root!r}')
else:
print(f'Telegram apiRoot already set to {api_root}')
path.write_text(json.dumps(data, indent=2) + '\n')
PY
/app/sync-root-data.sh reconcile
/app/sync-root-data.sh loop &
run_openclaw() {
while true; do
echo "Starting OpenClaw on 127.0.0.1:${OPENCLAW_PORT}..."
if [ -n "${OPENCLAW_CMD:-}" ]; then
sh -lc "$OPENCLAW_CMD"
else
openclaw gateway --port "${OPENCLAW_PORT}" --allow-unconfigured
fi
echo "OpenClaw exited; restarting in 2 seconds..."
sleep 2
done
}
run_nginx() {
while true; do
envsubst '${PROXY_PORT} ${OPENCLAW_PORT}' < /app/nginx.conf.template > /tmp/nginx.conf
nginx -c /tmp/nginx.conf -g 'daemon off;'
echo "Nginx exited; restarting in 2 seconds..."
sleep 2
done
}
run_openclaw &
run_nginx &
wait -n
exit 1