diff --git a/.gitignore b/.gitignore index 0716199..e2ab988 100644 --- a/.gitignore +++ b/.gitignore @@ -49,4 +49,7 @@ nbproject/ /storage/ /var/log/* *.factorypath -/storage/ \ No newline at end of file +/storage/ + +# Docker buildx cache +.buildx-cache/ \ No newline at end of file diff --git a/build-docker.sh b/build-docker.sh index 15d3024..9b1d64a 100755 --- a/build-docker.sh +++ b/build-docker.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash # 构建 Docker 镜像脚本 +# 用法: ./build-docker.sh [amd64|arm64] +# 如果不指定架构,将使用本机架构 -set -e +set -euo pipefail # 颜色输出 RED='\033[0;31m' @@ -11,6 +13,57 @@ NC='\033[0m' # No Color echo -e "${GREEN}=== 开始构建 PeiPei 后端 Docker 镜像 ===${NC}" +# 检测本机架构 +NATIVE_ARCH=$(uname -m) +if [[ "$NATIVE_ARCH" == "x86_64" ]]; then + NATIVE_ARCH="amd64" +elif [[ "$NATIVE_ARCH" == "arm64" ]] || [[ "$NATIVE_ARCH" == "aarch64" ]]; then + NATIVE_ARCH="arm64" +fi + +# 处理命令行参数 +if [[ "$1" == "-h" || "$1" == "--help" ]]; then + echo -e "${GREEN}PeiPei 后端 Docker 镜像构建脚本${NC}" + echo "" + echo -e "${YELLOW}用法:${NC}" + echo " ./build-docker.sh [选项] [架构]" + echo "" + echo -e "${YELLOW}选项:${NC}" + echo " -h, --help 显示此帮助信息" + echo "" + echo -e "${YELLOW}架构:${NC}" + echo " amd64 构建 Linux amd64 镜像 (适用于服务器)" + echo " arm64 构建 Linux arm64 镜像 (适用于 Apple Silicon Mac)" + echo " [空] 自动检测本机架构" + echo "" + echo -e "${YELLOW}示例:${NC}" + echo " ./build-docker.sh # 自动检测架构构建" + echo " ./build-docker.sh amd64 # 构建服务器镜像" + echo " ./build-docker.sh arm64 # 构建 Mac 镜像" + echo " ./build-docker.sh -h # 显示帮助" + echo "" + echo -e "${YELLOW}说明:${NC}" + echo " - 本机架构: ${NATIVE_ARCH}" + echo " - 使用 Docker Buildx 进行构建" + echo " - 镜像将带有架构后缀标签 (如: latest-amd64)" + echo " - 构建缓存存储在: .buildx-cache/" + echo " - 确保 Dockerfile 使用: FROM --platform=\$TARGETPLATFORM" + exit 0 +fi + +TARGET_ARCH="${1:-$NATIVE_ARCH}" + +# 验证架构参数 +if [[ "$TARGET_ARCH" != "amd64" && "$TARGET_ARCH" != "arm64" ]]; then + echo -e "${RED}错误: 不支持的架构 '$TARGET_ARCH'${NC}" + echo -e "${YELLOW}支持的架构: amd64, arm64${NC}" + echo -e "${YELLOW}用法: ./build-docker.sh [amd64|arm64]${NC}" + exit 1 +fi + +echo -e "${YELLOW}目标架构: ${TARGET_ARCH}${NC}" +echo -e "${YELLOW}本机架构: ${NATIVE_ARCH}${NC}" + # 检查是否在正确的目录 if [ ! -f "docker/Dockerfile" ]; then echo -e "${RED}错误: 请在项目根目录执行此脚本${NC}" @@ -25,28 +78,83 @@ echo -e "${YELLOW}构建时间戳 (UTC+8): ${TIMESTAMP}${NC}" # 镜像名称和标签 IMAGE_NAME="peipei-backend" -VERSION_TAG="${TIMESTAMP}" -LATEST_TAG="latest" +VERSION_TAG="${TIMESTAMP}-${TARGET_ARCH}" +LATEST_TAG="latest-${TARGET_ARCH}" echo -e "${YELLOW}镜像名称: ${IMAGE_NAME}${NC}" echo -e "${YELLOW}版本标签: ${VERSION_TAG}${NC}" # 构建 Docker 镜像 echo -e "${GREEN}开始构建镜像...${NC}" -if docker build -f docker/Dockerfile \ + +# 确保 buildx 可用 +if ! docker buildx version >/dev/null 2>&1; then + echo -e "${RED}错误: 需要 Docker Buildx 支持${NC}" + exit 1 +fi + +# 创建并使用 builder(如果不存在) +if ! docker buildx inspect peipei-builder >/dev/null 2>&1; then + echo -e "${YELLOW}创建 buildx builder...${NC}" + docker buildx create --name peipei-builder --use +else + docker buildx use peipei-builder +fi + +# 启动 builder 和 QEMU(用于跨架构支持) +echo -e "${YELLOW}初始化 buildx builder...${NC}" +docker buildx inspect --bootstrap >/dev/null + +# 显示构建类型 +if [[ "$TARGET_ARCH" != "$NATIVE_ARCH" ]]; then + echo -e "${YELLOW}跨平台构建: ${NATIVE_ARCH} -> ${TARGET_ARCH}${NC}" +else + echo -e "${YELLOW}本机架构构建: ${TARGET_ARCH}${NC}" +fi + +# 创建缓存目录(可选优化) +CACHE_DIR=".buildx-cache" +mkdir -p "$CACHE_DIR" + +# 始终使用 buildx 以保持行为一致 +echo -e "${GREEN}执行构建...${NC}" +if docker buildx build \ + --platform "linux/${TARGET_ARCH}" \ + --load \ + --cache-from="type=local,src=${CACHE_DIR}" \ + --cache-to="type=local,dest=${CACHE_DIR}" \ + -f docker/Dockerfile \ -t "${IMAGE_NAME}:${VERSION_TAG}" \ -t "${IMAGE_NAME}:${LATEST_TAG}" \ .; then + BUILD_SUCCESS=true +else + BUILD_SUCCESS=false +fi +# 检查构建结果 +if [[ "$BUILD_SUCCESS" == "true" ]]; then echo -e "${GREEN}✅ Docker 镜像构建成功!${NC}" echo -e "${GREEN}镜像标签:${NC}" echo -e " - ${IMAGE_NAME}:${VERSION_TAG}" echo -e " - ${IMAGE_NAME}:${LATEST_TAG}" echo -e "\n${YELLOW}镜像信息:${NC}" - docker images | grep -E "^${IMAGE_NAME}\s" | head -2 + docker images | grep -E "^${IMAGE_NAME}\s" - echo -e "\n${GREEN}下一步: 运行 ./push-docker.sh 推送到私有仓库${NC}" + echo -e "\n${GREEN}使用说明:${NC}" + if [[ "$TARGET_ARCH" == "amd64" ]]; then + echo -e " - 该镜像适用于 Linux amd64 服务器部署" + echo -e " - 推送到服务器: ./push-docker.sh" + elif [[ "$TARGET_ARCH" == "arm64" ]]; then + echo -e " - 该镜像适用于 Apple Silicon Mac 本地运行" + echo -e " - 本地测试: docker run ${IMAGE_NAME}:${LATEST_TAG}" + fi + + echo -e "\n${YELLOW}构建其他架构:${NC}" + echo -e " - 构建 amd64 (服务器): ./build-docker.sh amd64" + echo -e " - 构建 arm64 (Mac): ./build-docker.sh arm64" + echo -e " - 自动检测架构: ./build-docker.sh" else echo -e "${RED}❌ Docker 镜像构建失败!${NC}" exit 1 diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index 4ece7be..0000000 --- a/deploy.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# 发包脚本 -set -e - -# 获取当前时间并格式化为指定格式 -current_time=$(date +"%Y-%m-%d %H:%M:%S") -echo "发布开始,当前时间是:$current_time" - -# 构建项目 -echo "开始构建项目..." -mvn clean install - -echo "项目构建成功,继续部署..." -# 部署到服务器 -echo "开始部署到服务器..." -scp ./play-admin/target/play-admin-1.0.jar root@122.51.20.105:/www/wwwroot/july.hucs.top -ssh root@122.51.20.105 "source /etc/profile;cd /www/wwwroot/july.hucs.top;sh start.sh restart" - -# 备用服务器部署 (已注释) -# scp ./play-admin/target/play-admin-1.0.jar root@122.51.20.105:/www/wwwroot/julyharbor.com -# ssh root@122.51.20.105 "source /etc/profile;cd /www/wwwroot/julyharbor.com;sh start.sh restart" - -# 获取结束时间 -current_time=$(date +"%Y-%m-%d %H:%M:%S") -echo "发布完成,当前时间是:$current_time" \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index c16f854..4b8c10d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ # ---------- Build stage ---------- -FROM --platform=$BUILDPLATFORM maven:3.9-eclipse-temurin-11 AS build +FROM maven:3.9-eclipse-temurin-11 AS build WORKDIR /workspace # Cache-friendly: copy POMs first @@ -20,7 +20,7 @@ COPY play-generator/src play-generator/src/ RUN --mount=type=cache,target=/root/.m2 mvn -pl play-admin -am -B -DskipTests -T 1C clean package # ---------- Runtime stage (multi-arch) ---------- -FROM eclipse-temurin:11-jre AS runtime +FROM --platform=$TARGETPLATFORM eclipse-temurin:11-jre AS runtime # non-root RUN groupadd -g 1001 appgroup && useradd -u 1001 -g appgroup -m -s /usr/sbin/nologin appuser WORKDIR /app diff --git a/fetch-log.sh b/fetch-log.sh deleted file mode 100755 index df1295e..0000000 --- a/fetch-log.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# 拉取日志脚本 -set -e - -# 获取当前时间并格式化为指定格式 -current_time=$(date +"%Y-%m-%d %H:%M:%S") -echo "开始拉取日志,当前时间是:$current_time" - -# 创建本地log目录(如果不存在) -mkdir -p ./log - -# 从远程服务器拉取整个log文件夹 -echo "正在从远程服务器拉取日志文件..." -scp -r root@122.51.20.105:/www/wwwroot/july.hucs.top/log/* ./log/ - -# 获取当前时间并格式化为指定格式 -current_time=$(date +"%Y-%m-%d %H:%M:%S") -echo "日志拉取完成,当前时间是:$current_time" \ No newline at end of file diff --git a/push-docker.sh b/push-docker.sh index 59c972e..d6aaa8d 100755 --- a/push-docker.sh +++ b/push-docker.sh @@ -1,7 +1,7 @@ #!/bin/bash # 推送 Docker 镜像到私有仓库脚本 -set -e +set -euo pipefail # 颜色输出 RED='\033[0;31m' @@ -22,8 +22,9 @@ echo -e "${GREEN}=== 推送 PeiPei 后端镜像到私有仓库 ===${NC}" TIMESTAMP=$(TZ='Asia/Shanghai' date +"%Y-%m-%d-%Hh-%Mm") echo -e "${YELLOW}推送时间戳 (UTC+8): ${TIMESTAMP}${NC}" -# 本地镜像名称 +# 本地镜像名称 (始终推送 amd64 版本到服务器) LOCAL_IMAGE="peipei-backend" +LOCAL_TAG="latest-amd64" # 服务器使用 amd64 架构 # 远程镜像名称和标签 REMOTE_IMAGE="${REGISTRY_URL}/${PROJECT_PATH}" @@ -35,9 +36,11 @@ echo -e "${BLUE}项目路径: ${PROJECT_PATH}${NC}" echo -e "${BLUE}远程镜像: ${REMOTE_IMAGE}${NC}" # 检查本地镜像是否存在 -if ! docker images | grep -q "${LOCAL_IMAGE}"; then - echo -e "${RED}错误: 本地镜像 ${LOCAL_IMAGE} 不存在${NC}" - echo -e "${YELLOW}请先运行: ./build-docker.sh${NC}" +if ! docker images --format "{{.Repository}}:{{.Tag}}" | grep -q "^${LOCAL_IMAGE}:${LOCAL_TAG}$"; then + echo -e "${RED}错误: 本地镜像 ${LOCAL_IMAGE}:${LOCAL_TAG} 不存在${NC}" + echo -e "${YELLOW}请先运行: ./build-docker.sh amd64${NC}" + echo -e "${YELLOW}当前可用的镜像:${NC}" + docker images --format "table {{.Repository}}\t{{.Tag}}" | grep "^${LOCAL_IMAGE}\s" exit 1 fi @@ -53,12 +56,12 @@ fi echo -e "${GREEN}✅ 登录成功!${NC}" # 标记镜像 - 版本标签 -echo -e "${GREEN}标记镜像: ${LOCAL_IMAGE}:latest -> ${REMOTE_IMAGE}:${VERSION_TAG}${NC}" -docker tag "${LOCAL_IMAGE}:latest" "${REMOTE_IMAGE}:${VERSION_TAG}" +echo -e "${GREEN}标记镜像: ${LOCAL_IMAGE}:${LOCAL_TAG} -> ${REMOTE_IMAGE}:${VERSION_TAG}${NC}" +docker tag "${LOCAL_IMAGE}:${LOCAL_TAG}" "${REMOTE_IMAGE}:${VERSION_TAG}" # 标记镜像 - latest 标签 -echo -e "${GREEN}标记镜像: ${LOCAL_IMAGE}:latest -> ${REMOTE_IMAGE}:${LATEST_TAG}${NC}" -docker tag "${LOCAL_IMAGE}:latest" "${REMOTE_IMAGE}:${LATEST_TAG}" +echo -e "${GREEN}标记镜像: ${LOCAL_IMAGE}:${LOCAL_TAG} -> ${REMOTE_IMAGE}:${LATEST_TAG}${NC}" +docker tag "${LOCAL_IMAGE}:${LOCAL_TAG}" "${REMOTE_IMAGE}:${LATEST_TAG}" # 推送版本标签 echo -e "${GREEN}推送版本标签镜像...${NC}" @@ -92,6 +95,8 @@ echo -e " docker pull ${REMOTE_IMAGE}:${LATEST_TAG}" echo -e "\n${YELLOW}更新 docker-compose.yml 中的镜像:${NC}" echo -e " image: ${REMOTE_IMAGE}:${VERSION_TAG}" +echo -e "\n${BLUE}注意: 此脚本推送 amd64 架构镜像到服务器${NC}" + # 清理本地标记的远程镜像标签 (可选) echo -e "\n${GREEN}清理本地远程标签...${NC}" docker rmi "${REMOTE_IMAGE}:${VERSION_TAG}" "${REMOTE_IMAGE}:${LATEST_TAG}" 2>/dev/null || true diff --git a/rollback.sh b/rollback.sh deleted file mode 100755 index c5bd181..0000000 --- a/rollback.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# 快速回滚脚本 -set -e -echo "开始回滚到本地备份版本..." - -# 使用本地备份文件回滚 -scp ./backup/play-admin-1.0-20250830-215753.jar root@122.51.20.105:/www/wwwroot/july.hucs.top/play-admin-1.0.jar -echo "备份文件已上传!" - -# 重启服务 -ssh root@122.51.20.105 "source /etc/profile;cd /www/wwwroot/july.hucs.top;sh start.sh restart" -echo "服务已重启,回滚完成!" \ No newline at end of file