146 lines
5.5 KiB
Bash
Executable File
146 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# 全国记者站管理系统 — 一键部署脚本
|
|
# 用法: ./deploy.sh
|
|
# 功能: 拉取最新代码 → 安装依赖 → 数据库迁移 → 构建 → 重启服务
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
# ── 配置 ──────────────────────────────────────────────────
|
|
DEPLOY_DIR="/var/www/rsms"
|
|
GIT_REMOTE="origin"
|
|
BRANCH="main"
|
|
API_PORT="${API_PORT:-8787}"
|
|
PM2_NAME="rsms-server"
|
|
NGINX_SITE="r.all8ai.top"
|
|
|
|
# 颜色输出
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log() { echo -e "${GREEN}[deploy]${NC} $1"; }
|
|
warn() { echo -e "${YELLOW}[warn]${NC} $1"; }
|
|
err() { echo -e "${RED}[error]${NC} $1"; exit 1; }
|
|
|
|
# ── 前置检查 ──────────────────────────────────────────────
|
|
check_deps() {
|
|
log "检查依赖..."
|
|
command -v git >/dev/null || err "git 未安装"
|
|
command -v node >/dev/null || err "node 未安装"
|
|
command -v npm >/dev/null || err "npm 未安装"
|
|
command -v nginx >/dev/null || err "nginx 未安装"
|
|
command -v pm2 >/dev/null || err "pm2 未安装 (运行: npm install -g pm2)"
|
|
|
|
NODE_MAJOR=$(node -v | sed 's/v\([0-9]*\).*/\1/')
|
|
[ "$NODE_MAJOR" -ge 22 ] || err "Node.js 版本需 >= 22 (当前: $(node -v))"
|
|
|
|
log "依赖检查通过: node $(node -v), npm $(npm -v)"
|
|
}
|
|
|
|
# ── 拉取最新代码 ──────────────────────────────────────────
|
|
pull_code() {
|
|
log "拉取最新代码..."
|
|
cd "$DEPLOY_DIR"
|
|
git fetch "$GIT_REMOTE" "$BRANCH"
|
|
git reset --hard "$GIT_REMOTE/$BRANCH"
|
|
log "代码已更新到 $(git log --oneline -1)"
|
|
}
|
|
|
|
# ── 安装依赖 ──────────────────────────────────────────────
|
|
install_deps() {
|
|
log "安装依赖..."
|
|
npm install --production=false
|
|
log "依赖安装完成"
|
|
}
|
|
|
|
# ── 数据库迁移 ────────────────────────────────────────────
|
|
run_migrations() {
|
|
log "执行数据库迁移..."
|
|
npm run db:migrate
|
|
log "数据库迁移完成"
|
|
}
|
|
|
|
# ── 构建前端 ──────────────────────────────────────────────
|
|
build_frontend() {
|
|
log "构建前端..."
|
|
npm run build
|
|
log "前端构建完成: $(ls dist/assets/*.js | wc -l) 个 JS 文件"
|
|
}
|
|
|
|
# ── 重启后端服务 ──────────────────────────────────────────
|
|
restart_server() {
|
|
log "重启后端服务 (pm2: $PM2_NAME)..."
|
|
pm2 delete "$PM2_NAME" 2>/dev/null || true
|
|
pm2 start npm --name "$PM2_NAME" -- run server:start
|
|
pm2 save
|
|
sleep 2
|
|
|
|
# 健康检查
|
|
local health
|
|
health=$(curl -s "http://127.0.0.1:${API_PORT}/api/health" 2>/dev/null || echo "FAIL")
|
|
if echo "$health" | grep -q '"status":"ok"'; then
|
|
log "后端服务健康检查通过"
|
|
else
|
|
warn "后端健康检查异常: $health"
|
|
warn "查看日志: pm2 logs $PM2_NAME --lines 20"
|
|
fi
|
|
}
|
|
|
|
# ── 重载 nginx ────────────────────────────────────────────
|
|
reload_nginx() {
|
|
log "检查 nginx 配置..."
|
|
nginx -t 2>&1 || err "nginx 配置检查失败"
|
|
nginx -s reload
|
|
log "nginx 已重载"
|
|
}
|
|
|
|
# ── 验证站点 ──────────────────────────────────────────────
|
|
verify_site() {
|
|
log "验证站点..."
|
|
local http_code
|
|
http_code=$(curl -s -o /dev/null -w "%{http_code}" "http://${NGINX_SITE}/" 2>/dev/null || echo "000")
|
|
if [ "$http_code" = "200" ]; then
|
|
log "站点验证通过: http://${NGINX_SITE} → 200"
|
|
else
|
|
warn "站点返回: $http_code (可能需要检查 DNS 或 nginx 配置)"
|
|
fi
|
|
|
|
# HTTPS 检查(如果证书存在)
|
|
if [ -d "/etc/letsencrypt/live/${NGINX_SITE}" ]; then
|
|
local https_code
|
|
https_code=$(curl -s -o /dev/null -w "%{http_code}" "https://${NGINX_SITE}/" 2>/dev/null || echo "000")
|
|
log "HTTPS 验证: https://${NGINX_SITE} → $https_code"
|
|
fi
|
|
}
|
|
|
|
# ── 主流程 ────────────────────────────────────────────────
|
|
main() {
|
|
echo ""
|
|
echo "══════════════════════════════════════════════════"
|
|
echo " 全国记者站管理系统 — 一键部署"
|
|
echo "══════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
check_deps
|
|
pull_code
|
|
install_deps
|
|
run_migrations
|
|
build_frontend
|
|
restart_server
|
|
reload_nginx
|
|
verify_site
|
|
|
|
echo ""
|
|
log "部署完成!"
|
|
echo " 站点: https://${NGINX_SITE}"
|
|
echo " API: https://${NGINX_SITE}/api/health"
|
|
echo " 日志: pm2 logs ${PM2_NAME}"
|
|
echo " 状态: pm2 list"
|
|
echo ""
|
|
}
|
|
|
|
main "$@"
|