Files
gouki ec55a1d536
Publish Mini Program Dev Version / publish (push) Canceled after 0s
Build and Deploy Server / build (push) Canceled after 0s
fix(ci): 部署链路重构为拉取式,修复工作流问题
- deploy.sh: 目录级原子切换(current.new/current.old)替代 rm -rf 空窗式替换;
  健康检查改为轮询 /api/version HTTP 接口;失败自动回滚上一版本
- 新增 deploy-watch.sh: 服务器本地 systemd timer 轮询 /ci-artifacts 产物指纹,
  发现新版本自动部署——CI 与 AI 不再需要 SSH 到服务器执行任何命令
- server-deploy.yml: 部署包补入 web/ 后台静态资源;移除永不生效的前端构建死代码;
  通知文案如实改为'构建成功'(部署由服务器侧 watcher 完成)
- miniapp-preview.yml: 移除无意义的 --runInBand 测试参数
- 新增 PULL_DEPLOY.md 一次性安装文档(管理员手工执行)
2026-08-09 00:10:45 +00:00

160 lines
4.3 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
# 自动部署脚本 - 部署到 1Panel Docker 容器
# 设计原则:拉取式部署,只在服务器本地执行,CI 不通过 SSH 触发
# 使用方法: ./deploy.sh <deploy_package_path>
# deploy_package_path: 部署包路径(如 /ci-artifacts/server-deploy-latest.tar.gz
set -e
DEPLOY_PACKAGE="$1"
CONTAINER_NAME="${CONTAINER_NAME:-lunar-server}"
DEPLOY_DIR="${DEPLOY_DIR:-/opt/lunar/production}"
BACKUP_DIR="${BACKUP_DIR:-/opt/lunar/backups}"
HEALTH_URL="${HEALTH_URL:-http://localhost:8080/api/version}"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 回滚函数:恢复 current.old 并重启容器
rollback() {
if [ -d "$DEPLOY_DIR/current.old" ]; then
rm -rf "$DEPLOY_DIR/current"
mv "$DEPLOY_DIR/current.old" "$DEPLOY_DIR/current"
docker restart "$CONTAINER_NAME" || log_error "回滚后容器重启失败,需人工介入"
log_warn "已回滚到上一版本"
else
log_error "无可回滚版本,需人工介入"
fi
}
# 检查部署包是否存在
if [ ! -f "$DEPLOY_PACKAGE" ]; then
log_error "部署包不存在: $DEPLOY_PACKAGE"
exit 1
fi
log_info "开始自动部署..."
log_info "部署包: $DEPLOY_PACKAGE"
log_info "目标容器: $CONTAINER_NAME"
log_info "部署目录: $DEPLOY_DIR"
# 创建必要的目录
mkdir -p "$DEPLOY_DIR"
mkdir -p "$BACKUP_DIR"
# 备份当前版本
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_${TIMESTAMP}.tar.gz"
if [ -d "$DEPLOY_DIR/current" ]; then
log_info "备份当前版本到: $BACKUP_FILE"
tar -czf "$BACKUP_FILE" -C "$DEPLOY_DIR" current/ || log_warn "备份失败,继续部署"
fi
# 解压新版本到暂存目录(不碰 current,避免部署空窗)
log_info "解压部署包..."
TEMP_DIR=$(mktemp -d)
tar -xzf "$DEPLOY_PACKAGE" -C "$TEMP_DIR"
# 检查解压后的目录结构
if [ ! -d "$TEMP_DIR/deploy" ]; then
log_error "部署包结构错误:缺少 deploy 目录"
rm -rf "$TEMP_DIR"
exit 1
fi
# 校验二进制存在
if [ ! -f "$TEMP_DIR/deploy/bin/server" ]; then
log_error "部署包缺少 bin/server 二进制"
rm -rf "$TEMP_DIR"
exit 1
fi
chmod +x "$TEMP_DIR/deploy/bin/server"
# 部署新版本(目录级交换,接近原子)
log_info "部署新版本..."
mv "$TEMP_DIR/deploy" "$DEPLOY_DIR/current.new"
rm -rf "$DEPLOY_DIR/current.old"
if [ -d "$DEPLOY_DIR/current" ]; then
mv "$DEPLOY_DIR/current" "$DEPLOY_DIR/current.old"
fi
mv "$DEPLOY_DIR/current.new" "$DEPLOY_DIR/current"
rm -rf "$TEMP_DIR"
# 检查 Docker 容器是否存在
if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
log_error "Docker 容器不存在: $CONTAINER_NAME"
log_info "请在 1Panel 中创建容器,或使用以下命令:"
echo ""
echo "docker run -d \\"
echo " --name $CONTAINER_NAME \\"
echo " -v $DEPLOY_DIR/current:/app \\"
echo " -p 8080:8080 \\"
echo " --restart unless-stopped \\"
echo " golang:1.22-bookworm \\"
echo " /app/bin/server"
echo ""
exit 1
fi
# 重启 Docker 容器
log_info "重启 Docker 容器: $CONTAINER_NAME"
if docker restart "$CONTAINER_NAME"; then
log_info "✅ 容器重启成功"
else
log_error "❌ 容器重启失败,回滚到上一版本"
rollback
exit 1
fi
# 健康检查:轮询 HTTP 接口确认服务真正可用
log_info "执行健康检查: $HEALTH_URL"
HEALTHY=0
for i in $(seq 1 10); do
sleep 2
if curl -fsS --max-time 5 "$HEALTH_URL" > /dev/null 2>&1; then
HEALTHY=1
break
fi
done
if [ "$HEALTHY" = "1" ]; then
log_info "✅ 健康检查通过"
curl -fsS --max-time 5 "$HEALTH_URL" && echo ""
rm -rf "$DEPLOY_DIR/current.old"
else
log_error "❌ 健康检查失败,回滚到上一版本"
docker logs --tail 50 "$CONTAINER_NAME" || true
rollback
exit 1
fi
# 清理旧备份(保留最近 5 个)
log_info "清理旧备份..."
ls -t "$BACKUP_DIR"/backup_*.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm -f
log_info "✅ 部署完成!"
log_info "备份文件: $BACKUP_FILE"
log_info "部署目录: $DEPLOY_DIR/current"
# 输出部署信息(用于通知)
echo ""
echo "DEPLOY_SUCCESS=true"
echo "DEPLOY_TIME=$TIMESTAMP"
echo "CONTAINER_NAME=$CONTAINER_NAME"