247 lines
5.5 KiB
Bash
Executable File
247 lines
5.5 KiB
Bash
Executable File
#!/bin/bash
|
||
# 智能项目定价模型 - 生产环境部署脚本
|
||
# 遵循瑞小美部署规范
|
||
|
||
set -e
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
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"
|
||
}
|
||
|
||
# 检查必要命令
|
||
check_requirements() {
|
||
log_info "检查环境依赖..."
|
||
|
||
local requirements=("docker" "docker-compose")
|
||
for cmd in "${requirements[@]}"; do
|
||
if ! command -v $cmd &> /dev/null; then
|
||
log_error "$cmd 未安装"
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
log_info "环境检查通过"
|
||
}
|
||
|
||
# 检查 .env 文件
|
||
check_env_file() {
|
||
log_info "检查环境配置..."
|
||
|
||
if [ ! -f ".env" ]; then
|
||
log_error ".env 文件不存在,请从 env.example 复制并配置"
|
||
log_info "执行: cp env.example .env && chmod 600 .env"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 .env 文件权限
|
||
local perms=$(stat -c %a .env 2>/dev/null || stat -f %OLp .env 2>/dev/null)
|
||
if [ "$perms" != "600" ]; then
|
||
log_warn ".env 文件权限不是 600,正在修复..."
|
||
chmod 600 .env
|
||
fi
|
||
|
||
# 检查必要配置项
|
||
local required_vars=("DATABASE_URL" "MYSQL_ROOT_PASSWORD" "MYSQL_PASSWORD" "SECRET_KEY")
|
||
source .env
|
||
|
||
for var in "${required_vars[@]}"; do
|
||
if [ -z "${!var}" ]; then
|
||
log_error "缺少必要配置: $var"
|
||
exit 1
|
||
fi
|
||
done
|
||
|
||
# 检查是否修改了默认密码
|
||
if [[ "$SECRET_KEY" == *"change-in-production"* ]]; then
|
||
log_error "请修改 SECRET_KEY 为随机字符串"
|
||
exit 1
|
||
fi
|
||
|
||
log_info "配置检查通过"
|
||
}
|
||
|
||
# 检查网络
|
||
check_network() {
|
||
log_info "检查 Docker 网络..."
|
||
|
||
# 检查 scrm_network 是否存在
|
||
if ! docker network ls | grep -q "scrm_network"; then
|
||
log_info "创建 scrm_network 网络..."
|
||
docker network create scrm_network
|
||
fi
|
||
|
||
log_info "网络检查通过"
|
||
}
|
||
|
||
# 拉取/构建镜像
|
||
build_images() {
|
||
log_info "构建 Docker 镜像..."
|
||
|
||
docker-compose build --no-cache
|
||
|
||
log_info "镜像构建完成"
|
||
}
|
||
|
||
# 停止旧服务
|
||
stop_services() {
|
||
log_info "停止旧服务..."
|
||
|
||
docker-compose down --remove-orphans 2>/dev/null || true
|
||
|
||
log_info "旧服务已停止"
|
||
}
|
||
|
||
# 启动服务
|
||
start_services() {
|
||
log_info "启动服务..."
|
||
|
||
docker-compose up -d
|
||
|
||
log_info "服务启动中..."
|
||
}
|
||
|
||
# 等待服务就绪
|
||
wait_for_services() {
|
||
log_info "等待服务就绪..."
|
||
|
||
local max_attempts=30
|
||
local attempt=0
|
||
|
||
# 等待后端健康检查
|
||
while [ $attempt -lt $max_attempts ]; do
|
||
if docker-compose exec -T pricing-backend curl -sf http://localhost:8000/health > /dev/null 2>&1; then
|
||
log_info "后端服务就绪"
|
||
break
|
||
fi
|
||
attempt=$((attempt + 1))
|
||
echo -n "."
|
||
sleep 2
|
||
done
|
||
|
||
if [ $attempt -eq $max_attempts ]; then
|
||
log_error "服务启动超时"
|
||
docker-compose logs --tail=50
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 刷新 Nginx DNS 缓存
|
||
refresh_nginx() {
|
||
log_info "刷新 Nginx DNS 缓存..."
|
||
|
||
# 检查 nginx_proxy 容器是否存在
|
||
if docker ps | grep -q "nginx_proxy"; then
|
||
docker exec nginx_proxy nginx -s reload 2>/dev/null || log_warn "Nginx reload 失败,请手动执行"
|
||
else
|
||
log_warn "nginx_proxy 容器未运行,请确保 Nginx 配置正确"
|
||
fi
|
||
}
|
||
|
||
# 显示服务状态
|
||
show_status() {
|
||
log_info "服务状态:"
|
||
echo ""
|
||
docker-compose ps
|
||
echo ""
|
||
|
||
log_info "健康检查:"
|
||
curl -sf http://localhost:8000/health 2>/dev/null && echo "" || log_warn "后端服务不可访问"
|
||
|
||
echo ""
|
||
log_info "部署完成!"
|
||
echo ""
|
||
echo "访问地址:"
|
||
echo " - 前端: https://pricing.example.com (需配置 Nginx)"
|
||
echo " - 后端 API: http://localhost:8000"
|
||
echo " - API 文档: http://localhost:8000/docs (仅开发环境)"
|
||
}
|
||
|
||
# 回滚
|
||
rollback() {
|
||
log_warn "执行回滚..."
|
||
docker-compose down
|
||
|
||
# 如果有备份,恢复
|
||
if [ -f ".env.backup" ]; then
|
||
mv .env.backup .env
|
||
fi
|
||
|
||
log_info "回滚完成,请检查日志排查问题"
|
||
}
|
||
|
||
# 主函数
|
||
main() {
|
||
local action="${1:-deploy}"
|
||
|
||
cd "$(dirname "$0")/.."
|
||
|
||
case $action in
|
||
deploy)
|
||
log_info "开始部署智能项目定价模型..."
|
||
echo ""
|
||
|
||
check_requirements
|
||
check_env_file
|
||
check_network
|
||
build_images
|
||
stop_services
|
||
start_services
|
||
wait_for_services
|
||
refresh_nginx
|
||
show_status
|
||
;;
|
||
|
||
restart)
|
||
log_info "重启服务..."
|
||
docker-compose restart
|
||
wait_for_services
|
||
refresh_nginx
|
||
show_status
|
||
;;
|
||
|
||
stop)
|
||
log_info "停止服务..."
|
||
docker-compose down
|
||
log_info "服务已停止"
|
||
;;
|
||
|
||
status)
|
||
show_status
|
||
;;
|
||
|
||
logs)
|
||
docker-compose logs -f --tail=100
|
||
;;
|
||
|
||
rollback)
|
||
rollback
|
||
;;
|
||
|
||
*)
|
||
echo "用法: $0 {deploy|restart|stop|status|logs|rollback}"
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# 捕获错误
|
||
trap 'log_error "部署失败"; exit 1' ERR
|
||
|
||
main "$@"
|