#!/usr/bin/env bash # 部署到服务器。 # # **为什么要有这个脚本**:2026-09-16 我用一条 rsync 命令把服务器上的东西 # 删了一大片,教训有三条,都固化在这里: # # 1. **绝不用 `--delete`。** 服务器上还有本地没有的东西(.venv、models 软链、 # logs、数据库软链等)。`--delete` 会把它们全删掉。 # 实测后果:.venv/bin 与 100+ 个 *.dist-info 被删、services/ 被清空、 # README/部署说明被删、models 软链被删。 # 2. **一次只同步一个目录,不要多源。** 多源 rsync 不带 --relative 时, # 会把 `app/` 的内容**平铺**到目标根目录,而不是放进 `app/` 下。 # 3. **排除清单要显式。** 即使不用 --delete,也别把 __pycache__ 之类带过去。 # # 用法: # ./deploy.sh # 同步代码 # ./deploy.sh --restart # 同步后重启两个服务 set -uo pipefail HOST="${AI_DEPLOY_HOST:-yonglin@cadadmin-server.taild0f91d.ts.net}" DEST="${AI_DEPLOY_DEST:-~/ai-companion}" HERE="$(cd "$(dirname "$0")" && pwd)" # 服务器上不该被本地覆盖的东西——保留在服务器上 EXCLUDES=( --exclude '__pycache__' --exclude '*.pyc' --exclude '.baseline' --exclude '.venv' --exclude 'logs' --exclude 'models' --exclude 'out' --exclude 'p0/stt_tts_bench/models' ) sync_one() { # sync_one <本地目录> <远端子路径> echo " → $2" rsync -az "${EXCLUDES[@]}" -e "ssh -o BatchMode=yes" \ "$HERE/$1" "$HOST:$DEST/$2" } echo "部署到 $HOST:$DEST" sync_one "app/" "app/" sync_one "services/" "services/" sync_one "client/" "client/" sync_one "p1/" "p1/" for f in README.md 部署说明.md requirements.txt; do [ -f "$HERE/$f" ] && rsync -az -e "ssh -o BatchMode=yes" "$HERE/$f" "$HOST:$DEST/" done # 把 requirements 里没有、但运行需要的包装上(幂等) ssh -o BatchMode=yes "$HOST" "cd $DEST && .venv/bin/pip -q install pipecat-ai-small-webrtc-prebuilt 2>&1 | tail -1" if [ "${1:-}" = "--restart" ]; then echo "重启服务" ssh -o BatchMode=yes "$HOST" 'bash -s' </dev/null); do kill "\$p" 2>/dev/null; done sleep 3 cd ~/tts-qwen && setsid nohup .venv/bin/python tts_server.py --port 18040 > logs/tts_service.log 2>&1 < /dev/null & sleep 1 cd ~/ai-companion && setsid nohup .venv/bin/python services/bot_server.py --host 0.0.0.0 --port 7860 > logs/bot_server.log 2>&1 < /dev/null & for i in \$(seq 1 30); do curl -sf -o /dev/null http://127.0.0.1:7860/health 2>/dev/null && { echo " bot ✅"; break; } sleep 3 done curl -sf http://127.0.0.1:18040/health 2>/dev/null | grep -q model_loaded && echo " tts ✅" || echo " tts ⚠️" REMOTE fi echo "完成"