2026-01-27 11:36:24 +08:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
|
|
# 短信验证码功能部署脚本
|
|
|
|
|
|
# 用途:自动化部署短信验证码功能
|
|
|
|
|
|
|
|
|
|
|
|
set -e # 遇到错误立即退出
|
|
|
|
|
|
|
|
|
|
|
|
# 颜色定义
|
|
|
|
|
|
RED='\033[0;31m'
|
|
|
|
|
|
GREEN='\033[0;32m'
|
|
|
|
|
|
YELLOW='\033[1;33m'
|
|
|
|
|
|
BLUE='\033[0;34m'
|
|
|
|
|
|
NC='\033[0m' # No Color
|
|
|
|
|
|
|
|
|
|
|
|
# 打印函数
|
|
|
|
|
|
print_header() {
|
|
|
|
|
|
echo -e "\n${BLUE}========================================${NC}"
|
|
|
|
|
|
echo -e "${BLUE}$1${NC}"
|
|
|
|
|
|
echo -e "${BLUE}========================================${NC}\n"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_success() {
|
|
|
|
|
|
echo -e "${GREEN}✓ $1${NC}"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_error() {
|
|
|
|
|
|
echo -e "${RED}✗ $1${NC}"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_warning() {
|
|
|
|
|
|
echo -e "${YELLOW}⚠ $1${NC}"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print_info() {
|
|
|
|
|
|
echo -e "${BLUE}ℹ $1${NC}"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查命令是否存在
|
|
|
|
|
|
check_command() {
|
|
|
|
|
|
if ! command -v $1 &> /dev/null; then
|
|
|
|
|
|
print_error "$1 未安装"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
print_success "$1 已安装"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 检查环境变量
|
|
|
|
|
|
check_env_var() {
|
|
|
|
|
|
if [ -z "${!1}" ]; then
|
|
|
|
|
|
print_error "环境变量 $1 未设置"
|
|
|
|
|
|
return 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
print_success "环境变量 $1 已设置"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 主函数
|
|
|
|
|
|
main() {
|
|
|
|
|
|
print_header "短信验证码功能部署脚本"
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 检查前置条件
|
|
|
|
|
|
print_header "1. 检查前置条件"
|
|
|
|
|
|
|
|
|
|
|
|
check_command "python3" || exit 1
|
|
|
|
|
|
check_command "pip3" || exit 1
|
|
|
|
|
|
check_command "psql" || print_warning "psql 未安装,将跳过数据库迁移"
|
|
|
|
|
|
check_command "redis-cli" || print_warning "redis-cli 未安装,请确保Redis服务正在运行"
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 检查环境变量
|
|
|
|
|
|
print_header "2. 检查环境变量"
|
|
|
|
|
|
|
|
|
|
|
|
if [ -f ".env.production" ]; then
|
|
|
|
|
|
print_success "找到 .env.production 文件"
|
|
|
|
|
|
source .env.production
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error ".env.production 文件不存在"
|
|
|
|
|
|
print_info "请创建 .env.production 文件并配置必要的环境变量"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 检查必要的环境变量
|
|
|
|
|
|
REQUIRED_VARS=(
|
|
|
|
|
|
"DATABASE_URL"
|
|
|
|
|
|
"REDIS_URL"
|
|
|
|
|
|
"JWT_SECRET_KEY"
|
|
|
|
|
|
"TENCENT_SMS_SECRET_ID"
|
|
|
|
|
|
"TENCENT_SMS_SECRET_KEY"
|
|
|
|
|
|
"TENCENT_SMS_SDK_APP_ID"
|
|
|
|
|
|
"TENCENT_SMS_SIGN_NAME"
|
|
|
|
|
|
"TENCENT_SMS_TEMPLATE_ID"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
ALL_VARS_SET=true
|
|
|
|
|
|
for var in "${REQUIRED_VARS[@]}"; do
|
|
|
|
|
|
check_env_var "$var" || ALL_VARS_SET=false
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
if [ "$ALL_VARS_SET" = false ]; then
|
|
|
|
|
|
print_error "部分环境变量未设置,请检查 .env.production 文件"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 安装依赖
|
|
|
|
|
|
print_header "3. 安装Python依赖"
|
|
|
|
|
|
|
|
|
|
|
|
if [ -f "requirements.txt" ]; then
|
|
|
|
|
|
print_info "正在安装依赖..."
|
|
|
|
|
|
pip3 install -r requirements.txt
|
|
|
|
|
|
print_success "依赖安装完成"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "requirements.txt 文件不存在"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 数据库迁移
|
|
|
|
|
|
print_header "4. 执行数据库迁移"
|
|
|
|
|
|
|
|
|
|
|
|
if command -v psql &> /dev/null; then
|
|
|
|
|
|
read -p "是否执行数据库迁移? (y/n): " -n 1 -r
|
|
|
|
|
|
echo
|
|
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
|
|
|
|
if [ -f "migrations/add_sms_verification.sql" ]; then
|
|
|
|
|
|
print_info "正在执行数据库迁移..."
|
|
|
|
|
|
|
|
|
|
|
|
# 从DATABASE_URL提取数据库连接信息
|
|
|
|
|
|
# 格式: postgresql://user:password@host:port/database
|
|
|
|
|
|
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
|
|
|
|
|
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
|
|
|
|
|
|
|
|
|
|
|
if [ -z "$DB_USER" ] || [ -z "$DB_NAME" ]; then
|
|
|
|
|
|
print_warning "无法从DATABASE_URL解析数据库信息"
|
|
|
|
|
|
print_info "请手动执行: psql -U <user> -d <database> -f migrations/add_sms_verification.sql"
|
|
|
|
|
|
else
|
|
|
|
|
|
psql -U "$DB_USER" -d "$DB_NAME" -f migrations/add_sms_verification.sql
|
|
|
|
|
|
print_success "数据库迁移完成"
|
|
|
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "迁移脚本不存在: migrations/add_sms_verification.sql"
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
print_warning "跳过数据库迁移"
|
|
|
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
print_warning "psql 未安装,跳过数据库迁移"
|
|
|
|
|
|
print_info "请手动执行: psql -U <user> -d <database> -f migrations/add_sms_verification.sql"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 验证部署
|
|
|
|
|
|
print_header "5. 验证部署"
|
|
|
|
|
|
|
|
|
|
|
|
print_info "正在验证腾讯云SDK..."
|
|
|
|
|
|
python3 -c "from tencentcloud.sms.v20210111 import sms_client; print('腾讯云SDK验证成功')" && \
|
|
|
|
|
|
print_success "腾讯云SDK验证通过" || \
|
|
|
|
|
|
print_error "腾讯云SDK验证失败"
|
|
|
|
|
|
|
|
|
|
|
|
# 6. 测试连接
|
|
|
|
|
|
print_header "6. 测试服务连接"
|
|
|
|
|
|
|
|
|
|
|
|
read -p "是否启动服务并测试? (y/n): " -n 1 -r
|
|
|
|
|
|
echo
|
|
|
|
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
|
|
|
|
print_info "正在启动服务..."
|
|
|
|
|
|
|
|
|
|
|
|
# 在后台启动服务
|
|
|
|
|
|
python3 main.py &
|
|
|
|
|
|
SERVER_PID=$!
|
|
|
|
|
|
|
|
|
|
|
|
print_info "服务PID: $SERVER_PID"
|
|
|
|
|
|
print_info "等待服务启动..."
|
|
|
|
|
|
sleep 5
|
|
|
|
|
|
|
|
|
|
|
|
# 测试健康检查
|
|
|
|
|
|
print_info "测试健康检查..."
|
|
|
|
|
|
if curl -s http://localhost:8000/health > /dev/null; then
|
|
|
|
|
|
print_success "健康检查通过"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "健康检查失败"
|
|
|
|
|
|
kill $SERVER_PID 2>/dev/null || true
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 测试发送验证码API
|
|
|
|
|
|
print_info "测试发送验证码API..."
|
|
|
|
|
|
read -p "请输入测试手机号 (或按Enter跳过): " TEST_PHONE
|
|
|
|
|
|
|
|
|
|
|
|
if [ -n "$TEST_PHONE" ]; then
|
|
|
|
|
|
RESPONSE=$(curl -s -X POST http://localhost:8000/api/auth/sms/send \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d "{\"phone\":\"$TEST_PHONE\",\"purpose\":\"register\"}")
|
|
|
|
|
|
|
|
|
|
|
|
if echo "$RESPONSE" | grep -q "验证码已发送"; then
|
|
|
|
|
|
print_success "验证码发送成功"
|
|
|
|
|
|
print_info "响应: $RESPONSE"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_error "验证码发送失败"
|
|
|
|
|
|
print_info "响应: $RESPONSE"
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 停止测试服务
|
|
|
|
|
|
print_info "停止测试服务..."
|
|
|
|
|
|
kill $SERVER_PID 2>/dev/null || true
|
|
|
|
|
|
print_success "测试服务已停止"
|
|
|
|
|
|
else
|
|
|
|
|
|
print_warning "跳过服务测试"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# 7. 部署完成
|
|
|
|
|
|
print_header "部署完成"
|
|
|
|
|
|
|
|
|
|
|
|
print_success "短信验证码功能部署完成!"
|
|
|
|
|
|
echo
|
|
|
|
|
|
print_info "后续步骤:"
|
2026-03-25 17:40:04 +08:00
|
|
|
|
echo " 1. 使用 Docker 部署: docker compose up -d"
|
2026-01-27 11:36:24 +08:00
|
|
|
|
echo " 2. 或使用 Systemd 部署: sudo systemctl start life-echo-api"
|
2026-03-25 17:40:04 +08:00
|
|
|
|
echo " 3. 查看日志: docker compose logs -f 或 journalctl -u life-echo-api -f"
|
2026-01-27 11:36:24 +08:00
|
|
|
|
echo " 4. 运行测试: python test_sms_verification.py"
|
|
|
|
|
|
echo " 5. 查看部署文档: docs/部署指南.md"
|
|
|
|
|
|
echo
|
|
|
|
|
|
print_warning "重要提示:"
|
|
|
|
|
|
echo " - 请确保已配置防火墙和SSL证书"
|
|
|
|
|
|
echo " - 请配置日志监控和告警"
|
|
|
|
|
|
echo " - 请设置数据库自动备份"
|
|
|
|
|
|
echo " - 请妥善保管API密钥,不要泄露"
|
|
|
|
|
|
echo
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 执行主函数
|
|
|
|
|
|
main
|