feat: 增强Docker构建系统,支持多架构构建

- 为build-docker.sh添加架构特定构建支持 (amd64/arm64)
- 始终使用Docker Buildx确保跨平台构建的一致性
- 添加构建缓存支持,使用.buildx-cache目录
- 更新Dockerfile使用平台感知基础镜像 (FROM --platform=$TARGETPLATFORM)
- 改进push-docker.sh以支持架构特定标签
- 为构建脚本添加帮助选项 (-h)
- 使用更严格的错误处理 (set -euo pipefail)
- 更新.gitignore排除构建缓存

现在支持构建:
- Apple Silicon本地开发 (arm64)
- Linux服务器部署 (amd64)
- 从任意机器进行跨平台构建
This commit is contained in:
irving
2025-09-06 21:57:59 -04:00
parent b96fdc6427
commit ea0490e141
7 changed files with 134 additions and 73 deletions

5
.gitignore vendored
View File

@@ -49,4 +49,7 @@ nbproject/
/storage/
/var/log/*
*.factorypath
/storage/
/storage/
# Docker buildx cache
.buildx-cache/

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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 "服务已重启,回滚完成!"