#!/usr/bin/env bash # 家里 Station NAS(192.168.110.29 · DS213j · 无 Docker)部署工作手机网站 # # 用法(Mac 与 NAS 同网): # export NAS_HOST=192.168.110.29 NAS_USER=admin NAS_PASS='zhiqun1984' # bash sdk/scripts/deploy_home_station.sh # # 访问(部署成功后): # 内网(最稳) http://192.168.110.29:8899/hub # 公网 HTTPS https://workphone.quwanzhi.com/hub (推荐;kr Nginx 443 → frp 8889 → NAS 8899) # 公网 HTTP http://workphone.quwanzhi.com/hub (部分网络/Clash 下 80 可能 Empty reply) # frp 直连 http://opennas2.quwanzhi.com:8889/hub # API Key workphone-secret-key(Header: X-API-Key) # # 外网验收注意: # - kr 本机 curl 127.0.0.1 + Host 已 200;链路正常 # - Mac 开 Clash 时域名可能解析到 fake-ip(198.18.x)→ 请加 DIRECT 或 --resolve # - 腾讯云安全组 API 凭证失效时需控制台手动放行 80/443/8889 set -euo pipefail NAS_HOST="${NAS_HOST:-192.168.110.29}" NAS_USER="${NAS_USER:-admin}" NAS_PASS="${NAS_PASS:-zhiqun1984}" NAS_SDK_DIR="${NAS_SDK_DIR:-/volume1/web/workphone-sdk}" NAS_CKB_WEB="${NAS_CKB_WEB:-/volume1/web/cunkebao}" SDK_PORT="${SDK_PORT:-8899}" CKB_WEB_PORT="${CKB_WEB_PORT:-8800}" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SDK_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" REPO_ROOT="$(cd "$SDK_ROOT/.." && pwd)" CKB_ROOT="$(cd "$REPO_ROOT/../cunkebao_v3" 2>/dev/null && pwd || echo "")" SSH_OPTS=(-o StrictHostKeyChecking=no -o ConnectTimeout=15 -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc) ssh_nas() { sshpass -p "$NAS_PASS" ssh "${SSH_OPTS[@]}" "${NAS_USER}@${NAS_HOST}" "$@" } rsync_nas() { sshpass -p "$NAS_PASS" rsync -avz -e "ssh ${SSH_OPTS[*]}" "$@" } echo ">>> 探测家里 NAS ${NAS_HOST} …" ssh_nas "hostname; free -m | head -2" echo ">>> 同步工作手机 SDK -> ${NAS_SDK_DIR}" ssh_nas "mkdir -p '${NAS_SDK_DIR}'" rsync_nas \ --exclude '.git' --exclude '__pycache__' --exclude '*.pyc' --exclude 'node_modules' \ --exclude '.venv' --exclude 'venv' --exclude '.pytest_cache' \ --exclude 'android-app' --exclude 'admin' --exclude 'phone' \ --exclude 'scripts/gadget_work' --exclude 'scripts/**/*.apk' \ --exclude 'data/operation_logs' --exclude '*.md' \ "${SDK_ROOT}/app" "${SDK_ROOT}/scripts" \ "${SDK_ROOT}/requirements.nas-lite.txt" "${SDK_ROOT}/requirements.txt" \ "${SDK_ROOT}/Dockerfile" "${SDK_ROOT}/docker-compose.nas.yml" \ "${NAS_USER}@${NAS_HOST}:${NAS_SDK_DIR}/" echo ">>> 安装 Python 依赖(NAS 精简版)…" ssh_nas "bash -s" <&1 | tail -5 || true REMOTE echo ">>> 写入启动脚本 …" ssh_nas "bash -s" < "\$SDK_DIR/start_workphone.sh" <<'EOS' #!/bin/sh export PATH="/var/services/homes/admin/.local/bin:/usr/local/bin:\$PATH" cd __SDK_DIR__/app export ENV=production export API_KEY=REPLACE_WITH_A_RANDOM_SECRET export AI_BRAIN_ENABLED=false # 家里 NAS 无 Mongo/Redis 容器;SDK 可降级运行 export MONGO_URI= export REDIS_URL= exec /usr/local/bin/python3 -m uvicorn main:app --host 0.0.0.0 --port __PORT__ EOS sed -i "s|__SDK_DIR__|\$SDK_DIR|g; s|__PORT__|\$PORT|g" "\$SDK_DIR/start_workphone.sh" chmod +x "\$SDK_DIR/start_workphone.sh" # 停止旧进程 pkill -f "uvicorn main:app.*${SDK_PORT}" 2>/dev/null || true sleep 1 nohup "\$SDK_DIR/start_workphone.sh" > "\$SDK_DIR/workphone.log" 2>&1 & sleep 8 REMOTE echo ">>> 健康检查 …" if ssh_nas "wget -qO- http://127.0.0.1:${SDK_PORT}/health 2>/dev/null | head -c 200"; then echo "" echo "✅ 工作手机 SDK 已启动" else echo "⚠️ health 未响应,查看日志:" ssh_nas "tail -30 '${NAS_SDK_DIR}/workphone.log' 2>/dev/null || true" fi # 存客宝前端(可选:本地构建后 rsync) if [[ -d "${CKB_ROOT}/Cunkebao" ]]; then echo ">>> 构建存客宝前端(本机)…" if command -v pnpm >/dev/null 2>&1; then (cd "${CKB_ROOT}/Cunkebao" && pnpm install --silent 2>/dev/null && VITE_API_BASE_URL="" pnpm run build 2>&1 | tail -5) || echo "存客宝构建跳过(pnpm 失败)" fi if [[ -d "${CKB_ROOT}/Cunkebao/dist" ]]; then echo ">>> 同步存客宝静态站到 NAS ${NAS_CKB_WEB} …" ssh_nas "mkdir -p '${NAS_CKB_WEB}'" rsync_nas -a --delete "${CKB_ROOT}/Cunkebao/dist/" "${NAS_USER}@${NAS_HOST}:${NAS_CKB_WEB}/" echo " 存客宝静态:http://${NAS_HOST}:${CKB_WEB_PORT}/ (需 WebStation/反代,或 python -m http.server)" fi fi echo "" echo "==============================================" echo " 家里 NAS 部署完成" echo " 工作手机控制台: http://${NAS_HOST}:${SDK_PORT}/hub" echo " SDK API / 文档: http://${NAS_HOST}:${SDK_PORT}/docs" echo " 请在 DSM 防火墙放行 TCP ${SDK_PORT}" echo "=============================================="