Files
2026-01-31 21:33:06 +08:00

247 lines
5.5 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 "$@"