Files
soul-yongping/deploy_to_nas.sh

326 lines
9.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ============================================
# Soul创业实验项目 - NAS部署脚本
# 用途: 自动部署Next.js应用到NAS-2
# ============================================
set -e
# 配置
NAS_USER="fnvtk"
NAS_IP="192.168.2.201"
NAS_PASSWORD="Zhiqun1984"
SUDO_PASSWORD="Zhiqun1984"
DOCKER_CMD="/volume1/@appstore/ContainerManager/usr/bin/docker"
DOCKER_COMPOSE_CMD="/volume1/@appstore/ContainerManager/usr/bin/docker-compose"
PROJECT_NAME="soul-book"
PROJECT_DIR="/volume1/docker/${PROJECT_NAME}"
LOCAL_PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="/tmp/soul_deploy_$(date +%Y%m%d_%H%M%S).log"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "==========================================" | tee -a $LOG_FILE
echo "Soul创业实验项目 - NAS部署脚本" | tee -a $LOG_FILE
echo "开始时间: $(date)" | tee -a $LOG_FILE
echo "==========================================" | tee -a $LOG_FILE
echo ""
print_step() {
echo -e "${GREEN}[步骤 $1]${NC} $2" | tee -a $LOG_FILE
}
print_error() {
echo -e "${RED}[错误]${NC} $1" | tee -a $LOG_FILE
}
print_warn() {
echo -e "${YELLOW}[警告]${NC} $1" | tee -a $LOG_FILE
}
# 检查 expect
if ! command -v expect &> /dev/null; then
print_error "expect 未安装,请先安装: brew install expect"
exit 1
fi
# ============================================
# 步骤 1: 检查网络连通性
# ============================================
print_step "1" "检查网络连通性..."
if ping -c 1 $NAS_IP > /dev/null 2>&1; then
echo "✅ NAS-2 在线" | tee -a $LOG_FILE
else
print_error "无法连接到 NAS-2 ($NAS_IP)"
exit 1
fi
# ============================================
# 步骤 2: 创建项目目录
# ============================================
print_step "2" "创建项目目录..."
expect << EOF | tee -a $LOG_FILE
set timeout 30
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "sudo mkdir -p ${PROJECT_DIR} && sudo chown -R ${NAS_USER}:users ${PROJECT_DIR} && echo '目录创建完成'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
"目录创建完成" {
puts "✅ 目录创建成功"
}
timeout {
puts "❌ 超时"
exit 1
}
}
expect eof
EOF
# ============================================
# 步骤 3: 检查nas-network是否存在
# ============================================
print_step "3" "检查Docker网络..."
expect << EOF | tee -a $LOG_FILE
set timeout 30
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "sudo $DOCKER_CMD network inspect nas-network > /dev/null 2>&1 || sudo $DOCKER_CMD network create nas-network && echo '网络检查完成'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
"网络检查完成" {
puts "✅ 网络检查成功"
}
timeout {
puts "⚠️ 超时,但继续执行"
}
}
expect eof
EOF
# ============================================
# 步骤 4: 传输项目文件排除node_modules和.git
# ============================================
print_step "4" "传输项目文件到NAS这可能需要几分钟..."
# 创建临时排除文件
EXCLUDE_FILE=$(mktemp)
cat > $EXCLUDE_FILE << 'EXCLUDES'
node_modules/
.git/
.next/
.DS_Store
*.log
.env.local
.env*.local
EXCLUDES
expect << EOF | tee -a $LOG_FILE
set timeout 600
spawn rsync -avz --progress --exclude-from=$EXCLUDE_FILE -e "ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc" "$LOCAL_PROJECT_DIR/" $NAS_USER@$NAS_IP:${PROJECT_DIR}/
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
timeout {
puts "⚠️ 传输可能超时,但继续执行"
}
}
expect eof
EOF
rm -f $EXCLUDE_FILE
# ============================================
# 步骤 5: 在NAS上安装依赖和构建
# ============================================
print_step "5" "在NAS上安装依赖使用pnpm..."
expect << EOF | tee -a $LOG_FILE
set timeout 300
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "cd ${PROJECT_DIR} && if ! command -v pnpm &> /dev/null; then npm install -g pnpm; fi && pnpm install --frozen-lockfile && echo '依赖安装完成'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
"依赖安装完成" {
puts "✅ 依赖安装成功"
}
timeout {
puts "⚠️ 安装可能超时,但继续执行"
}
}
expect eof
EOF
# ============================================
# 步骤 6: 停止并删除旧容器(如果存在)
# ============================================
print_step "6" "停止并删除旧容器(如果存在)..."
expect << EOF | tee -a $LOG_FILE
set timeout 60
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "cd ${PROJECT_DIR} && sudo $DOCKER_COMPOSE_CMD down 2>/dev/null || true && sudo $DOCKER_CMD rm -f ${PROJECT_NAME} 2>/dev/null || true && echo '旧容器清理完成'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
"旧容器清理完成" {
puts "✅ 旧容器清理成功"
}
timeout {
puts "⚠️ 清理可能超时,但继续执行"
}
}
expect eof
EOF
# ============================================
# 步骤 7: 构建Docker镜像
# ============================================
print_step "7" "构建Docker镜像这可能需要5-10分钟..."
expect << EOF | tee -a $LOG_FILE
set timeout 1200
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "cd ${PROJECT_DIR} && sudo $DOCKER_COMPOSE_CMD build --no-cache && echo '镜像构建完成'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
"镜像构建完成" {
puts "✅ 镜像构建成功"
}
timeout {
puts "⚠️ 构建可能超时,但继续执行"
}
}
expect eof
EOF
# ============================================
# 步骤 8: 启动容器
# ============================================
print_step "8" "启动容器..."
expect << EOF | tee -a $LOG_FILE
set timeout 120
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "cd ${PROJECT_DIR} && sudo $DOCKER_COMPOSE_CMD up -d && echo '容器启动完成'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
"容器启动完成" {
puts "✅ 容器启动成功"
}
timeout {
puts "⚠️ 启动可能超时"
}
}
expect eof
EOF
# 等待服务启动
echo "等待服务启动30秒..." | tee -a $LOG_FILE
sleep 30
# ============================================
# 步骤 9: 检查容器状态
# ============================================
print_step "9" "检查容器状态..."
expect << EOF | tee -a $LOG_FILE
set timeout 30
spawn ssh -t -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "sudo $DOCKER_CMD ps --filter name=${PROJECT_NAME} --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"Password:" {
send "$SUDO_PASSWORD\r"
exp_continue
}
}
expect eof
EOF
# ============================================
# 步骤 10: 检查服务健康状态
# ============================================
print_step "10" "检查服务健康状态..."
expect << EOF | tee -a $LOG_FILE
set timeout 30
spawn ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 -o Ciphers=+aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc $NAS_USER@$NAS_IP "curl -s -o /dev/null -w '%{http_code}' http://localhost:3000 || echo '服务未响应'"
expect {
"password:" {
send "$NAS_PASSWORD\r"
exp_continue
}
"200" {
puts "✅ 服务运行正常"
}
"服务未响应" {
puts "⚠️ 服务可能还在启动中"
}
}
expect eof
EOF
# ============================================
# 完成
# ============================================
echo "" | tee -a $LOG_FILE
echo "==========================================" | tee -a $LOG_FILE
echo "✅ 部署脚本执行完成!" | tee -a $LOG_FILE
echo "完成时间: $(date)" | tee -a $LOG_FILE
echo "日志文件: $LOG_FILE" | tee -a $LOG_FILE
echo "==========================================" | tee -a $LOG_FILE
echo ""
echo "访问地址:"
echo " http://${NAS_IP}:3000"
echo ""
echo "下一步操作:"
echo "1. 查看容器日志: ssh $NAS_USER@$NAS_IP 'sudo $DOCKER_CMD logs -f ${PROJECT_NAME}'"
echo "2. 查看容器状态: ssh $NAS_USER@$NAS_IP 'sudo $DOCKER_CMD ps --filter name=${PROJECT_NAME}'"
echo "3. 重启容器: ssh $NAS_USER@$NAS_IP 'cd ${PROJECT_DIR} && sudo $DOCKER_COMPOSE_CMD restart'"
echo "4. 停止容器: ssh $NAS_USER@$NAS_IP 'cd ${PROJECT_DIR} && sudo $DOCKER_COMPOSE_CMD down'"