fix: Optimize Docker build and resolve network timeout issues

根据Gemini建议的优化方案:

 **Dockerfile修复**:
- 修复FROM语句大小写警告 (as -> AS)
- 修复Maven settings.xml中的XML标签错误 (<n> -> <name>)
- 优化健康检查端点支持Actuator标准
- 统一使用mvnw执行命令

 **Jenkinsfile优化**:
- 简化Docker buildx命令,移除可能导致网络问题的参数
- 添加备用构建方案:Buildx失败时自动切换到传统Docker构建
- 移除复杂的缓存配置,先确保基本构建正常
- 优化错误处理和重试逻辑
- 减少重试次数避免无谓等待

 **工具脚本**:
- setup-docker-mirrors.sh: 配置Docker镜像加速器
- test-docker-build.sh: 测试Docker构建环境
- 包含网络优化和构建器验证

**主要解决问题**:
- Docker Hub网络超时问题
- Buildx配置复杂性
- 构建失败时的降级策略

下一步建议在服务器运行 scripts/setup-docker-mirrors.sh 配置镜像加速器
This commit is contained in:
wangtianqi 2025-06-24 10:08:54 +08:00
parent 98b08af4a3
commit 4862d39139
8 changed files with 415 additions and 24 deletions

View File

@ -1,5 +1,5 @@
# 使用多阶段构建优化镜像大小 # 使用多阶段构建优化镜像大小 - 修复FROM语句大小写
FROM amazoncorretto:17-alpine-jdk as builder FROM amazoncorretto:17-alpine-jdk AS builder
# 设置工作目录 # 设置工作目录
WORKDIR /app WORKDIR /app
@ -26,7 +26,7 @@ COPY mvnw .
# 给mvnw脚本添加执行权限 # 给mvnw脚本添加执行权限
RUN chmod +x ./mvnw RUN chmod +x ./mvnw
# 首先只下载依赖利用Docker层缓存不使用mount缓存 # 首先只下载依赖利用Docker层缓存
RUN ./mvnw dependency:resolve -B -q RUN ./mvnw dependency:resolve -B -q
# 复制源代码 # 复制源代码
@ -64,9 +64,9 @@ USER spring
# 暴露端口 # 暴露端口
EXPOSE 8080 EXPOSE 8080
# 健康检查 # 健康检查 - 使用Spring Boot Actuator标准端点
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/api/health || exit 1 CMD curl -f http://localhost:8080/actuator/health || curl -f http://localhost:8080/api/health || exit 1
# JVM调优参数 # JVM调优参数
ENV JAVA_OPTS="-server -Xms256m -Xmx512m -XX:+UseG1GC -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" ENV JAVA_OPTS="-server -Xms256m -Xmx512m -XX:+UseG1GC -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"

40
Jenkinsfile vendored
View File

