Files
happy-life-star/packages/emotion-museum-1.0.0-20250713_111829/deploy.sh
T

1015 lines
26 KiB
Bash
Executable File

#!/bin/bash
# 情绪博物馆测试环境部署脚本
# 作者: EmotionMuseum Team
# 版本: 2.0.0
# 日期: 2025-07-13
# 说明: 完整的测试环境部署脚本,包含环境安装、数据库初始化、服务部署等
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'
# 日志函数
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"
}
log_success() {
echo -e "${PURPLE}[SUCCESS]${NC} $1"
}
log_debug() {
if [ "$DEBUG_MODE" = "true" ]; then
echo -e "${CYAN}[DEBUG]${NC} $1"
fi
}
# 配置变量
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="$SCRIPT_DIR/.env.test"
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.test.yml"
DEBUG_MODE=${DEBUG_MODE:-false}
SKIP_ENV_INSTALL=${SKIP_ENV_INSTALL:-false}
SKIP_DB_INIT=${SKIP_DB_INIT:-false}
# 加载环境变量
load_environment() {
log_step "加载环境配置..."
if [ -f "$ENV_FILE" ]; then
log_info "加载环境配置文件: $ENV_FILE"
set -a
source "$ENV_FILE"
set +a
log_debug "环境变量加载完成"
else
log_warn "环境配置文件不存在: $ENV_FILE"
log_info "使用默认配置"
fi
}
# 显示帮助信息
show_help() {
echo "情绪博物馆测试环境部署脚本"
echo ""
echo "用法: $0 [命令] [选项]"
echo ""
echo "命令:"
echo " install-env 安装基础环境 (Java, Maven, Node.js, Docker等)"
echo " init-db 初始化数据库"
echo " build 构建应用镜像"
echo " deploy 完整部署 (默认)"
echo " start 启动服务"
echo " stop 停止服务"
echo " restart 重启服务"
echo " status 查看服务状态"
echo " logs 查看服务日志"
echo " clean 清理资源"
echo " health 健康检查"
echo " backup 备份数据"
echo " update 更新服务"
echo ""
echo "选项:"
echo " --skip-env 跳过环境安装"
echo " --skip-db 跳过数据库初始化"
echo " --debug 启用调试模式"
echo " --force 强制执行"
echo " -h, --help 显示帮助信息"
echo ""
echo "示例:"
echo " $0 # 完整部署"
echo " $0 deploy --skip-env # 部署但跳过环境安装"
echo " $0 start # 仅启动服务"
echo " $0 logs --debug # 查看日志并启用调试"
echo ""
}
# 检查系统要求
check_requirements() {
log_step "检查系统要求..."
# 检查操作系统
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
log_info "操作系统: Linux"
elif [[ "$OSTYPE" == "darwin"* ]]; then
log_info "操作系统: macOS"
else
log_warn "未测试的操作系统: $OSTYPE"
fi
# 检查必要的命令
local missing_commands=()
if ! command -v docker &> /dev/null; then
missing_commands+=("docker")
fi
if ! command -v docker-compose &> /dev/null; then
missing_commands+=("docker-compose")
fi
if [ ${#missing_commands[@]} -gt 0 ]; then
log_error "缺少必要的命令: ${missing_commands[*]}"
log_info "请运行 './install-environment.sh' 安装基础环境"
exit 1
fi
# 检查Docker服务
if ! docker info &> /dev/null; then
log_error "Docker服务未启动,请启动Docker服务"
exit 1
fi
log_success "系统要求检查通过"
}
# 安装基础环境
install_environment() {
if [ "$SKIP_ENV_INSTALL" = "true" ]; then
log_info "跳过环境安装"
return
fi
log_step "安装基础环境..."
if [ -f "$SCRIPT_DIR/install-environment.sh" ]; then
log_info "执行环境安装脚本..."
chmod +x "$SCRIPT_DIR/install-environment.sh"
"$SCRIPT_DIR/install-environment.sh"
log_success "基础环境安装完成"
else
log_error "环境安装脚本不存在: $SCRIPT_DIR/install-environment.sh"
exit 1
fi
}
# 初始化数据库
initialize_database() {
if [ "$SKIP_DB_INIT" = "true" ]; then
log_info "跳过数据库初始化"
return
fi
log_step "初始化数据库..."
if [ -f "$SCRIPT_DIR/init-database.sh" ]; then
log_info "执行数据库初始化脚本..."
chmod +x "$SCRIPT_DIR/init-database.sh"
"$SCRIPT_DIR/init-database.sh"
log_success "数据库初始化完成"
else
log_error "数据库初始化脚本不存在: $SCRIPT_DIR/init-database.sh"
exit 1
fi
}
# 创建必要的目录
create_directories() {
log_step "创建部署目录..."
local directories=(
"${DEPLOY_PATH:-/data/emotion-museum}"
"${LOG_PATH:-/data/logs/emotion-museum}"
"${UPLOAD_PATH:-/data/uploads/emotion-museum}"
"${BACKUP_PATH:-/data/backups/emotion-museum}"
"./data/mysql"
"./data/redis"
"./data/nacos"
"./deploy/mysql/conf.d"
"./deploy/redis"
"./deploy/nginx/conf.d"
"./deploy/nginx/ssl"
"./logs"
)
for dir in "${directories[@]}"; do
if [ ! -d "$dir" ]; then
log_debug "创建目录: $dir"
mkdir -p "$dir"
fi
done
# 设置目录权限
chmod 755 ./data ./deploy ./logs
log_success "目录创建完成"
}
# 生成配置文件
generate_configs() {
log_step "生成配置文件..."
# 生成MySQL配置
if [ ! -f "deploy/mysql/conf.d/my.cnf" ]; then
log_debug "生成MySQL配置文件"
cat > deploy/mysql/conf.d/my.cnf << 'EOF'
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-time-zone='+8:00'
max_connections=1000
max_allowed_packet=64M
innodb_buffer_pool_size=512M
innodb_log_file_size=256M
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
binlog_expire_logs_seconds=604800
max_binlog_size=100M
EOF
fi
# 生成Redis配置
if [ ! -f "deploy/redis/redis.conf" ]; then
log_debug "生成Redis配置文件"
cat > deploy/redis/redis.conf << 'EOF'
bind 0.0.0.0
port 6379
timeout 300
tcp-keepalive 60
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
EOF
fi
# 生成Nginx配置
if [ ! -f "deploy/nginx/conf.d/default.conf" ]; then
log_debug "生成Nginx配置文件"
cat > deploy/nginx/conf.d/default.conf << EOF
# 情绪博物馆测试环境Nginx配置
# 适用于Docker Compose部署
server {
listen 80;
server_name ${SERVER_IP:-localhost};
# 日志配置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 前端静态文件 - 代理到前端容器
location / {
proxy_pass http://emotion-web:80;
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;
# 超时设置
proxy_connect_timeout 10s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;
}
# API网关 - 代理到网关容器
location /api/ {
proxy_pass http://emotion-gateway: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;
# 超时设置
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 缓存控制
proxy_cache_bypass \$http_upgrade;
proxy_no_cache \$http_upgrade;
}
# WebSocket支持
location /ws/ {
proxy_pass http://emotion-gateway:9000/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
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 /health {
proxy_pass http://emotion-gateway:9000/actuator/health;
proxy_set_header Host \$host;
}
# Nginx健康检查
location /nginx-health {
access_log off;
return 200 "healthy\\n";
add_header Content-Type text/plain;
}
# 静态资源缓存优化
location ~* \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)\$ {
proxy_pass http://emotion-web:80;
expires 30d;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
}
# HTML文件不缓存
location ~* \\.(html|htm)\$ {
proxy_pass http://emotion-web:80;
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
# 如果需要支持非Docker部署,可以使用以下配置
# 注释掉上面的配置,启用下面的配置
#
# server {
# listen 80;
# server_name ${SERVER_IP:-localhost};
#
# # API网关 - 代理到宿主机服务
# location /api/ {
# proxy_pass http://localhost:9000/;
# # 或使用服务器IP: proxy_pass http://${SERVER_IP:-localhost}: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 / {
# root /data/www/emotion-museum;
# index index.html index.htm;
# try_files \$uri \$uri/ /index.html;
# }
# }
EOF
fi
log_success "配置文件生成完成"
}
# 生成配置文件
generate_configs() {
log_step "生成配置文件..."
# MySQL配置
if [ ! -f "deploy/mysql/conf.d/my.cnf" ]; then
cat > deploy/mysql/conf.d/my.cnf << 'EOF'
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-time-zone='+8:00'
max_connections=1000
max_allowed_packet=64M
innodb_buffer_pool_size=512M
innodb_log_file_size=256M
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
EOF
log_info "MySQL配置文件已生成"
fi
# Redis配置
if [ ! -f "deploy/redis/redis.conf" ]; then
cat > deploy/redis/redis.conf << 'EOF'
bind 0.0.0.0
port 6379
timeout 300
tcp-keepalive 60
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
EOF
log_info "Redis配置文件已生成"
fi
}
# 构建镜像
build_images() {
log_step "构建Docker镜像..."
# 检查Docker Compose文件
if [ ! -f "$COMPOSE_FILE" ]; then
log_warn "Docker Compose文件不存在: $COMPOSE_FILE"
log_info "使用默认配置文件: docker-compose.yml"
COMPOSE_FILE="docker-compose.yml"
fi
log_info "使用配置文件: $COMPOSE_FILE"
# 构建后端服务镜像
log_info "构建后端服务镜像..."
local backend_services=("gateway" "ai-service" "user-service")
for service in "${backend_services[@]}"; do
log_debug "构建服务: $service"
if docker-compose -f "$COMPOSE_FILE" build "$service"; then
log_success "$service 镜像构建成功"
else
log_error "$service 镜像构建失败"
exit 1
fi
done
# 构建前端应用镜像
log_info "构建前端应用镜像..."
if docker-compose -f "$COMPOSE_FILE" build web; then
log_success "✅ 前端应用镜像构建成功"
else
log_error "❌ 前端应用镜像构建失败"
exit 1
fi
log_success "所有镜像构建完成"
}
# 启动Nacos服务
start_nacos() {
log_step "启动Nacos注册中心..."
# 检查Nacos容器是否已存在
if docker ps -a | grep -q "emotion-nacos"; then
if docker ps | grep -q "emotion-nacos"; then
log_info "Nacos容器已在运行"
return
else
log_info "启动已存在的Nacos容器"
docker start emotion-nacos
fi
else
log_info "创建新的Nacos容器"
docker run -d \
--name emotion-nacos \
--restart unless-stopped \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=${MYSQL_HOST:-localhost} \
-e MYSQL_SERVICE_DB_NAME=${NACOS_DATABASE:-nacos_config} \
-e MYSQL_SERVICE_PORT=${MYSQL_PORT:-3306} \
-e MYSQL_SERVICE_USER=${MYSQL_USERNAME:-emotion} \
-e MYSQL_SERVICE_PASSWORD=${MYSQL_PASSWORD:-emotion123} \
-e MYSQL_SERVICE_DB_PARAM="characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true" \
-e JVM_XMS=${JVM_XMS:-512m} \
-e JVM_XMX=${JVM_XMX:-1024m} \
-e JVM_XMN=${JVM_XMN:-256m} \
-e TZ=${TZ:-Asia/Shanghai} \
-p 8848:8848 \
-p 9848:9848 \
-v $(pwd)/data/nacos:/home/nacos/data \
-v $(pwd)/logs:/home/nacos/logs \
--network ${NETWORK_NAME:-emotion-test-network} \
nacos/nacos-server:v2.2.0
fi
# 等待Nacos启动
log_info "等待Nacos服务启动..."
local retry_count=0
local max_retries=30
while [ $retry_count -lt $max_retries ]; do
if curl -s http://localhost:8848/nacos/v1/ns/operator/metrics &> /dev/null; then
log_success "Nacos服务已就绪"
break
fi
retry_count=$((retry_count + 1))
log_debug "等待Nacos服务就绪... ($retry_count/$max_retries)"
sleep 2
done
if [ $retry_count -eq $max_retries ]; then
log_error "Nacos服务启动超时"
exit 1
fi
}
# 启动服务
start_services() {
log_step "启动服务..."
# 创建Docker网络
if ! docker network ls | grep -q "${NETWORK_NAME:-emotion-test-network}"; then
log_info "创建Docker网络: ${NETWORK_NAME:-emotion-test-network}"
docker network create --driver bridge \
--subnet=${SUBNET:-172.20.0.0/16} \
--gateway=${GATEWAY_IP:-172.20.0.1} \
${NETWORK_NAME:-emotion-test-network}
fi
# 启动基础服务
log_info "启动基础服务 (MySQL, Redis)..."
docker-compose -f "$COMPOSE_FILE" up -d mysql redis
# 等待基础服务启动
log_info "等待基础服务启动完成..."
sleep 15
# 启动Nacos
start_nacos
# 等待Nacos完全启动
sleep 10
# 启动应用服务
log_info "启动应用服务..."
local app_services=("gateway" "user-service" "ai-service")
for service in "${app_services[@]}"; do
log_debug "启动服务: $service"
docker-compose -f "$COMPOSE_FILE" up -d "$service"
sleep 5
done
# 等待应用服务启动
log_info "等待应用服务启动完成..."
sleep 20
# 启动前端和Nginx
log_info "启动前端和Nginx..."
docker-compose -f "$COMPOSE_FILE" up -d web nginx
log_success "所有服务启动完成"
}
# 停止服务
stop_services() {
log_step "停止服务..."
if [ -f "$COMPOSE_FILE" ]; then
docker-compose -f "$COMPOSE_FILE" down
else
docker-compose down
fi
# 停止独立的Nacos容器
if docker ps | grep -q "emotion-nacos"; then
log_info "停止Nacos容器..."
docker stop emotion-nacos
fi
log_success "服务停止完成"
}
# 重启服务
restart_services() {
local service_name=${1:-}
if [ -n "$service_name" ]; then
log_step "重启服务: $service_name"
if [ "$service_name" = "nacos" ]; then
docker restart emotion-nacos
else
docker-compose -f "$COMPOSE_FILE" restart "$service_name"
fi
else
log_step "重启所有服务..."
stop_services
sleep 3
start_services
fi
log_success "服务重启完成"
}
# 检查服务状态
check_services() {
log_step "检查服务状态..."
echo ""
echo "=== Docker容器状态 ==="
if [ -f "$COMPOSE_FILE" ]; then
docker-compose -f "$COMPOSE_FILE" ps
else
docker-compose ps
fi
# 检查独立的Nacos容器
if docker ps -a | grep -q "emotion-nacos"; then
echo ""
echo "=== Nacos容器状态 ==="
docker ps -a --filter name=emotion-nacos --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
fi
echo ""
# 检查关键服务健康状态
log_info "检查服务健康状态..."
local all_healthy=true
# 检查MySQL
if docker exec emotion-mysql mysqladmin ping -h localhost -u root -p${MYSQL_ROOT_PASSWORD:-123456} &> /dev/null; then
log_success "✅ MySQL服务正常"
else
log_error "❌ MySQL服务异常"
all_healthy=false
fi
# 检查Redis
if docker exec emotion-redis redis-cli ping | grep -q PONG; then
log_success "✅ Redis服务正常"
else
log_error "❌ Redis服务异常"
all_healthy=false
fi
# 检查Nacos
if curl -s http://localhost:8848/nacos/v1/ns/operator/metrics &> /dev/null; then
log_success "✅ Nacos服务正常"
else
log_error "❌ Nacos服务异常"
all_healthy=false
fi
# 检查网关
if curl -s http://localhost:${GATEWAY_PORT:-9000}/actuator/health &> /dev/null; then
log_success "✅ 网关服务正常"
else
log_error "❌ 网关服务异常"
all_healthy=false
fi
# 检查用户服务
if curl -s http://localhost:${USER_SERVICE_PORT:-9001}/actuator/health &> /dev/null; then
log_success "✅ 用户服务正常"
else
log_error "❌ 用户服务异常"
all_healthy=false
fi
# 检查AI服务
if curl -s http://localhost:${AI_SERVICE_PORT:-9002}/actuator/health &> /dev/null; then
log_success "✅ AI服务正常"
else
log_error "❌ AI服务异常"
all_healthy=false
fi
# 检查前端服务
if curl -s http://localhost:${WEB_PORT:-3000}/health &> /dev/null || curl -s http://localhost:${WEB_PORT:-3000}/ &> /dev/null; then
log_success "✅ 前端服务正常"
else
log_error "❌ 前端服务异常"
all_healthy=false
fi
# 检查Nginx
if curl -s http://localhost:${NGINX_PORT:-80}/health &> /dev/null || curl -s http://localhost:${NGINX_PORT:-80}/ &> /dev/null; then
log_success "✅ Nginx服务正常"
else
log_error "❌ Nginx服务异常"
all_healthy=false
fi
echo ""
if $all_healthy; then
log_success "🎉 所有服务健康检查通过"
else
log_warn "⚠️ 部分服务存在问题,请检查日志"
fi
# 显示资源使用情况
echo ""
echo "=== 资源使用情况 ==="
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
}
# 查看日志
show_logs() {
local service_name=${1:-}
local follow_flag=${2:-}
if [ -n "$service_name" ]; then
log_info "查看服务日志: $service_name"
if [ "$service_name" = "nacos" ]; then
docker logs $follow_flag emotion-nacos
else
docker-compose -f "$COMPOSE_FILE" logs $follow_flag "$service_name"
fi
else
log_info "查看所有服务日志"
docker-compose -f "$COMPOSE_FILE" logs $follow_flag
# 显示Nacos日志
if docker ps | grep -q "emotion-nacos"; then
echo ""
echo "=== Nacos日志 ==="
docker logs --tail 50 emotion-nacos
fi
fi
}
# 备份数据
backup_data() {
log_step "备份数据..."
local backup_dir="${BACKUP_PATH:-./backups}/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"
# 备份MySQL数据
log_info "备份MySQL数据..."
docker exec emotion-mysql mysqldump -u root -p${MYSQL_ROOT_PASSWORD:-123456} --all-databases > "$backup_dir/mysql_backup.sql"
# 备份Redis数据
log_info "备份Redis数据..."
docker exec emotion-redis redis-cli BGSAVE
sleep 2
docker cp emotion-redis:/data/dump.rdb "$backup_dir/redis_backup.rdb"
# 备份Nacos数据
log_info "备份Nacos数据..."
if [ -d "./data/nacos" ]; then
cp -r ./data/nacos "$backup_dir/"
fi
# 备份配置文件
log_info "备份配置文件..."
cp -r deploy "$backup_dir/" 2>/dev/null || true
cp -r backend/config "$backup_dir/" 2>/dev/null || true
cp docker-compose*.yml "$backup_dir/" 2>/dev/null || true
cp .env* "$backup_dir/" 2>/dev/null || true
# 压缩备份
tar -czf "$backup_dir.tar.gz" -C "$(dirname $backup_dir)" "$(basename $backup_dir)"
rm -rf "$backup_dir"
log_success "备份完成: $backup_dir.tar.gz"
}
# 清理资源
clean_resources() {
log_step "清理Docker资源..."
log_warn "此操作将清理未使用的Docker资源"
read -p "是否继续? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
# 清理未使用的镜像
docker image prune -f
# 清理未使用的容器
docker container prune -f
# 清理未使用的网络
docker network prune -f
# 清理未使用的卷(谨慎使用)
# docker volume prune -f
log_success "资源清理完成"
else
log_info "清理操作已取消"
fi
}
# 更新服务
update_services() {
log_step "更新服务..."
# 备份当前数据
log_info "备份当前数据..."
backup_data
# 停止服务
log_info "停止当前服务..."
stop_services
# 重新构建镜像
log_info "重新构建镜像..."
build_images
# 启动服务
log_info "启动更新后的服务..."
start_services
# 健康检查
sleep 10
check_services
log_success "服务更新完成"
}
# 显示访问信息
show_access_info() {
log_step "部署完成!"
local server_ip=${SERVER_IP:-localhost}
local nginx_port=${NGINX_PORT:-80}
local gateway_port=${GATEWAY_PORT:-9000}
echo ""
echo "🎉 情绪博物馆测试环境部署成功!"
echo ""
echo "📱 访问地址:"
echo " 前端应用: http://$server_ip:$nginx_port"
echo " API网关: http://$server_ip:$gateway_port"
echo " Nacos: http://$server_ip:8848/nacos (用户名/密码: nacos/nacos)"
echo ""
echo "🔧 管理命令:"
echo " 查看状态: $0 status"
echo " 查看日志: $0 logs [服务名]"
echo " 重启服务: $0 restart [服务名]"
echo " 停止服务: $0 stop"
echo " 健康检查: $0 health"
echo " 备份数据: $0 backup"
echo ""
echo "📊 监控命令:"
echo " 查看容器: docker ps"
echo " 查看资源: docker stats"
echo " 查看网络: docker network ls"
echo ""
echo "🗄️ 数据库信息:"
echo " MySQL: $server_ip:${MYSQL_PORT:-3306} (用户: ${MYSQL_USERNAME:-emotion})"
echo " Redis: $server_ip:${REDIS_PORT:-6379}"
echo ""
echo "📁 重要路径:"
echo " 日志目录: ${LOG_PATH:-/data/logs/emotion-museum}"
echo " 上传目录: ${UPLOAD_PATH:-/data/uploads/emotion-museum}"
echo " 备份目录: ${BACKUP_PATH:-./backups}"
echo ""
}
# 完整部署流程
full_deploy() {
echo "🚀 开始完整部署情绪博物馆测试环境..."
echo ""
load_environment
check_requirements
install_environment
initialize_database
create_directories
generate_configs
build_images
start_services
echo ""
log_info "等待服务完全启动..."
sleep 15
check_services
show_access_info
log_success "🎉 部署完成!"
}
# 解析命令行参数
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
--skip-env)
SKIP_ENV_INSTALL=true
shift
;;
--skip-db)
SKIP_DB_INIT=true
shift
;;
--debug)
DEBUG_MODE=true
shift
;;
--force)
FORCE_MODE=true
shift
;;
-h|--help)
show_help
exit 0
;;
*)
# 保留其他参数
break
;;
esac
done
}
# 主函数
main() {
# 解析参数
parse_arguments "$@"
# 加载环境变量
load_environment
# 处理命令
case "${1:-}" in
"install-env")
check_requirements
install_environment
;;
"init-db")
check_requirements
initialize_database
;;
"build")
check_requirements
create_directories
generate_configs
build_images
;;
"start")
check_requirements
start_services
check_services
show_access_info
;;
"stop")
stop_services
;;
"restart")
restart_services "$2"
;;
"status")
check_services
;;
"logs")
if [ "$2" = "-f" ] || [ "$2" = "--follow" ]; then
show_logs "$3" "-f"
else
show_logs "$2"
fi
;;
"health")
check_services
;;
"backup")
backup_data
;;
"clean")
clean_resources
;;
"update")
update_services
;;
"deploy")
full_deploy
;;
"-h"|"--help"|"help")
show_help
;;
"")
# 默认执行完整部署
full_deploy
;;
*)
log_error "未知命令: $1"
echo ""
show_help
exit 1
;;
esac
}
# 脚本入口
main "$@"