fix(install): bring install.sh up to Node 22 and document both Linux scripts (#165)

install.sh still installed Node 20 (dropped in #152), ran the Debian-only
NodeSource script on yum systems, and hard-coded /usr/bin/node. The
README only mentioned install.sh, not setup.sh.

install.sh now:
- installs Node 22 LTS from the right NodeSource repo per distro and
  checks the same 22.12+/24+ floor as setup.sh
- delegates npm install, mirror detection, native-binary checks and the
  build to setup.sh, so the two scripts share one install path
- stops the service and replaces dist/node_modules on re-install (data/
  is kept), copies bin/ (yt-dlp), and uses the real node path in the unit

README explains the difference between the two scripts and when to use
which. setup.sh's "Node.js not found" message no longer says 20+.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
TIANYAO ZHANGandClaude Opus 5.5 committed 2026-09-27 21:42:59 +08:00
1 parent 8ff51ea6e0
commit 88e6b5a691
3 files changed
+90 -26

No files matched your search

+24 -2
View File
@@ -136,14 +136,35 @@ ports:
</details> </details>
### 方式四:Linux 一键安装 ### 方式四:Linux 安装脚本
Linux 下有两个脚本,按需二选一:
| | `scripts/install.sh`(一键安装 + 系统服务) | `scripts/setup.sh`(只安装构建) |
|---|---|---|
| 适合 | 想开箱即用、开机自启的服务器 | 想自己决定怎么常驻(screen / tmux / pm2 / 自写服务)的用户,或 macOS |
| Node.js | 没有或版本过低时**自动安装 Node 22 LTS**(apt / yum / pacman) | **不会安装**,需先自行装好 Node 22.12+ |
| 系统依赖 | 自动安装构建工具(和 FFmpeg,作为内置 FFmpeg 的后备) | 不安装,只提示 |
| 安装位置 | 构建后复制到 `/opt/tsmusicbot`(重装时保留 `data/`) | 就在当前项目目录 |
| 系统服务 | 自动配置 systemd 服务 `tsmusicbot` 并开机自启 | **不配置服务**,完成后自己 `npm start` |
| 需要 root | 是(`sudo`) | 否 |
两者共用同一套安装逻辑:`install.sh` 会调用 `setup.sh` 完成依赖安装、国内网络镜像切换、原生模块校验和构建,然后再复制文件、配置服务。
**一键安装 + systemd 服务:**
```bash ```bash
chmod +x scripts/install.sh chmod +x scripts/install.sh
sudo ./scripts/install.sh sudo ./scripts/install.sh
# 之后:systemctl status|restart|stop tsmusicbot,日志:journalctl -u tsmusicbot -f
``` ```
自动安装 Node.js 和依赖,配置 systemd 服务,支持开机自启。 **只安装构建(不装 Node、不配服务):**
```bash
bash scripts/setup.sh
npm start
```
## 更新升级 ## 更新升级
@@ -495,6 +516,7 @@ teamspeak-music-bot/
├── scripts/ # 部署脚本 ├── scripts/ # 部署脚本
│ ├── setup.bat # Windows 首次安装 │ ├── setup.bat # Windows 首次安装
│ ├── start.bat # Windows 启动脚本 │ ├── start.bat # Windows 启动脚本
│ ├── setup.sh # Linux/macOS 首次安装(只安装构建)
│ ├── install.sh # Linux 一键安装 + systemd 服务 │ ├── install.sh # Linux 一键安装 + systemd 服务
│ └── docker/ # Docker 部署文件 │ └── docker/ # Docker 部署文件
│ ├── Dockerfile │ ├── Dockerfile
+65 -23
View File
@@ -1,6 +1,16 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
#
# TSMusicBot Installer (Linux, systemd)
# - Installs system packages and Node.js 22 LTS
# - Runs scripts/setup.sh to install dependencies, verify native binaries and build
# - Copies the build to /opt/tsmusicbot and registers a systemd service (auto-start on boot)
#
# Only want to build and run it yourself (no Node install, no service)?
# Use scripts/setup.sh instead — see README「Linux 安装脚本」.
#
echo "╔══════════════════════════════════════╗" echo "╔══════════════════════════════════════╗"
echo "║ TSMusicBot Installer ║" echo "║ TSMusicBot Installer ║"
echo "╚══════════════════════════════════════╝" echo "╚══════════════════════════════════════╝"
@@ -11,6 +21,9 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
INSTALL_DIR="/opt/tsmusicbot" INSTALL_DIR="/opt/tsmusicbot"
SERVICE_NAME="tsmusicbot" SERVICE_NAME="tsmusicbot"
# Node LTS line to install when a supported Node is missing. Keep in sync with
# package.json "engines" and the floor check in setup.sh (#152).
NODE_LTS_MAJOR=22
# Verify we're in a valid project directory # Verify we're in a valid project directory
if [ ! -f "$PROJECT_DIR/package.json" ]; then if [ ! -f "$PROJECT_DIR/package.json" ]; then
@@ -28,42 +41,66 @@ else
exit 1 exit 1
fi fi
echo "[1/6] Installing system dependencies..." # Supported: 22.12+ or 24+ (odd majors are excluded by better-sqlite3 and vitest).
node_supported() {
command -v node &> /dev/null &&
node -e 'const v=process.versions.node.split(".").map(Number); process.exit((v[0]===22&&v[1]>=12)||v[0]>=24?0:1)'
}
echo "[1/5] Installing system dependencies..."
case $OS in case $OS in
ubuntu|debian) ubuntu|debian)
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install -y -qq curl build-essential python3 sudo apt-get install -y -qq curl ca-certificates build-essential python3 ffmpeg
;; ;;
centos|rhel|fedora) centos|rhel|fedora|rocky|almalinux)
sudo yum install -y curl gcc gcc-c++ make python3 sudo yum install -y curl gcc gcc-c++ make python3
;; ;;
arch|manjaro) arch|manjaro)
sudo pacman -S --noconfirm curl base-devel python sudo pacman -S --noconfirm --needed curl base-devel python ffmpeg
;; ;;
*) *)
echo "Unsupported OS: $OS. Please install Node.js 20, build tools, and FFmpeg manually." echo "Unsupported OS: $OS. Please install Node.js ${NODE_LTS_MAJOR}.12+ and build tools manually."
;; ;;
esac esac
echo "[2/6] Installing Node.js 20 LTS..." echo "[2/5] Installing Node.js ${NODE_LTS_MAJOR} LTS..."
if ! command -v node &> /dev/null || [[ $(node -v | cut -d. -f1 | tr -d 'v') -lt 20 ]]; then if node_supported; then
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - echo "Node.js $(node -v) already installed"
sudo apt-get install -y -qq nodejs 2>/dev/null || sudo yum install -y nodejs 2>/dev/null else
fi case $OS in
echo "Node.js $(node -v) installed" ubuntu|debian)
curl -fsSL "https://deb.nodesource.com/setup_${NODE_LTS_MAJOR}.x" | sudo -E bash -
echo "[3/6] Installing dependencies..." sudo apt-get install -y -qq nodejs
cd "$PROJECT_DIR" ;;
npm install centos|rhel|fedora|rocky|almalinux)
if [ -d "$PROJECT_DIR/web/package.json" ] || [ -f "$PROJECT_DIR/web/package.json" ]; then curl -fsSL "https://rpm.nodesource.com/setup_${NODE_LTS_MAJOR}.x" | sudo bash -
(cd "$PROJECT_DIR/web" && npm install) sudo yum install -y nodejs
;;
arch|manjaro)
sudo pacman -S --noconfirm --needed nodejs npm
;;
esac
if ! node_supported; then
echo "Error: Node.js 22.12+ (or 24+) is required, found: $(node -v 2>/dev/null || echo none)."
echo "Install it from https://nodejs.org/ (or https://nodejs.cn/) and re-run this script."
exit 1
fi
echo "Node.js $(node -v) installed"
fi fi
echo "[4/6] Building project..." echo "[3/5] Installing dependencies and building (scripts/setup.sh)..."
npm run build bash "$SCRIPT_DIR/setup.sh"
echo "[5/6] Copying to $INSTALL_DIR..." echo "[4/5] Copying to $INSTALL_DIR..."
# Stop a running copy before replacing its files (re-install / upgrade).
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
sudo systemctl stop "$SERVICE_NAME"
fi
sudo mkdir -p "$INSTALL_DIR" sudo mkdir -p "$INSTALL_DIR"
# Replace build output wholesale so files removed upstream don't linger.
# data/ (config, database, cookies) is never touched.
sudo rm -rf "$INSTALL_DIR/dist" "$INSTALL_DIR/node_modules" "$INSTALL_DIR/web/dist"
sudo cp -r "$PROJECT_DIR/dist" "$INSTALL_DIR/" sudo cp -r "$PROJECT_DIR/dist" "$INSTALL_DIR/"
sudo cp -r "$PROJECT_DIR/node_modules" "$INSTALL_DIR/" sudo cp -r "$PROJECT_DIR/node_modules" "$INSTALL_DIR/"
sudo cp "$PROJECT_DIR/package.json" "$INSTALL_DIR/" sudo cp "$PROJECT_DIR/package.json" "$INSTALL_DIR/"
@@ -72,13 +109,18 @@ if [ -d "$PROJECT_DIR/web/dist" ]; then
sudo mkdir -p "$INSTALL_DIR/web" sudo mkdir -p "$INSTALL_DIR/web"
sudo cp -r "$PROJECT_DIR/web/dist" "$INSTALL_DIR/web/" sudo cp -r "$PROJECT_DIR/web/dist" "$INSTALL_DIR/web/"
fi fi
# yt-dlp is looked up in bin/ next to dist/ before falling back to PATH
if [ -d "$PROJECT_DIR/bin" ]; then
sudo cp -r "$PROJECT_DIR/bin" "$INSTALL_DIR/"
fi
# Copy scripts for future use # Copy scripts for future use
sudo mkdir -p "$INSTALL_DIR/scripts" sudo mkdir -p "$INSTALL_DIR/scripts"
sudo cp -r "$PROJECT_DIR/scripts/"* "$INSTALL_DIR/scripts/" 2>/dev/null || true sudo cp -r "$PROJECT_DIR/scripts/"* "$INSTALL_DIR/scripts/" 2>/dev/null || true
# Create data directory # Create data directory
sudo mkdir -p "$INSTALL_DIR/data" sudo mkdir -p "$INSTALL_DIR/data"
echo "[6/6] Creating systemd service..." echo "[5/5] Creating systemd service..."
NODE_BIN="$(command -v node)"
sudo tee /etc/systemd/system/${SERVICE_NAME}.service > /dev/null <<EOL sudo tee /etc/systemd/system/${SERVICE_NAME}.service > /dev/null <<EOL
[Unit] [Unit]
Description=TSMusicBot - TeamSpeak Music Bot Description=TSMusicBot - TeamSpeak Music Bot
@@ -88,7 +130,7 @@ After=network.target
Type=simple Type=simple
User=root User=root
WorkingDirectory=${INSTALL_DIR} WorkingDirectory=${INSTALL_DIR}
ExecStart=/usr/bin/node ${INSTALL_DIR}/dist/index.js ExecStart=${NODE_BIN} ${INSTALL_DIR}/dist/index.js
Restart=on-failure Restart=on-failure
RestartSec=5 RestartSec=5
Environment=NODE_ENV=production Environment=NODE_ENV=production
@@ -99,7 +141,7 @@ EOL
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo systemctl enable ${SERVICE_NAME} sudo systemctl enable ${SERVICE_NAME}
sudo systemctl start ${SERVICE_NAME} sudo systemctl restart ${SERVICE_NAME}
echo "" echo ""
echo "╔══════════════════════════════════════╗" echo "╔══════════════════════════════════════╗"
+1 -1
View File
@@ -21,7 +21,7 @@ echo ""
# ---- Check Node.js ---- # ---- Check Node.js ----
if ! command -v node &>/dev/null; then if ! command -v node &>/dev/null; then
echo "[ERROR] Node.js not found. Please install Node.js 20+ from https://nodejs.org" echo "[ERROR] Node.js not found. Please install Node.js 22.12+ LTS from https://nodejs.org"
echo " or https://nodejs.cn/ (China mirror)." echo " or https://nodejs.cn/ (China mirror)."
exit 1 exit 1
fi fi