openclaw/scripts/vps-setup.sh

242 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Clawdbot VPS Setup Script
# For Hetzner or any Debian/Ubuntu VPS
#
# Usage: curl -fsSL https://raw.githubusercontent.com/.../vps-setup.sh | bash
# or: bash vps-setup.sh
#
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[+]${NC} $1"; }
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
error() { echo -e "${RED}[x]${NC} $1"; exit 1; }
# Check root
[[ $EUID -eq 0 ]] || error "Run as root: sudo bash $0"
# Detect OS
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS=$ID
else
error "Cannot detect OS"
fi
log "Detected OS: $OS"
#───────────────────────────────────────────────────────────────────────────────
# 1. System packages
#───────────────────────────────────────────────────────────────────────────────
log "Installing system dependencies..."
if [[ "$OS" == "ubuntu" || "$OS" == "debian" ]]; then
apt-get update -qq
apt-get install -y -qq curl wget git build-essential
elif [[ "$OS" == "fedora" || "$OS" == "centos" || "$OS" == "rhel" ]]; then
dnf install -y curl wget git gcc gcc-c++ make
else
warn "Unknown OS, assuming packages are installed"
fi
#───────────────────────────────────────────────────────────────────────────────
# 2. Node.js (via NodeSource)
#───────────────────────────────────────────────────────────────────────────────
if ! command -v node &>/dev/null || [[ $(node -v | cut -d. -f1 | tr -d 'v') -lt 22 ]]; then
log "Installing Node.js 22..."
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs
else
log "Node.js $(node -v) already installed"
fi
# Parse arguments
TAILSCALE_AUTH_KEY=""
while [[ $# -gt 0 ]]; do
case $1 in
--tailscale-key)
TAILSCALE_AUTH_KEY="$2"
shift 2
;;
*)
shift
;;
esac
done
#───────────────────────────────────────────────────────────────────────────────
# 3. Tailscale
#───────────────────────────────────────────────────────────────────────────────
if ! command -v tailscale &>/dev/null; then
log "Installing Tailscale..."
curl -fsSL https://tailscale.com/install.sh | sh
else
log "Tailscale already installed"
fi
# Authenticate Tailscale if key provided
if [[ -n "$TAILSCALE_AUTH_KEY" ]]; then
log "Authenticating Tailscale..."
tailscale up --authkey="$TAILSCALE_AUTH_KEY" --ssh --reset
elif ! tailscale status &>/dev/null; then
warn "Tailscale not connected. Run: tailscale up --ssh"
warn "Get auth key from: https://login.tailscale.com/admin/settings/keys"
fi
#───────────────────────────────────────────────────────────────────────────────
# 4. Create clawdbot user
#───────────────────────────────────────────────────────────────────────────────
CLAWDBOT_USER="clawdbot"
CLAWDBOT_HOME="/home/$CLAWDBOT_USER"
if ! id "$CLAWDBOT_USER" &>/dev/null; then
log "Creating user: $CLAWDBOT_USER"
useradd -m -s /bin/bash "$CLAWDBOT_USER"
else
log "User $CLAWDBOT_USER already exists"
fi
#───────────────────────────────────────────────────────────────────────────────
# 5. Install Clawdbot
#───────────────────────────────────────────────────────────────────────────────
log "Installing Clawdbot..."
npm install -g clawdbot@latest
# Verify installation
CLAWDBOT_VERSION=$(clawdbot --version 2>/dev/null || echo "unknown")
log "Clawdbot version: $CLAWDBOT_VERSION"
#───────────────────────────────────────────────────────────────────────────────
# 6. Create directories
#───────────────────────────────────────────────────────────────────────────────
log "Creating directories..."
mkdir -p "$CLAWDBOT_HOME/.clawdbot"
mkdir -p "$CLAWDBOT_HOME/clawd"
chown -R "$CLAWDBOT_USER:$CLAWDBOT_USER" "$CLAWDBOT_HOME/.clawdbot"
chown -R "$CLAWDBOT_USER:$CLAWDBOT_USER" "$CLAWDBOT_HOME/clawd"
#───────────────────────────────────────────────────────────────────────────────
# 7. Create systemd service
#───────────────────────────────────────────────────────────────────────────────
log "Creating systemd service..."
cat > /etc/systemd/system/clawdbot-gateway.service << 'EOF'
[Unit]
Description=Clawdbot Gateway
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=clawdbot
Group=clawdbot
WorkingDirectory=/home/clawdbot/clawd
ExecStart=/usr/bin/clawdbot gateway run --bind loopback --port 18789
Restart=always
RestartSec=10
# Environment
Environment=NODE_ENV=production
Environment=HOME=/home/clawdbot
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/clawdbot/.clawdbot /home/clawdbot/clawd
PrivateTmp=true
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=clawdbot-gateway
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
log "Systemd service created: clawdbot-gateway"
#───────────────────────────────────────────────────────────────────────────────
# 8. Create config template
#───────────────────────────────────────────────────────────────────────────────
CONFIG_FILE="$CLAWDBOT_HOME/.clawdbot/clawdbot.json"
if [[ ! -f "$CONFIG_FILE" ]]; then
log "Creating config template..."
cat > "$CONFIG_FILE" << 'EOF'
{
"gateway": {
"mode": "local",
"port": 18789,
"bind": "loopback",
"auth": {
"mode": "token",
"token": "REPLACE_WITH_SECURE_TOKEN"
}
},
"channels": {},
"plugins": {
"entries": {}
}
}
EOF
chown "$CLAWDBOT_USER:$CLAWDBOT_USER" "$CONFIG_FILE"
warn "Edit config: nano $CONFIG_FILE"
warn "Generate token: openssl rand -hex 32"
fi
#───────────────────────────────────────────────────────────────────────────────
# 9. Firewall (UFW)
#───────────────────────────────────────────────────────────────────────────────
if command -v ufw &>/dev/null; then
log "Configuring firewall..."
ufw allow ssh
ufw allow in on tailscale0
ufw --force enable
log "Firewall: SSH + Tailscale allowed"
else
warn "UFW not installed - configure firewall manually"
fi
#───────────────────────────────────────────────────────────────────────────────
# Summary
#───────────────────────────────────────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════════════════════════════════════"
echo -e "${GREEN}Setup Complete!${NC}"
echo "═══════════════════════════════════════════════════════════════════════════"
echo ""
echo "Next steps:"
echo ""
echo " 1. Connect Tailscale (if not already):"
echo " tailscale up --ssh --authkey=tskey-auth-xxx"
echo ""
echo " 2. Generate gateway token:"
echo " TOKEN=\$(openssl rand -hex 32)"
echo " echo \"Token: \$TOKEN\""
echo ""
echo " 3. Edit config:"
echo " nano $CONFIG_FILE"
echo " # Set the token and add channels"
echo ""
echo " 4. Start gateway:"
echo " systemctl enable --now clawdbot-gateway"
echo ""
echo " 5. Check status:"
echo " systemctl status clawdbot-gateway"
echo " journalctl -u clawdbot-gateway -f"
echo ""
echo " 6. Access from Mac (via Tailscale):"
echo " ssh clawdbot@$(hostname)"
echo " # Or via Tailscale name: ssh clawdbot@vps-tailscale-name"
echo ""
echo "═══════════════════════════════════════════════════════════════════════════"