@ -154,9 +154,11 @@ pipeline {
try { try {
// 清理旧镜像以节省空间 // 清理旧镜像以节省空间
sh 'docker image prune -f || true' sh 'docker image prune -f || true'
echo "开始构建Docker镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
echo "开始构建Docker镜像: ${IMAGE_NAME}:${IMAGE_TAG}" // 启用Docker Buildx并创建构建器 // 检查Buildx是否可用
sh ''' sh '''
docker buildx version
echo "✅ 使用已安装的 Docker Buildx $(docker buildx version)" echo "✅ 使用已安装的 Docker Buildx $(docker buildx version)"
# 简化构建器管理:重用或创建 # 简化构建器管理:重用或创建
@ -170,39 +172,39 @@ pipeline {
# 验证构建器状态 # 验证构建器状态
docker buildx inspect jenkins-builder docker buildx inspect jenkins-builder
''' ''' // 使用Buildx构建镜像简化配置避免网络问题
// 使用Buildx构建镜像增加超时时间到30分钟
timeout(time: 30, unit: 'MINUTES') { timeout(time: 30, unit: 'MINUTES') {
sh ''' sh '''
# 使用Buildx构建镜像移除网络限制 # 使用简化的Buildx构建命令移除可能导致问题的参数
docker buildx build \\ docker buildx build \\
--builder jenkins-builder \\ --builder jenkins-builder \\
--platform linux/amd64 \\ --platform linux/amd64 \\
--cache-from type=local,src=/tmp/.buildx-cache \\
--cache-to type=local,dest=/tmp/.buildx-cache-new,mode=max \\
--build-arg BUILDKIT_INLINE_CACHE=1 \\
--load \\ --load \\
-t ${IMAGE_NAME}:${IMAGE_TAG} \\ -t ${IMAGE_NAME}:${IMAGE_TAG} \\
-t ${IMAGE_NAME}:latest \\ -t ${IMAGE_NAME}:latest \\
. .
# 移动缓存(避免缓存无限增长)
rm -rf /tmp/.buildx-cache || true
mv /tmp/.buildx-cache-new /tmp/.buildx-cache || true
''' '''
} }
echo "✅ Docker镜像构建完成: ${IMAGE_NAME}:${IMAGE_TAG}" echo "✅ Docker镜像构建完成: ${IMAGE_NAME}:${IMAGE_TAG}"
// 验证镜像是否创建成功 // 验证镜像是否创建成功
sh "docker images ${IMAGE_NAME}:${IMAGE_TAG}" sh "docker images ${IMAGE_NAME}:${IMAGE_TAG}" } catch (Exception e) {
} catch (Exception e) { echo "⚠️ Buildx构建失败: ${e.getMessage()}"
echo "⚠️ Docker构建失败: ${e.getMessage()}" echo "🔄 尝试使用传统Docker构建..."
// 清理可能的中间状态,但保留缓存用于下次构建
sh ''' // 备用方案使用传统Docker构建
docker system prune -f || true try {
''' timeout(time: 25, unit: 'MINUTES') {
throw e def image = docker.build("${IMAGE_NAME}:${IMAGE_TAG}", ".")
sh "docker tag ${IMAGE_NAME}:${IMAGE_TAG} ${IMAGE_NAME}:latest"
}
echo "✅ 传统Docker构建完成: ${IMAGE_NAME}:${IMAGE_TAG}"
} catch (Exception fallbackError) {
echo "❌ 传统Docker构建也失败: ${fallbackError.getMessage()}"
sh 'docker system prune -f || true'
throw fallbackError
}
} }
} }
} }

View File

@ -0,0 +1,87 @@
#!/bin/bash
# Jenkins构建测试脚本
# 模拟Jenkins环境测试Docker构建
echo "🚀 Jenkins构建环境测试"
echo "===================="
# 设置变量模拟Jenkins环境变量
export IMAGE_NAME="jenkins-demo"
export IMAGE_TAG="test"
echo "📋 测试环境:"
echo " 镜像名称: ${IMAGE_NAME}"
echo " 镜像标签: ${IMAGE_TAG}"
# 1. 清理旧镜像
echo "🧹 清理旧镜像..."
docker image prune -f || true
# 2. 检查Buildx
echo "🔍 检查Buildx..."
echo "✅ 使用已安装的 Docker Buildx $(docker buildx version)"
# 3. 管理构建器
echo "🏗️ 管理构建器..."
if ! docker buildx inspect jenkins-builder >/dev/null 2>&1; then
echo "创建新的构建器实例..."
docker buildx create --name jenkins-builder --use --bootstrap
else
echo "使用现有构建器实例..."
docker buildx use jenkins-builder
fi
# 验证构建器状态
docker buildx inspect jenkins-builder
# 4. 执行构建
echo "🐳 开始构建Docker镜像..."
cd "$(dirname "$0")/.."
docker buildx build \
--builder jenkins-builder \
--platform linux/amd64 \
--cache-from type=local,src=/tmp/.buildx-cache \
--cache-to type=local,dest=/tmp/.buildx-cache-new,mode=max \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--load \
-t ${IMAGE_NAME}:${IMAGE_TAG} \
-t ${IMAGE_NAME}:latest \
.
# 检查构建结果
if [ $? -eq 0 ]; then
echo "✅ Docker镜像构建完成: ${IMAGE_NAME}:${IMAGE_TAG}"
# 验证镜像
docker images ${IMAGE_NAME}:${IMAGE_TAG}
# 测试运行
echo "🧪 测试运行镜像..."
docker run --rm -d --name test-container -p 18080:8080 ${IMAGE_NAME}:${IMAGE_TAG}
# 等待启动
sleep 10
# 健康检查
if curl -f http://localhost:18080/api/health 2>/dev/null; then
echo "✅ 应用启动成功,健康检查通过"
else
echo "⚠️ 健康检查失败,但镜像构建成功"
fi
# 停止测试容器
docker stop test-container || true
else
echo "❌ Docker镜像构建失败"
exit 1
fi
# 5. 移动缓存
echo "📦 管理构建缓存..."
rm -rf /tmp/.buildx-cache || true
mv /tmp/.buildx-cache-new /tmp/.buildx-cache || true
echo "🎉 测试完成!"

