Files
backend/deploy.sh
34047007@qq.com a6cd99a4ca
CI / backend (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
feat: initial commit - oncology literature search platform
OncoLit: a multi-tenant oncology literature search, feed, and
collaboration platform. Built with FastAPI + Vue 3 + PostgreSQL.
Includes PubMed pipeline, drug approvals, AI summaries, and
systematic review tools.
2026-07-27 07:59:18 +08:00

154 lines
6.4 KiB
Bash
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
# ═══════════════════════════════════════════════════════════════════
# SciLit — 生产环境一键部署脚本
# ═══════════════════════════════════════════════════════════════════
#
# 用法:
# export SCILIT_HOST=your-server.com
# ./deploy.sh # 部署到默认服务器
# ./deploy.sh --skip-tests # 跳过本地测试,直接部署
# ./deploy.sh --help # 查看全部选项
#
# 前置条件:
# - 本地: SSH 可连接到服务器(推荐用 ~/.ssh/config
# - 服务器: 已装 Docker + docker compose,已 clone 项目
# - 服务器: .env 文件已配置好
# - 代码仓库: 支持 Gitee / GitHub / 自建 Gitgit pull 能工作即可)
#
# 远程仓库配置:
# - 本地 git remote 指向 Gitee:
# git remote add gitee https://gitee.com/你的用户名/scilit-oncology.git
# # deploy.sh 会尝试 push 到 origin(可设为 Gitee
# - 服务器上 git remote 也指向 Gitee:
# git remote set-url origin https://gitee.com/你的用户名/scilit-oncology.git
# - 可选: GitHub 同时保留用作备份:
# git remote add github https://github.com/你的用户名/scilit-oncology.git
# ═══════════════════════════════════════════════════════════════════
set -euo pipefail
# ── 默认配置 ─────────────────────────────────────────────────────
# 改为你的服务器信息
SERVER_HOST="${SCILIT_HOST:-your-server.com}"
SERVER_USER="${SCILIT_USER:-root}"
SERVER_PATH="${SCILIT_PATH:-/root/scilit-oncology}"
# 本地项目根目录
LOCAL_ROOT="$(cd "$(dirname "$0")" && pwd)"
# ── 颜色 ─────────────────────────────────────────────────────────
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
info() { echo -e "${GREEN}[✓]${NC} $1"; }
warn() { echo -e "${YELLOW}[!]${NC} $1"; }
error() { echo -e "${RED}[✗]${NC} $1"; exit 1; }
# ── 参数解析 ─────────────────────────────────────────────────────
SKIP_TESTS=false
ENV_FILE=""
while [[ $# -gt 0 ]]; do
case "$1" in
--skip-tests) SKIP_TESTS=true; shift ;;
--env) ENV_FILE="$2"; shift 2 ;;
--help)
echo "用法: $0 [--skip-tests] [--env .env.prod]"
echo ""
echo " --skip-tests 跳过本地测试和 lint"
echo " --env FILE 指定服务器上的 .env 文件路径(默认: {SERVER_PATH}/.env"
exit 0 ;;
*) error "未知参数: $1,使用 --help 查看用法" ;;
esac
done
# ── 第一步:本地检查 + 测试 ─────────────────────────────────────
echo "════════════════════════════════════════════"
echo " SciLit 部署"
echo " 目标: ${SERVER_USER}@${SERVER_HOST}"
echo "════════════════════════════════════════════"
echo ""
if [ "$SKIP_TESTS" = false ]; then
echo "── 1/4 本地测试 ──"
cd "$LOCAL_ROOT/backend"
info "运行后端测试..."
python -m pytest tests/ -v --no-cov --tb=short 2>&1 | tail -5
local EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
error "后端测试失败(exit code $EXIT_CODE),中止部署。用 --skip-tests 跳过。"
fi
info "后端测试通过"
cd "$LOCAL_ROOT/frontend"
info "构建前端(验证)..."
npm run build 2>&1 | tail -3
info "前端构建通过"
cd "$LOCAL_ROOT"
else
echo "── 1/4 本地测试 ── 已跳过"
fi
# ── 第二步:推送代码 ─────────────────────────────────────────────
echo ""
echo "── 2/4 推送代码 ──"
cd "$LOCAL_ROOT"
if git status --porcelain | grep -q .; then
warn "有未提交的改动,建议先提交再部署。继续?(y/N)"
read -r yn
if [ "$yn" != "y" ] && [ "$yn" != "Y" ]; then
error "已取消"
fi
fi
# 尝试推送到 GitHub(失败不阻塞)
if git push origin main 2>&1; then
info "GitHub push 成功"
else
warn "GitHub push 失败(网络问题),继续部署..."
fi
# ── 第三步:服务器拉取 + 构建 + 启动 ────────────────────────────
echo ""
echo "── 3/4 服务器部署 ──"
DEPLOY_CMD=$(cat << SSHCMD
set -e
cd ${SERVER_PATH}
echo " 拉取代码..."
git pull origin main 2>&1 || echo " [!] git pull 失败,继续用本地代码"
echo " 构建并启动..."
docker compose -f docker-compose.prod.yml build 2>&1 | tail -3
# 优雅重启(不中断现有连接)
echo " 正在更新服务..."
docker compose -f docker-compose.prod.yml up -d --no-deps --remove-orphans 2>&1
echo " 等待就绪..."
sleep 5
curl -sf http://localhost:8000/health && echo " [✓] backend 健康检查通过" || echo " [!] backend 健康检查失败"
curl -sf http://localhost:80 && echo " [✓] frontend 健康检查通过" || echo " [!] frontend 健康检查失败"
echo " 清理旧镜像..."
docker image prune -f 2>&1 | tail -1
SSHCMD
)
ssh -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_HOST}" bash <<< "$DEPLOY_CMD"
info "服务器部署完成"
# ── 第四步:日志 ─────────────────────────────────────────────────
echo ""
echo "── 4/4 查看日志 ──"
echo ""
echo " 实时日志: ssh ${SERVER_USER}@${SERVER_HOST} 'cd ${SERVER_PATH} && docker compose -f docker-compose.prod.yml logs -f'"
echo " backend: ssh ${SERVER_USER}@${SERVER_HOST} 'cd ${SERVER_PATH} && docker compose -f docker-compose.prod.yml logs -f backend'"
echo " 重新部署: cd $(pwd) && bash deploy.sh"
echo ""
info "部署完毕 🎉"