209 lines
6.0 KiB
Bash
Executable File
209 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ============================================================
|
||
# 蝶雅采购智能体平台 - 一键部署脚本
|
||
# 用法:
|
||
# bash deploy.sh # 标准部署(安装依赖 + 启动)
|
||
# bash deploy.sh --db-only # 仅部署数据库
|
||
# bash deploy.sh --app-only # 仅部署应用
|
||
# bash deploy.sh --help # 查看帮助
|
||
# ============================================================
|
||
set -euo pipefail
|
||
|
||
# ---------- 配置区(部署前按需修改)----------
|
||
DB_USER="dy_app"
|
||
DB_PASS="***"
|
||
DB_NAME="dy_data"
|
||
DB_HOST="127.0.0.1"
|
||
DB_PORT=3306
|
||
|
||
APP_PORT=18888
|
||
APP_HOST="0.0.0.0"
|
||
|
||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
# ============================================
|
||
|
||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||
info() { echo -e "${CYAN}[INFO]${NC} $*"; }
|
||
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
|
||
|
||
show_help() {
|
||
sed -n '2,10p' "$0"
|
||
exit 0
|
||
}
|
||
|
||
# ---------- 1. 环境检测 ----------
|
||
check_env() {
|
||
info "检测系统环境..."
|
||
|
||
# Python
|
||
if command -v python3 &>/dev/null; then
|
||
ok "Python3: $(python3 --version)"
|
||
else
|
||
err "需要 Python3,请先安装: sudo apt install python3 python3-pip python3-venv"
|
||
fi
|
||
|
||
# MySQL
|
||
if command -v mysql &>/dev/null; then
|
||
ok "MySQL: $(mysql --version | head -c 50)"
|
||
else
|
||
err "需要 MySQL,请先安装: sudo apt install mysql-server"
|
||
fi
|
||
|
||
# pip
|
||
if command -v pip3 &>/dev/null; then
|
||
ok "pip3: $(pip3 --version | head -c 40)"
|
||
fi
|
||
|
||
info "环境检测通过"
|
||
}
|
||
|
||
# ---------- 2. 配置数据库 ----------
|
||
setup_db() {
|
||
info "配置数据库..."
|
||
|
||
# 创建数据库
|
||
sudo mysql -e "CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || {
|
||
mysql -e "CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || warn "无法创建数据库,请手动执行: CREATE DATABASE ${DB_NAME} ..."
|
||
}
|
||
|
||
# 创建用户授权
|
||
sudo mysql -e "
|
||
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
|
||
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||
FLUSH PRIVILEGES;
|
||
" 2>/dev/null || warn "数据库用户配置失败,请手动创建用户"
|
||
|
||
ok "数据库 ${DB_NAME} 就绪"
|
||
|
||
# 导入数据
|
||
local dump_file="${PROJECT_DIR}/dy_data_backup.sql"
|
||
if [ -f "$dump_file" ]; then
|
||
info "导入数据备份文件..."
|
||
mysql -u"${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" < "$dump_file"
|
||
ok "数据导入完成"
|
||
else
|
||
warn "未找到数据备份文件 ${dump_file}"
|
||
warn "部署后数据库为空,需要先导入数据才能使用"
|
||
info "在有数据的服务器上执行导出:"
|
||
info " mysqldump -u ${DB_USER} -p'${DB_PASS}' ${DB_NAME} > dy_data_backup.sql"
|
||
fi
|
||
}
|
||
|
||
# ---------- 3. 配置 Python 环境 ----------
|
||
setup_python_env() {
|
||
info "配置 Python 虚拟环境..."
|
||
|
||
if [ -d "${PROJECT_DIR}/venv" ]; then
|
||
warn "虚拟环境已存在,跳过创建"
|
||
else
|
||
python3 -m venv "${PROJECT_DIR}/venv"
|
||
ok "虚拟环境已创建"
|
||
fi
|
||
|
||
source "${PROJECT_DIR}/venv/bin/activate"
|
||
|
||
info "安装 Python 依赖..."
|
||
pip install --quiet --upgrade pip
|
||
pip install --quiet \
|
||
flask==3.1.3 \
|
||
pymysql==1.2.0 \
|
||
gunicorn==26.0.0 \
|
||
gevent==26.5.0 \
|
||
openpyxl==3.1.5 \
|
||
DBUtils==3.1.2 \
|
||
flask-cors==6.0.2 \
|
||
Flask-Login==0.6.3 \
|
||
Flask-Compress==1.24
|
||
|
||
ok "Python 依赖安装完成"
|
||
}
|
||
|
||
# ---------- 4. 启动服务 ----------
|
||
start_app() {
|
||
info "启动应用服务..."
|
||
|
||
# 先停掉旧的
|
||
kill "$(lsof -t -i:${APP_PORT})" 2>/dev/null || true
|
||
sleep 1
|
||
|
||
cd "${PROJECT_DIR}"
|
||
|
||
# 确保 logs 目录存在
|
||
mkdir -p logs
|
||
|
||
# 生产模式:Gunicorn
|
||
nohup "${PROJECT_DIR}/venv/bin/gunicorn" \
|
||
-w 4 \
|
||
-b "${APP_HOST}:${APP_PORT}" \
|
||
--timeout 120 \
|
||
--access-logfile logs/access.log \
|
||
--error-logfile logs/error.log \
|
||
app:app > /dev/null 2>&1 &
|
||
|
||
sleep 2
|
||
|
||
if curl -s "http://127.0.0.1:${APP_PORT}/" > /dev/null 2>&1; then
|
||
ok "服务已启动 → http://${APP_HOST}:${APP_PORT}"
|
||
else
|
||
warn "服务启动可能尚未完成,请稍后检查: curl http://127.0.0.1:${APP_PORT}"
|
||
fi
|
||
}
|
||
|
||
# ---------- 5. 配置定时任务 ----------
|
||
setup_cron() {
|
||
info "配置定时更新任务..."
|
||
|
||
local cron_job="0 7,12,18 * * * cd ${PROJECT_DIR} && python3 auto_update.py >> logs/auto_update.log 2>&1"
|
||
local existing
|
||
existing="$(crontab -l 2>/dev/null || true)"
|
||
|
||
if echo "$existing" | grep -q "auto_update.py"; then
|
||
warn "定时任务已存在,跳过"
|
||
else
|
||
(echo "$existing"; echo "$cron_job") | crontab -
|
||
ok "定时任务已配置(每日 7:00 / 12:00 / 18:00)"
|
||
fi
|
||
}
|
||
|
||
# ---------- 6. 输出部署总结 ----------
|
||
print_summary() {
|
||
echo ""
|
||
echo -e "${GREEN}=================================${NC}"
|
||
echo -e "${GREEN} 蝶雅采购智能体平台部署完成${NC}"
|
||
echo -e "${GREEN}=================================${NC}"
|
||
echo ""
|
||
echo " 访问地址: http://服务器IP:${APP_PORT}"
|
||
echo " 默认账号: 甘旭东 / ***"
|
||
echo " 项目目录: ${PROJECT_DIR}"
|
||
echo " 启动方式: bash run.py # 开发模式"
|
||
echo " bash run.py --prod # 生产模式"
|
||
echo ""
|
||
echo " 定时更新: 每日 7:00 / 12:00 / 18:00"
|
||
echo " 日志文件: logs/app.log"
|
||
echo ""
|
||
echo " 如需从旧服务器迁移数据:"
|
||
echo " 1. 旧服务器导出: mysqldump -u dy_app -p'***' dy_data > dy_data_backup.sql"
|
||
echo " 2. 放到本项目目录下"
|
||
echo " 3. 重新运行部署: bash deploy.sh"
|
||
echo ""
|
||
}
|
||
|
||
# ---------- 主流程 ----------
|
||
main() {
|
||
case "${1:-}" in
|
||
--help|-h) show_help ;;
|
||
--db-only) check_env; setup_db; print_summary ;;
|
||
--app-only) check_env; setup_python_env; start_app; print_summary ;;
|
||
*) check_env
|
||
setup_db
|
||
setup_python_env
|
||
start_app
|
||
setup_cron
|
||
print_summary ;;
|
||
esac
|
||
}
|
||
|
||
main "$@"
|