View File

@ -0,0 +1,54 @@
#!/bin/bash
# Docker镜像加速器配置脚本
# 用于解决从Docker Hub拉取镜像超时的问题
echo "🔧 配置Docker镜像加速器..."
# 创建docker配置目录
sudo mkdir -p /etc/docker
# 备份原有配置(如果存在)
if [ -f /etc/docker/daemon.json ]; then
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.backup
echo "✅ 已备份原有配置文件"
fi
# 配置多个镜像加速器(提高可用性)
cat << 'EOF' | sudo tee /etc/docker/daemon.json
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com",
"https://hub-mirror.c.163.com"
],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"insecure-registries": [],
"live-restore": true
}
EOF
echo "✅ Docker配置文件已更新"
# 重启Docker服务
echo "🔄 重启Docker服务..."
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
echo "🔍 验证Docker配置..."
sudo systemctl status docker --no-pager -l
docker info | grep -A 10 "Registry Mirrors"
echo "✅ Docker镜像加速器配置完成"
echo "📝 配置的镜像源:"
echo " - 腾讯云: https://mirror.ccs.tencentyun.com"
echo " - Azure中国: https://dockerhub.azk8s.cn"
echo " - 七牛云: https://reg-mirror.qiniu.com"
echo " - 网易: https://hub-mirror.c.163.com"

View File

@ -0,0 +1,54 @@
#!/bin/bash
# Docker镜像加速器配置脚本
echo "🔧 配置Docker镜像加速器..."
# 备份原有配置
if [ -f /etc/docker/daemon.json ]; then
echo "备份现有配置到 /etc/docker/daemon.json.backup"
cp /etc/docker/daemon.json /etc/docker/daemon.json.backup
fi
# 创建daemon.json配置文件
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://drzsd1vw.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=systemd"],
"live-restore": true,
"features": {
"buildkit": true
}
}
EOF
echo "✅ 配置文件已创建:"
cat /etc/docker/daemon.json
echo ""
echo "🔄 重启Docker服务..."
systemctl daemon-reload
systemctl restart docker
echo ""
echo "⏳ 等待Docker服务启动..."
sleep 5
echo ""
echo "🔍 验证配置..."
docker info | grep -A 10 "Registry Mirrors"
docker version
echo ""
echo "✅ Docker镜像加速器配置完成"
echo "💡 您可以运行以下命令测试:"
echo " docker pull hello-world"

59
scripts/test-buildx.sh Normal file
View File

@ -0,0 +1,59 @@
#!/bin/bash
# Docker Buildx 测试脚本
# 用于验证Buildx安装和配置
echo "🔍 Docker Buildx 测试脚本"
echo "========================="
# 1. 检查Docker版本
echo "📦 Docker版本:"
docker --version
# 2. 检查Buildx版本
echo "🛠️ Buildx版本:"
docker buildx version
# 3. 列出现有构建器
echo "📋 现有构建器:"
docker buildx ls
# 4. 测试创建简单构建器
echo "🏗️ 测试创建构建器..."
if docker buildx create --name test-builder --use --bootstrap; then
echo "✅ 构建器创建成功"
# 检查构建器状态
echo "📊 构建器详情:"
docker buildx inspect test-builder
# 清理测试构建器
echo "🧹 清理测试构建器..."
docker buildx rm test-builder
echo "✅ 测试完成"
else
echo "❌ 构建器创建失败"
fi
# 5. 测试简单构建
echo "🐳 测试简单Docker构建..."
mkdir -p /tmp/buildx-test
cat > /tmp/buildx-test/Dockerfile << 'EOF'
FROM alpine:latest
RUN echo "Buildx test successful" > /test.txt
CMD cat /test.txt
EOF
cd /tmp/buildx-test
if docker buildx build --platform linux/amd64 -t buildx-test . --load; then
echo "✅ Buildx构建测试成功"
docker run --rm buildx-test
docker rmi buildx-test
else
echo "❌ Buildx构建测试失败"
fi
# 清理
rm -rf /tmp/buildx-test
echo "🎉 测试完成!"

