Files
happy-life-star/deploy-aliyun.sh
T

1028 lines
24 KiB
Bash
Executable File

#!/bin/bash
# 情绪博物馆阿里云服务器部署脚本
# 适配服务器配置: MySQL/Redis/Nacos直接安装,应用服务使用Docker
# 作者: EmotionMuseum Team
# 日期: 2025-07-13
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 服务器配置
SERVER_IP="47.111.10.27"
SERVER_USER="root"
MYSQL_ROOT_PASSWORD="123456"
# 部署目录配置
PROGRAMS_DIR="/data/programs"
BUILDS_DIR="/data/builds"
WEB_DIR="/data/www/emotion-museum"
CONFIG_FILE="/data/deployment_config.md"
# 密码生成函数
generate_password() {
echo $(openssl rand -base64 32 | tr -d "=+/" | cut -c1-20)
}
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
# 远程执行命令
remote_exec() {
local command="$1"
ssh -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_IP}" "$command"
}
# 远程执行脚本
remote_exec_script() {
local script="$1"
ssh -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_IP}" 'bash -s' < "$script"
}
# 复制文件到服务器
remote_copy() {
local local_path="$1"
local remote_path="$2"
scp -o StrictHostKeyChecking=no -r "$local_path" "${SERVER_USER}@${SERVER_IP}:$remote_path"
}
# 检查服务器连接
check_server_connection() {
log_step "检查服务器连接..."
if ! ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 "${SERVER_USER}@${SERVER_IP}" "echo 'Connected to server successfully'" &>/dev/null; then
log_error "无法连接到服务器 ${SERVER_IP},请检查网络连接和SSH配置"
exit 1
fi
log_info "服务器连接正常"
}
# 创建服务器目录结构
create_server_directories() {
log_step "创建服务器目录结构..."
remote_exec "mkdir -p ${PROGRAMS_DIR}/{mysql,redis,nacos,java,maven,nodejs}"
remote_exec "mkdir -p ${BUILDS_DIR}"
remote_exec "mkdir -p ${WEB_DIR}"
remote_exec "mkdir -p /data/logs/{mysql,redis,nacos,docker}"
remote_exec "mkdir -p /data/backup"
log_info "目录结构创建完成"
}
# 安装基础环境
install_base_environment() {
log_step "安装基础环境..."
# 创建安装脚本
cat > /tmp/install_base.sh << 'EOF'
#!/bin/bash
# 更新系统
yum update -y
yum install -y wget curl git unzip vim net-tools
# 安装Docker
if ! command -v docker &> /dev/null; then
curl -fsSL https://get.docker.com | sh
systemctl start docker
systemctl enable docker
echo "Docker安装完成"
else
echo "Docker已安装"
fi
# 安装Docker Compose
if ! command -v docker-compose &> /dev/null; then
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
echo "Docker Compose安装完成"
else
echo "Docker Compose已安装"
fi
EOF
remote_exec_script /tmp/install_base.sh
rm /tmp/install_base.sh
log_info "基础环境安装完成"
}
# 安装配置Java环境
install_java() {
log_step "安装Java环境..."
cat > /tmp/install_java.sh << 'EOF'
#!/bin/bash
JAVA_VERSION="17"
JAVA_DIR="/data/programs/java"
# 检查Java是否已安装
if command -v java &> /dev/null; then
java_ver=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | cut -d'.' -f1)
if [ "$java_ver" -ge "$JAVA_VERSION" ]; then
echo "Java $java_ver 已安装"
exit 0
fi
fi
# 安装OpenJDK 17
yum install -y java-17-openjdk java-17-openjdk-devel
# 配置JAVA_HOME
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk' >> /etc/profile
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile
# 立即生效
source /etc/profile
echo "Java环境安装完成"
EOF
remote_exec_script /tmp/install_java.sh
rm /tmp/install_java.sh
log_info "Java环境安装完成"
}
# 安装配置Maven环境
install_maven() {
log_step "安装Maven环境..."
cat > /tmp/install_maven.sh << 'EOF'
#!/bin/bash
MAVEN_VERSION="3.9.5"
MAVEN_DIR="/data/programs/maven"
# 检查Maven是否已安装
if command -v mvn &> /dev/null; then
echo "Maven已安装: $(mvn -version | head -n 1)"
exit 0
fi
# 下载Maven
cd /tmp
wget https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz
# 解压到指定目录
tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz
mv apache-maven-${MAVEN_VERSION} ${MAVEN_DIR}
# 配置环境变量
echo "export MAVEN_HOME=${MAVEN_DIR}" >> /etc/profile
echo 'export PATH=$MAVEN_HOME/bin:$PATH' >> /etc/profile
# 立即生效
source /etc/profile
# 清理
rm -f apache-maven-${MAVEN_VERSION}-bin.tar.gz
echo "Maven环境安装完成"
EOF
remote_exec_script /tmp/install_maven.sh
rm /tmp/install_maven.sh
log_info "Maven环境安装完成"
}
# 安装配置Node.js环境
install_nodejs() {
log_step "安装Node.js环境..."
cat > /tmp/install_nodejs.sh << 'EOF'
#!/bin/bash
NODE_VERSION="18"
NODE_DIR="/data/programs/nodejs"
# 检查Node.js是否已安装
if command -v node &> /dev/null; then
node_ver=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
if [ "$node_ver" -ge "$NODE_VERSION" ]; then
echo "Node.js v$(node -v) 已安装"
exit 0
fi
fi
# 安装Node.js 18
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash -
yum install -y nodejs
# 配置npm镜像
npm config set registry https://registry.npmmirror.com
echo "Node.js环境安装完成"
EOF
remote_exec_script /tmp/install_nodejs.sh
rm /tmp/install_nodejs.sh
log_info "Node.js环境安装完成"
}
# 安装配置MySQL
install_mysql() {
log_step "安装配置MySQL..."
# 生成新的MySQL密码
NEW_MYSQL_PASSWORD=$(generate_password)
cat > /tmp/install_mysql.sh << EOF
#!/bin/bash
MYSQL_DIR="${PROGRAMS_DIR}/mysql"
CURRENT_PASSWORD="${MYSQL_ROOT_PASSWORD}"
NEW_PASSWORD="${NEW_MYSQL_PASSWORD}"
# 检查MySQL是否已安装
if systemctl is-active --quiet mysqld 2>/dev/null; then
echo "MySQL服务已在运行"
# 测试连接
if mysql -u root -p\${CURRENT_PASSWORD} -e "SELECT 1;" &>/dev/null; then
echo "MySQL连接正常,密码正确"
exit 0
else
echo "MySQL密码可能已更改"
fi
else
echo "开始安装MySQL..."
# 安装MySQL 8.0
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
rpm -ivh mysql80-community-release-el7-3.noarch.rpm
yum install -y mysql-server
# 启动MySQL服务
systemctl start mysqld
systemctl enable mysqld
# 获取临时密码
TEMP_PASSWORD=\$(grep 'temporary password' /var/log/mysqld.log | awk '{print \$NF}')
# 修改root密码
mysql -u root -p"\${TEMP_PASSWORD}" --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '\${NEW_PASSWORD}';"
# 创建应用数据库和用户
mysql -u root -p\${NEW_PASSWORD} -e "
CREATE DATABASE IF NOT EXISTS emotion_museum CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'emotion'@'%' IDENTIFIED BY 'EmotionDB2024!';
GRANT ALL PRIVILEGES ON emotion_museum.* TO 'emotion'@'%';
FLUSH PRIVILEGES;
"
echo "MySQL安装和配置完成"
echo "新的root密码: \${NEW_PASSWORD}"
fi
EOF
remote_exec_script /tmp/install_mysql.sh
rm /tmp/install_mysql.sh
# 记录密码信息
echo "MySQL_ROOT_PASSWORD=${NEW_MYSQL_PASSWORD}" >> /tmp/deployment_config.md
log_info "MySQL安装配置完成,新密码已生成"
}
# 安装配置Redis
install_redis() {
log_step "安装配置Redis..."
# 生成Redis密码
REDIS_PASSWORD=$(generate_password)
cat > /tmp/install_redis.sh << EOF
#!/bin/bash
REDIS_DIR="${PROGRAMS_DIR}/redis"
REDIS_PASSWORD="${REDIS_PASSWORD}"
# 检查Redis是否已安装
if systemctl is-active --quiet redis 2>/dev/null; then
echo "Redis服务已在运行"
exit 0
fi
# 安装Redis
yum install -y epel-release
yum install -y redis
# 配置Redis
sed -i 's/^# requirepass foobared/requirepass '\${REDIS_PASSWORD}'/' /etc/redis.conf
sed -i 's/^bind 127.0.0.1/bind 0.0.0.0/' /etc/redis.conf
# 启动Redis服务
systemctl start redis
systemctl enable redis
echo "Redis安装和配置完成"
echo "Redis密码: \${REDIS_PASSWORD}"
EOF
remote_exec_script /tmp/install_redis.sh
rm /tmp/install_redis.sh
# 记录密码信息
echo "REDIS_PASSWORD=${REDIS_PASSWORD}" >> /tmp/deployment_config.md
log_info "Redis安装配置完成,密码已生成"
}
# 安装配置Nacos
install_nacos() {
log_step "安装配置Nacos..."
cat > /tmp/install_nacos.sh << 'EOF'
#!/bin/bash
NACOS_VERSION="2.2.0"
NACOS_DIR="/data/programs/nacos"
# 检查Nacos是否已安装
if [ -d "${NACOS_DIR}" ] && [ -f "${NACOS_DIR}/bin/startup.sh" ]; then
echo "Nacos已安装"
# 检查是否运行
if pgrep -f "nacos" > /dev/null; then
echo "Nacos服务正在运行"
exit 0
else
echo "启动Nacos服务..."
cd ${NACOS_DIR}/bin
bash startup.sh -m standalone
exit 0
fi
fi
# 下载Nacos
cd /tmp
wget https://github.com/alibaba/nacos/releases/download/${NACOS_VERSION}/nacos-server-${NACOS_VERSION}.tar.gz
# 解压到指定目录
tar -xzf nacos-server-${NACOS_VERSION}.tar.gz
mv nacos ${NACOS_DIR}
# 配置Nacos
cd ${NACOS_DIR}/conf
cp application.properties application.properties.backup
# 使用内嵌数据库模式(单机版)
cat > application.properties << 'NACOS_EOF'
server.servlet.contextPath=/nacos
server.port=8848
nacos.cmdb.dumpTaskInterval=3600
nacos.cmdb.eventTaskInterval=10
nacos.cmdb.labelTaskInterval=300
nacos.cmdb.loadDataAtStart=false
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %{User-Agent}i
server.tomcat.basedir=
nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true
nacos.naming.expireInstance=true
nacos.istio.mcp.server.enabled=false
NACOS_EOF
# 启动Nacos
cd ${NACOS_DIR}/bin
bash startup.sh -m standalone
# 创建启动脚本
cat > /etc/systemd/system/nacos.service << 'SERVICE_EOF'
[Unit]
Description=Nacos Server
After=network.target
[Service]
Type=forking
ExecStart=/data/programs/nacos/bin/startup.sh -m standalone
ExecStop=/data/programs/nacos/bin/shutdown.sh
User=root
Group=root
Restart=always
[Install]
WantedBy=multi-user.target
SERVICE_EOF
systemctl daemon-reload
systemctl enable nacos
echo "Nacos安装和配置完成"
EOF
remote_exec_script /tmp/install_nacos.sh
rm /tmp/install_nacos.sh
log_info "Nacos安装配置完成"
}
# 构建后端服务
build_backend_services() {
log_step "构建后端服务..."
# 检查后端目录
if [ ! -d "backend" ]; then
log_error "backend目录不存在,请在项目根目录运行脚本"
exit 1
fi
# 构建所有微服务
log_info "开始构建微服务..."
cd backend
# 清理和编译
mvn clean install -DskipTests
# 创建构建产物目录
mkdir -p ../build-output/jars
mkdir -p ../build-output/configs
# 复制JAR文件
find . -name "*.jar" -not -path "*/target/original-*" | while read jar; do
service_name=$(echo $jar | cut -d'/' -f2)
cp "$jar" "../build-output/jars/${service_name}.jar"
log_info "已构建: ${service_name}.jar"
done
cd ..
log_info "后端服务构建完成"
}
# 构建前端应用
build_frontend() {
log_step "构建前端应用..."
# 检查前端目录
if [ ! -d "web" ]; then
log_error "web目录不存在,请在项目根目录运行脚本"
exit 1
fi
cd web
# 安装依赖
log_info "安装前端依赖..."
npm install
# 构建生产版本
log_info "构建生产版本..."
npm run build
# 创建构建产物目录
mkdir -p ../build-output/web
# 复制构建产物
cp -r dist/* ../build-output/web/
cd ..
log_info "前端应用构建完成"
}
# 上传构建产物
upload_build_artifacts() {
log_step "上传构建产物到服务器..."
# 上传JAR文件
if [ -d "build-output/jars" ]; then
remote_copy "build-output/jars/*" "${BUILDS_DIR}/"
log_info "JAR文件上传完成"
fi
# 上传前端文件
if [ -d "build-output/web" ]; then
remote_exec "rm -rf ${WEB_DIR}/*"
remote_copy "build-output/web/*" "${WEB_DIR}/"
log_info "前端文件上传完成"
fi
# 上传配置文件
remote_copy "backend/mysql_emotion_museum_final.sql" "/tmp/"
log_info "构建产物上传完成"
}
# 初始化数据库
initialize_database() {
log_step "初始化数据库..."
cat > /tmp/init_database.sh << 'EOF'
#!/bin/bash
# 导入数据库结构
mysql -u root -p"${NEW_MYSQL_PASSWORD}" emotion_museum < /tmp/mysql_emotion_museum_final.sql
echo "数据库初始化完成"
EOF
remote_exec_script /tmp/init_database.sh
rm /tmp/init_database.sh
log_info "数据库初始化完成"
}
# 创建Docker Compose文件
create_docker_compose() {
log_step "创建Docker Compose配置..."
cat > /tmp/docker-compose-aliyun.yml << 'EOF'
version: '3.8'
services:
# 网关服务
gateway:
build:
context: .
dockerfile: Dockerfile.gateway
image: emotion-gateway:latest
container_name: emotion-gateway
restart: always
ports:
- "9000:9000"
environment:
SPRING_PROFILES_ACTIVE: prod
NACOS_SERVER_ADDR: host.docker.internal:8848
MYSQL_HOST: host.docker.internal
MYSQL_PORT: 3306
REDIS_HOST: host.docker.internal
REDIS_PORT: 6379
TZ: Asia/Shanghai
volumes:
- /data/logs/docker/gateway:/app/logs
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- emotion-network
# AI服务
ai-service:
build:
context: .
dockerfile: Dockerfile.ai
image: emotion-ai:latest
container_name: emotion-ai
restart: always
ports:
- "9002:9002"
environment:
SPRING_PROFILES_ACTIVE: prod
NACOS_SERVER_ADDR: host.docker.internal:8848
MYSQL_HOST: host.docker.internal
MYSQL_PORT: 3306
REDIS_HOST: host.docker.internal
REDIS_PORT: 6379
COZE_API_TOKEN: pat_GCR4qKzqpf90wMCvKsldMrB18KG3QsLDci65bZthssKsbLxu8X70BKYumleDcabO
TZ: Asia/Shanghai
volumes:
- /data/logs/docker/ai:/app/logs
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- emotion-network
# 用户服务
user-service:
build:
context: .
dockerfile: Dockerfile.user
image: emotion-user:latest
container_name: emotion-user
restart: always
ports:
- "9001:9001"
environment:
SPRING_PROFILES_ACTIVE: prod
NACOS_SERVER_ADDR: host.docker.internal:8848
MYSQL_HOST: host.docker.internal
MYSQL_PORT: 3306
REDIS_HOST: host.docker.internal
REDIS_PORT: 6379
TZ: Asia/Shanghai
volumes:
- /data/logs/docker/user:/app/logs
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- emotion-network
networks:
emotion-network:
driver: bridge
EOF
# 上传Docker Compose文件
remote_copy "/tmp/docker-compose-aliyun.yml" "${BUILDS_DIR}/docker-compose.yml"
rm /tmp/docker-compose-aliyun.yml
log_info "Docker Compose配置创建完成"
}
# 创建Dockerfile
create_dockerfiles() {
log_step "创建Dockerfile..."
# Gateway Dockerfile
cat > /tmp/Dockerfile.gateway << 'EOF'
FROM openjdk:17-jre-slim
WORKDIR /app
COPY emotion-gateway.jar app.jar
EXPOSE 9000
ENTRYPOINT ["java", "-jar", "app.jar"]
EOF
# AI Service Dockerfile
cat > /tmp/Dockerfile.ai << 'EOF'
FROM openjdk:17-jre-slim
WORKDIR /app
COPY emotion-ai.jar app.jar
EXPOSE 9002
ENTRYPOINT ["java", "-jar", "app.jar"]
EOF
# User Service Dockerfile
cat > /tmp/Dockerfile.user << 'EOF'
FROM openjdk:17-jre-slim
WORKDIR /app
COPY emotion-user.jar app.jar
EXPOSE 9001
ENTRYPOINT ["java", "-jar", "app.jar"]
EOF
# 上传Dockerfile
remote_copy "/tmp/Dockerfile.*" "${BUILDS_DIR}/"
# 清理临时文件
rm /tmp/Dockerfile.*
log_info "Dockerfile创建完成"
}
# 配置Nginx
configure_nginx() {
log_step "配置Nginx..."
cat > /tmp/setup_nginx.sh << EOF
#!/bin/bash
WEB_DIR="${WEB_DIR}"
# 安装Nginx
if ! command -v nginx &> /dev/null; then
yum install -y nginx
fi
# 创建Nginx配置
cat > /etc/nginx/nginx.conf << 'NGINX_EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 前端应用
server {
listen 80;
server_name ${SERVER_IP};
root ${WEB_DIR};
index index.html;
# 前端路由支持
location / {
try_files \$uri \$uri/ /index.html;
}
# API代理
location /api/ {
proxy_pass http://127.0.0.1:9000/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
}
}
}
NGINX_EOF
# 启动Nginx
systemctl start nginx
systemctl enable nginx
echo "Nginx配置完成"
EOF
remote_exec_script /tmp/setup_nginx.sh
rm /tmp/setup_nginx.sh
log_info "Nginx配置完成"
}
# 启动Docker服务
start_docker_services() {
log_step "启动Docker服务..."
cat > /tmp/start_services.sh << EOF
#!/bin/bash
cd ${BUILDS_DIR}
# 构建Docker镜像
docker build -f Dockerfile.gateway -t emotion-gateway:latest .
docker build -f Dockerfile.ai -t emotion-ai:latest .
docker build -f Dockerfile.user -t emotion-user:latest .
# 启动服务
docker-compose up -d
echo "Docker服务启动完成"
EOF
remote_exec_script /tmp/start_services.sh
rm /tmp/start_services.sh
log_info "Docker服务启动完成"
}
# 创建部署配置记录
create_deployment_config() {
log_step "创建部署配置记录..."
cat > /tmp/deployment_config.md << EOF
# 情绪博物馆部署配置记录
## 服务器信息
- 服务器IP: ${SERVER_IP}
- 部署时间: $(date '+%Y-%m-%d %H:%M:%S')
## 目录结构
- 程序目录: ${PROGRAMS_DIR}
- 构建目录: ${BUILDS_DIR}
- 前端目录: ${WEB_DIR}
- 日志目录: /data/logs
## 服务配置
- MySQL端口: 3306
- Redis端口: 6379
- Nacos端口: 8848
- 网关端口: 9000
- AI服务端口: 9002
- 用户服务端口: 9001
- Nginx端口: 80
## 密码信息
$(cat /tmp/deployment_config.md 2>/dev/null || echo "# 密码信息将在安装过程中生成")
## 访问地址
- 前端应用: http://${SERVER_IP}
- API网关: http://${SERVER_IP}:9000
- Nacos控制台: http://${SERVER_IP}:8848/nacos (nacos/nacos)
## 管理命令
\`\`\`bash
# 查看服务状态
systemctl status mysql redis nacos nginx
docker ps
# 查看日志
tail -f /var/log/mysqld.log
tail -f /var/log/redis/redis.log
tail -f ${PROGRAMS_DIR}/nacos/logs/start.out
docker logs -f emotion-gateway
# 重启服务
systemctl restart mysql redis nacos nginx
docker-compose -f ${BUILDS_DIR}/docker-compose.yml restart
\`\`\`
## 备份和维护
\`\`\`bash
# 数据库备份
mysqldump -u root -p emotion_museum > /data/backup/emotion_museum_\$(date +%Y%m%d).sql
# 清理Docker
docker system prune -f
# 更新代码
cd ${BUILDS_DIR}
# 替换JAR文件
docker-compose restart
\`\`\`
EOF
# 上传配置文件
remote_copy "/tmp/deployment_config.md" "${CONFIG_FILE}"
rm /tmp/deployment_config.md
log_info "部署配置记录已创建: ${CONFIG_FILE}"
}
# 健康检查
health_check() {
log_step "执行健康检查..."
sleep 30 # 等待服务启动
log_info "检查基础服务状态..."
remote_exec "systemctl is-active mysql redis nacos nginx"
log_info "检查Docker服务状态..."
remote_exec "docker ps"
log_info "检查端口监听状态..."
remote_exec "netstat -tlnp | grep -E ':(80|3306|6379|8848|9000|9001|9002)'"
log_info "测试HTTP接口..."
if remote_exec "curl -s http://localhost:80 >/dev/null"; then
log_info "✅ 前端应用访问正常"
else
log_warn "❌ 前端应用访问异常"
fi
if remote_exec "curl -s http://localhost:9000/actuator/health >/dev/null"; then
log_info "✅ API网关访问正常"
else
log_warn "❌ API网关访问异常"
fi
if remote_exec "curl -s http://localhost:8848/nacos >/dev/null"; then
log_info "✅ Nacos控制台访问正常"
else
log_warn "❌ Nacos控制台访问异常"
fi
log_info "健康检查完成"
}
# 显示部署结果
show_deployment_result() {
log_step "部署完成!"
echo ""
echo "🎉 情绪博物馆部署成功!"
echo ""
echo "📱 访问地址:"
echo " 前端应用: http://${SERVER_IP}"
echo " API网关: http://${SERVER_IP}:9000"
echo " Nacos: http://${SERVER_IP}:8848/nacos (用户名/密码: nacos/nacos)"
echo ""
echo "📁 服务器目录:"
echo " 程序目录: ${PROGRAMS_DIR}"
echo " 构建目录: ${BUILDS_DIR}"
echo " 前端目录: ${WEB_DIR}"
echo " 配置文件: ${CONFIG_FILE}"
echo ""
echo "🔧 管理命令:"
echo " ssh ${SERVER_USER}@${SERVER_IP}"
echo " systemctl status mysql redis nacos nginx"
echo " docker ps"
echo " docker-compose -f ${BUILDS_DIR}/docker-compose.yml logs -f"
echo ""
echo "⚠️ 重要提醒:"
echo " 1. 密码信息已保存到服务器 ${CONFIG_FILE} 文件中"
echo " 2. 请及时修改默认密码"
echo " 3. 建议配置防火墙规则"
echo " 4. 定期备份数据库"
echo ""
}
# 主部署流程
main() {
echo "🚀 开始部署情绪博物馆到阿里云服务器..."
echo ""
# 检查本地构建环境
if ! command -v mvn &> /dev/null; then
log_error "本地未安装Maven,请先安装Maven"
exit 1
fi
if ! command -v npm &> /dev/null; then
log_error "本地未安装Node.js,请先安装Node.js"
exit 1
fi
# 执行部署步骤
check_server_connection
create_server_directories
install_base_environment
install_java
install_maven
install_nodejs
install_mysql
install_redis
install_nacos
# 本地构建
build_backend_services
build_frontend
# 部署到服务器
upload_build_artifacts
initialize_database
create_docker_compose
create_dockerfiles
configure_nginx
start_docker_services
create_deployment_config
# 验证部署
health_check
show_deployment_result
}
# 处理命令行参数
case "${1:-}" in
"build")
log_info "仅构建应用..."
build_backend_services
build_frontend
;;
"deploy-only")
log_info "仅部署到服务器(跳过构建)..."
check_server_connection
upload_build_artifacts
start_docker_services
health_check
;;
"health")
log_info "执行健康检查..."
check_server_connection
health_check
;;
*)
main
;;
esac