1028 lines
24 KiB
Bash
Executable File
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 |