#!/bin/bash # 定义变量 WORKSPACE_DIR="Admin.NET/Admin.NET.Web.Entry" PROJECT_FILE="Admin.NET.Web.Entry.csproj" PRIVATE_REGISTRY="192.168.104.102:5000" NAMESPACE="ycymedu" REPO_NAME="tuiwucarrerv1" IMAGE_NAME="$PRIVATE_REGISTRY/$REPO_NAME" TAG=$(date +%Y%m%d%H%M%S) PORT=5010 REMOTE_SERVER="192.168.104.102" REMOTE_USER="app" SSH_PRIVATE_KEY_PATH="/var/opt/YI_LIUYANG" # 从 Jenkins 全局变量中获取 # 钉钉 Webhook URL DINGDING_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=fca104958fea6273c9c7ef3f08b3d552645c214f929066785e8caf6e1885a5a6" # 输出当前工作目录 echo "当前工作目录: $(pwd)" # 清理之前的发布输出目录 rm -rf "$(pwd)/$WORKSPACE_DIR/out" # 进入项目目录 cd $WORKSPACE_DIR echo "当前工作目录: $(pwd)" # 检查是否成功进入项目目录 if [ $? -ne 0 ]; then echo "无法进入项目目录 $WORKSPACE_DIR,请检查路径设置。" exit 1 fi # 清理之前的构建产物 dotnet clean # 恢复项目依赖 dotnet restore echo "当前工作目录2: $(pwd)" # 发布项目 dotnet publish $PROJECT_FILE -c Release -o out echo "当前工作目录4: $(pwd)" cd out # 构建 Docker 镜像 docker build -t temp_image:latest . if [ $? -ne 0 ]; then echo "Docker 镜像构建失败,请检查 Dockerfile 和相关配置。" exit 1 fi # 为镜像打标签 # 打标签并推送 docker tag temp_image:latest "$IMAGE_NAME:$TAG" docker tag temp_image:latest "$IMAGE_NAME:latest" docker push "$IMAGE_NAME:$TAG" docker push "$IMAGE_NAME:latest" if [ $? -eq 0 ]; then echo "✅ Docker 镜像推送成功: $IMAGE_NAME:$TAG & latest" else echo "❌ Docker 镜像推送失败。" exit 1 fi # 推送 Docker 镜像到私有仓库 docker push "$IMAGE_NAME:$TAG" if [ $? -eq 0 ]; then echo "Docker 镜像构建并推送到私有仓库成功!镜像地址: $IMAGE_NAME:$TAG" else echo "Docker 镜像构建或推送失败,请检查日志。" exit 1 fi # ✅ 远程执行命令,并确保返回正确的 exit 状态码 ssh -o StrictHostKeyChecking=no -i "$SSH_PRIVATE_KEY_PATH" "$REMOTE_USER@$REMOTE_SERVER" 'bash -s' << EOF set -e # 遇到错误立即退出 echo "✅ 远程服务器登录成功!" PRIVATE_REGISTRY="192.168.104.102:5000" REPO_NAME="tuiwucarrerv1" IMAGE_NAME="\$PRIVATE_REGISTRY/\$REPO_NAME" PORT=5010 echo "🚀 拉取最新 Docker 镜像: \$IMAGE_NAME:$TAG 和 latest" sudo docker pull "\$IMAGE_NAME:$TAG" sudo docker pull "\$IMAGE_NAME:latest" # ✅ 停止并删除所有旧容器 echo "🛑 停止并删除所有旧容器" OLD_CONTAINERS=\$(sudo docker ps -aq --filter "name=$REPO_NAME") if [ "\$OLD_CONTAINERS" ]; then sudo docker stop \$OLD_CONTAINERS sudo docker rm \$OLD_CONTAINERS else echo "✅ 没有找到旧容器,无需删除" fi # ✅ 删除所有旧的 Docker 镜像(保留 latest 和当前 $TAG) echo "🧹 清理旧的 Docker 镜像" OLD_IMAGES=\$(sudo docker images "\$IMAGE_NAME" --format "{{.ID}}" | tail -n +2) if [ "\$OLD_IMAGES" ]; then sudo docker rmi -f \$OLD_IMAGES else echo "✅ 没有找到旧镜像,无需清理" fi # ✅ 启动新容器 NEW_CONTAINER_NAME="${REPO_NAME}_container_${TAG}" echo "🚀 启动新容器: \$NEW_CONTAINER_NAME" sudo docker run --restart=always -d --name "\$NEW_CONTAINER_NAME" -p $PORT:$PORT "\$IMAGE_NAME:$TAG" if [ \$? -eq 0 ]; then echo "✅ 部署成功: \$NEW_CONTAINER_NAME" exit 0 else echo "❌ 部署失败!请检查日志。" exit 1 fi EOF # ✅ 确保 ssh 的退出状态传递到本地 SSH_EXIT_CODE=$? echo "SSH 退出码: $SSH_EXIT_CODE" # ✅ 发送钉钉通知 send_dingtalk_notification() { local status="$1" local message="$2" curl -X POST "$DINGDING_WEBHOOK" \ -H "Content-Type: application/json" \ -d "{ \"msgtype\": \"text\", \"text\": { \"content\": \"【部署状态】$status\n$message\" } }" } if [ $SSH_EXIT_CODE -eq 0 ]; then SUCCESS_MESSAGE="远程服务器操作完成,应用已成功部署!\n镜像地址: $IMAGE_NAME:$TAG" send_dingtalk_notification "✅ 成功" "$SUCCESS_MESSAGE" else FAILURE_MESSAGE="【部署状态】远程服务器操作失败,请检查 SSH 连接和脚本。" send_dingtalk_notification "❌ 失败" "$FAILURE_MESSAGE" exit 1 fi