Files
hospital_performance/spug/deploy-docker-compose.sh
chenqi 4a46e7d2f5 fix(backend): 修正默认数据库用户名及调试模式配置
- 将默认数据库用户名从 your_user 改为 postgresql,明确用户名字段说明
- 修改 .env.example 中 DEBUG 默认为 True,方便本地调试
- 更新 deploy-docker-compose.sh 脚本中 DEBUG 默认值为 True,保持一致性
- 保持数据库连接字符串格式正确,确保环境变量配置一致
2026-02-28 17:53:30 +08:00

218 lines
6.5 KiB
Bash
Raw 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
# Spug 自动部署脚本 - 直接粘贴到 Spug 执行
# 用途:医院绩效考核系统传统部署(非 Docker
# 适用:服务器无法访问 Docker Hub 的情况
set -e
# ==================== 配置参数 ====================
PROJECT_DIR="${SPUG_DEPLOY_DIR:-/data/spug/service/hospital_performance}"
GIT_REPO="${SPUG_GIT_URL:-https://gitea.gentronhealth.com/chenqi/hospital_performance.git}"
GIT_BRANCH="${SPUG_GIT_BRANCH:-main}"
# 服务配置
BACKEND_PORT="${BACKEND_PORT:-5757}"
FRONTEND_PORT="${FRONTEND_PORT:-5758}"
# 环境变量
export DATABASE_HOST="${DATABASE_HOST:-192.168.110.252}"
export DATABASE_PORT="${DATABASE_PORT:-15432}"
export DATABASE_USER="${DATABASE_USER:-postgresql}"
export DATABASE_PASSWORD="${DATABASE_PASSWORD:-Jchl1528}"
export DATABASE_NAME="${DATABASE_NAME:-hospital_performance}"
export SECRET_KEY="${SECRET_KEY:-change-this-secret-key-in-production}"
export DEBUG="${DEBUG:-True}"
# 构建完整的 DATABASE_URL后端使用此变量
export DATABASE_URL="postgresql+asyncpg://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}"
# 日志配置
LOG_FILE="/tmp/spug-deploy-$(date +%Y%m%d_%H%M%S).log"
echo "========================================"
echo "Spug Docker Compose 自动部署开始"
echo "项目目录:${PROJECT_DIR}"
echo "Git 分支:${GIT_BRANCH}"
echo "========================================"
# ================= Step 1: 更新代码 =================
echo "========== 更新代码 =========="
# 确保目录存在
mkdir -p "${PROJECT_DIR}"
cd "${PROJECT_DIR}"
if [ ! -d ".git" ]; then
echo "首次部署,克隆仓库..."
# 检查目录是否为空,非空则备份
if [ "$(ls -A ${PROJECT_DIR} 2>/dev/null)" ]; then
echo "目录非空,备份现有文件..."
backup_dir="${PROJECT_DIR}_backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p "${backup_dir}"
mv ${PROJECT_DIR}/* ${PROJECT_DIR}/.[!.]* ${backup_dir}/ 2>/dev/null || true
echo "已备份到:${backup_dir}"
fi
git clone "${GIT_REPO}" .
git checkout "${GIT_BRANCH}"
else
echo "更新现有代码..."
git fetch origin "${GIT_BRANCH}"
git reset --hard "origin/${GIT_BRANCH}"
git clean -fd
fi
commit_hash=$(git rev-parse --short HEAD)
commit_msg=$(git log -1 --pretty=format:"%s")
echo "✅ 代码更新完成,当前版本:${commit_hash} - ${commit_msg}"
# ================= Step 2: 停止旧服务 =================
echo "========== 停止旧服务 =========="
# 停止旧的后端进程
OLD_BACKEND_PID=$(ps -ef | grep "uvicorn.*app.main:app" | grep -v grep | awk '{print $2}')
if [ -n "$OLD_BACKEND_PID" ]; then
echo "停止旧的后端进程 $OLD_BACKEND_PID"
kill -9 $OLD_BACKEND_PID || true
fi
echo "✅ 旧服务已停止"
# ================= Step 3: 创建环境配置 =================
echo "========== 创建环境配置 =========="
cd "${PROJECT_DIR}/backend"
# 创建 .env 文件
cat > .env <<ENVEOF
# 数据库配置
DATABASE_URL=${DATABASE_URL}
# JWT 配置
SECRET_KEY=${SECRET_KEY}
# 调试模式
DEBUG=${DEBUG}
ENVEOF
echo "✅ 环境配置已创建"
# ================= Step 4: 安装依赖并部署后端 =================
echo "========== 部署后端 =========="
cd "${PROJECT_DIR}/backend"
# 创建虚拟环境
if [ ! -d "venv" ]; then
echo "创建 Python 虚拟环境..."
python3 -m venv venv
fi
# 激活虚拟环境
source venv/bin/activate
# 安装依赖
echo "安装 Python 依赖..."
pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 数据库迁移
echo "执行数据库迁移..."
alembic upgrade head || true
# 启动后端
echo "启动后端服务..."
mkdir -p logs
nohup venv/bin/uvicorn app.main:app --host 0.0.0.0 --port ${BACKEND_PORT} --workers 4 > logs/backend.log 2>&1 &
echo "✅ 后端服务已启动,端口 ${BACKEND_PORT}"
# ================= Step 5: 构建前端 =================
echo "========== 构建前端 =========="
cd "${PROJECT_DIR}/frontend"
# 检查 node_modules
if [ ! -d "node_modules" ]; then
echo "安装前端依赖..."
npm install --registry=https://registry.npmmirror.com
else
echo "更新前端依赖..."
npm update --registry=https://registry.npmmirror.com
fi
# 构建前端
echo "构建前端项目..."
npm run build
echo "✅ 前端构建完成"
# ================= Step 6: 部署前端到 Nginx =================
echo "========== 部署前端 =========="
NGINX_HTML="/var/www/hospital_performance_html"
mkdir -p ${NGINX_HTML}
rm -rf ${NGINX_HTML}/*
cp -r ${PROJECT_DIR}/frontend/dist/* ${NGINX_HTML}/
# 创建 Nginx 配置
cat > /etc/nginx/conf.d/hospital_performance.conf <<EOF
server {
listen ${FRONTEND_PORT};
server_name localhost;
root ${NGINX_HTML};
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:${BACKEND_PORT};
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
location / {
try_files \$uri \$uri/ /index.html;
}
}
EOF
# 重启 Nginx
echo "重启 Nginx..."
systemctl restart nginx || nginx -s reload || true
echo "✅ 前端部署完成"
# ================= Step 7: 等待并健康检查 =================
echo "========== 执行健康检查 =========="
echo "等待服务启动..."
sleep 10
max_attempts=10
attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -f -s "http://localhost:${BACKEND_PORT}/health" > /dev/null 2>&1; then
echo "✅ 后端 API 健康检查通过"
break
else
if [ $attempt -eq $max_attempts ]; then
echo "❌ 后端 API 健康检查失败"
echo "最近日志如下:"
tail -n 50 ${PROJECT_DIR}/backend/logs/backend.log || echo "日志文件不存在"
exit 1
fi
echo "后端服务未就绪,等待... (${attempt}/${max_attempts})"
sleep 5
attempt=$((attempt + 1))
fi
done
# ================= Step 8: 查看状态 =================
echo "========== 服务状态 =========="
echo "后端进程:"
ps -ef | grep "uvicorn.*app.main:app" | grep -v grep
echo ""
echo "Nginx 状态:"
systemctl status nginx --no-pager || true
# ================= Step 9: 完成 =================
echo "✅ 部署完成"
echo "========================================"
echo "🎉 部署成功完成!"
echo "后端地址http://localhost:${BACKEND_PORT}"
echo "前端地址http://localhost:${FRONTEND_PORT}"
echo "========================================"