View File

@ -0,0 +1,73 @@
#!/bin/bash
# Docker构建测试脚本
echo "🧪 测试Docker构建环境..."
echo ""
echo "1. 检查Docker版本:"
docker --version
echo ""
echo "2. 检查Docker Buildx:"
docker buildx version
echo ""
echo "3. 检查Docker daemon配置:"
if [ -f /etc/docker/daemon.json ]; then
echo "✅ daemon.json存在:"
cat /etc/docker/daemon.json
else
echo "⚠️ daemon.json不存在建议运行 setup-docker-mirrors.sh"
fi
echo ""
echo "4. 检查Docker镜像加速器:"
docker info | grep -A 5 "Registry Mirrors" || echo "❌ 未配置镜像加速器"
echo ""
echo "5. 测试基础镜像拉取:"
echo "正在测试拉取 hello-world 镜像..."
if docker pull hello-world; then
echo "✅ 基础镜像拉取成功"
docker run --rm hello-world
else
echo "❌ 基础镜像拉取失败"
fi
echo ""
echo "6. 测试 amazoncorretto 镜像拉取:"
echo "正在测试拉取 amazoncorretto:17-alpine-jdk 镜像..."
if timeout 300 docker pull amazoncorretto:17-alpine-jdk; then
echo "✅ amazoncorretto镜像拉取成功"
else
echo "❌ amazoncorretto镜像拉取失败或超时"
fi
echo ""
echo "7. 检查Buildx构建器:"
if docker buildx inspect jenkins-builder >/dev/null 2>&1; then
echo "✅ jenkins-builder构建器存在"
docker buildx inspect jenkins-builder
else
echo "⚠️ jenkins-builder构建器不存在将创建新的"
docker buildx create --name jenkins-builder --use --bootstrap
fi
echo ""
echo "8. 测试简单构建:"
cat > /tmp/test-dockerfile << 'EOF'
FROM hello-world
LABEL test=true
EOF
if docker buildx build --platform linux/amd64 --load -t test-build -f /tmp/test-dockerfile /tmp; then
echo "✅ 简单构建测试成功"
docker rmi test-build >/dev/null 2>&1
else
echo "❌ 简单构建测试失败"
fi
rm -f /tmp/test-dockerfile
echo ""
echo "🏁 测试完成!"

62
scripts/verify-buildx.sh Normal file
View File

@ -0,0 +1,62 @@
#!/bin/bash
echo "==============================================="
echo "🔍 Docker Buildx 环境验证脚本"
echo "==============================================="
# 检查Docker版本
echo "📋 Docker版本:"
docker --version
# 检查Buildx版本
echo ""
echo "📋 Docker Buildx版本:"
docker buildx version
# 检查当前构建器
echo ""
echo "📋 当前构建器列表:"
docker buildx ls
# 检查是否存在jenkins-builder
echo ""
echo "📋 检查jenkins-builder构建器:"
if docker buildx inspect jenkins-builder >/dev/null 2>&1; then
echo "✅ jenkins-builder 构建器已存在"
docker buildx inspect jenkins-builder
else
echo "❌ jenkins-builder 构建器不存在,将创建新的"
docker buildx create --name jenkins-builder --use --bootstrap
echo "✅ jenkins-builder 构建器创建完成"
fi
# 检查BuildKit功能
echo ""
echo "📋 测试Buildx功能:"
echo "FROM alpine:latest" > /tmp/test.dockerfile
echo "RUN echo 'Hello BuildKit!'" >> /tmp/test.dockerfile
if docker buildx build -f /tmp/test.dockerfile -t buildx-test . >/dev/null 2>&1; then
echo "✅ Buildx构建测试成功"
docker rmi buildx-test >/dev/null 2>&1
else
echo "❌ Buildx构建测试失败"
fi
# 清理测试文件
rm -f /tmp/test.dockerfile
# 检查缓存目录
echo ""
echo "📋 缓存目录状态:"
if [ -d "/tmp/.buildx-cache" ]; then
cache_size=$(du -sh /tmp/.buildx-cache 2>/dev/null | cut -f1)
echo "✅ 缓存目录存在,大小: $cache_size"
else
echo "📁 缓存目录不存在(正常,首次构建会创建)"
fi
echo ""
echo "==============================================="
echo "✅ Docker Buildx 环境验证完成"
echo "==============================================="