#!/bin/bash # deploy.sh — AstroResearch 一键本地打包并推送服务器脚本 (Compose 部署版) # 退出脚本如果发生错误 set -e # ============================================================================= # 配置参数 # ============================================================================= REMOTE_USER="fmq" REMOTE_IP="100.66.1.2" REMOTE_PORT="22" REMOTE_DIR="/vol1/1000/program/astroresearch" IMAGE_NAME="astroresearch" TAG="latest" TAR_NAME="astroresearch.tar.gz" # SSH ControlMaster 配置 —— 复用同一连接,只需输入一次密码 SSH_CONTROL_DIR="$HOME/.ssh/cm" SSH_CONTROL_PATH="${SSH_CONTROL_DIR}/${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}" SSH_OPTS="-o ControlMaster=auto -o ControlPath=${SSH_CONTROL_PATH} -o ControlPersist=1800" mkdir -p "${SSH_CONTROL_DIR}" cleanup_control_master() { # 关闭 master 连接 ssh -p ${REMOTE_PORT} -o ControlPath=${SSH_CONTROL_PATH} ${REMOTE_USER}@${REMOTE_IP} -O exit 2>/dev/null || true } trap cleanup_control_master EXIT # 立即建立 SSH master 连接,提前输入密码,后续步骤复用此连接 echo "=== 连接服务器 (请立即输入密码) ===" ssh -p ${REMOTE_PORT} ${SSH_OPTS} -fN ${REMOTE_USER}@${REMOTE_IP} echo "=== 1. 开始在本地构建 Docker 镜像 (基于 Dockerfile.modeB) ===" docker build -f Dockerfile.modeB -t ${IMAGE_NAME}:${TAG} . echo "=== 2. 将镜像导出并压缩为本地临时文件 ${TAR_NAME} ===" docker save ${IMAGE_NAME}:${TAG} | gzip > ${TAR_NAME} echo "=== 3. 上传镜像包到服务器目标目录 ===" # 首次连接会要求输入密码,后续 scp/ssh 复用此连接 scp -P ${REMOTE_PORT} ${SSH_OPTS} ${TAR_NAME} ${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/ echo "=== 4. 连接服务器:载入镜像并使用 Docker Compose 启动 ===" # 使用 'EOF' 锁死环境,防止本地变量混淆远程环境变量 ssh -p ${REMOTE_PORT} ${SSH_OPTS} ${REMOTE_USER}@${REMOTE_IP} << 'EOF' set -e # 远程运行参数 REMOTE_DIR="/vol1/1000/program/astroresearch" IMAGE_NAME="astroresearch" TAG="latest" TAR_NAME="astroresearch.tar.gz" echo " -> 正在导入 Docker 镜像..." docker load < ${REMOTE_DIR}/${TAR_NAME} echo " -> 清理服务器上的临时镜像压缩包..." rm -f ${REMOTE_DIR}/${TAR_NAME} echo " -> 在服务器上写入/更新生产环境的 docker-compose.yml..." cat > ${REMOTE_DIR}/docker-compose.yml << 'INNER_EOF' version: '3.8' services: astroresearch: image: astroresearch:latest container_name: astroresearch restart: always ports: - "8001:8000" env_file: - .env environment: - DATABASE_URL=sqlite:///app/library/astro_research.db - LIBRARY_DIR=/app/library - SKILLS_DIR=/app/skills - LOG_DIR=/app/logs - PORT=8000 volumes: - ./library:/app/library - ./logs:/app/logs - ./skills:/app/skills:ro INNER_EOF # 进入远程部署目录 cd ${REMOTE_DIR} echo " -> 停止并移除已有的旧服务容器 (docker compose down)..." docker compose down 2>/dev/null || true echo " -> 使用 Docker Compose 启动新服务 (docker compose up -d)..." docker compose up -d echo " -> 部署成功!正在等待 3 秒检查服务运行状态..." sleep 3 docker compose ps EOF echo "=== 5. 清理本地临时压缩包 ===" rm -f ${TAR_NAME} echo "🎉 所有部署操作已圆满完成!服务已在服务器上通过 Docker Compose 后台运行。"