perf: 优化 CI Docker 镜像构建速度
- 新增 CI 精简 Dockerfile,直接打包 drone 预编译 jar,避免在 Docker 内重复编译(省去 npm ci + mvn 全量编译 ~15min) - build-docker-image 步骤改用精简 Dockerfile,去掉无效的 docker pull 缓存尝试 - maven-build 步骤优化:动态检测 CPU 核数设置并行度 -T 1C/2C、增加 JVM 内存、添加 --fail-at-end - .dockerignore 优化:CI Dockerfile 仅需 par-api/target/*.jar,排除所有源码/pom/前端文件 - par-api/Dockerfile 标注为独立多阶段构建版本(本地使用) 参考 mediabot 项目的多阶段构建思路,但将编译前置到 drone host 缓存中,Docker 构建秒级完成
This commit is contained in:
@@ -1,17 +1,20 @@
|
||||
# 构建产物
|
||||
target/
|
||||
*/target/
|
||||
# 构建产物(jar 除外 — CI Dockerfile 需要拷贝 par-api/target/*.jar)
|
||||
web/node_modules/
|
||||
web/dist/
|
||||
par-common/target/
|
||||
par-core/target/
|
||||
# 注意:不排除 par-api/target/,因为 CI Dockerfile 需要其中的 jar
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
*.iml
|
||||
.vscode/
|
||||
.codebuddy/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# 文档
|
||||
README.md
|
||||
@@ -31,6 +34,22 @@ run.sh
|
||||
.drone.yml
|
||||
docker-compose.yml
|
||||
|
||||
# 项目文件(Docker 上下文不需要)
|
||||
pom.xml
|
||||
par-*/pom.xml
|
||||
|
||||
# Java 源码(CI Dockerfile 不需要)
|
||||
par-common/src/
|
||||
par-core/src/
|
||||
par-api/src/
|
||||
|
||||
# 前端源码(CI Dockerfile 不需要)
|
||||
web/
|
||||
|
||||
# 其他
|
||||
*.md
|
||||
*.log
|
||||
*.iml
|
||||
*.class
|
||||
*.jar
|
||||
!par-api/target/*.jar
|
||||
|
||||
39
.drone.yml
39
.drone.yml
@@ -98,7 +98,7 @@ steps:
|
||||
image: 192.168.31.253/library/maven-java21:3.9.9-alpine
|
||||
pull: if-not-exists
|
||||
environment:
|
||||
MAVEN_OPTS: "-Dmaven.repo.local=/root/.m2/repository -Xms256m -Xmx512m"
|
||||
MAVEN_OPTS: "-Dmaven.repo.local=/root/.m2/repository -Xms512m -Xmx1024m -Djava.awt.headless=true -Dmaven.compiler.forceJavacCompilerUse=true"
|
||||
volumes:
|
||||
- name: maven-cache
|
||||
path: /root/.m2
|
||||
@@ -143,12 +143,24 @@ steps:
|
||||
echo "BUILD_DATE=$(TZ=Asia/Shanghai date +%Y%m%d)" >> /drone/src/.version.env
|
||||
echo "发布版本: $RELEASE_VERSION, 构建版本: $BUILD_VERSION"
|
||||
|
||||
# Maven 打包(使用阿里云镜像)
|
||||
# 检测可用 CPU 核数,动态设置 Maven 并行度
|
||||
CPU_CORES=$(nproc 2>/dev/null || echo 4)
|
||||
echo "检测到 $CPU_CORES 个 CPU 核心"
|
||||
if [ "$CPU_CORES" -ge 4 ]; then
|
||||
MVN_THREADS="2C"
|
||||
else
|
||||
MVN_THREADS="1C"
|
||||
fi
|
||||
echo "Maven 并行度: -T $MVN_THREADS"
|
||||
|
||||
# Maven 打包(使用阿里云镜像 + 多线程并行编译 + 跳过测试 + 离线优先)
|
||||
mvn -B clean package \
|
||||
-s /root/.m2/settings.xml \
|
||||
-DskipTests \
|
||||
-T 1C \
|
||||
--no-transfer-progress
|
||||
-Dmaven.test.skip=true \
|
||||
-T "$MVN_THREADS" \
|
||||
--no-transfer-progress \
|
||||
--fail-at-end
|
||||
|
||||
JAR_FILE=$(ls par-api/target/*.jar | head -1)
|
||||
echo "构建成功!产物: $JAR_FILE ($(du -sh $JAR_FILE | cut -f1))"
|
||||
@@ -157,6 +169,8 @@ steps:
|
||||
- frontend-build
|
||||
|
||||
# ===================== Docker 镜像构建 =====================
|
||||
# 参考 mediabot 优化:Drone 已在前序步骤完成编译(frontend-build + maven-build),
|
||||
# 此处使用 CI 精简 Dockerfile,仅将预构建 jar 打包进 JRE 镜像,无需在 Docker 内重新编译。
|
||||
- name: build-docker-image
|
||||
image: 192.168.31.253/library/docker:cli
|
||||
volumes:
|
||||
@@ -176,21 +190,22 @@ steps:
|
||||
fi
|
||||
echo "版本: $APP_VERSION"
|
||||
|
||||
# 拉取之前的镜像作为缓存来源(加速 layer 复用)
|
||||
echo "正在拉取缓存镜像..."
|
||||
docker pull "$IMAGE_NAME:latest" 2>/dev/null || true
|
||||
docker pull "$LOCAL_HARBOR_REG/$LOCAL_HARBOR_PROJ/$IMAGE_NAME:latest" 2>/dev/null || true
|
||||
# 验证 jar 产物存在
|
||||
JAR_FILE=$(ls par-api/target/*.jar 2>/dev/null | head -1)
|
||||
if [ -z "$JAR_FILE" ]; then
|
||||
echo "错误:未找到 jar 产物,maven-build 可能失败"
|
||||
exit 1
|
||||
fi
|
||||
echo "jar 产物: $JAR_FILE ($(du -sh $JAR_FILE | cut -f1))"
|
||||
|
||||
# 使用 BuildKit 构建,启用缓存
|
||||
# 使用 CI 精简 Dockerfile:仅 COPY jar + 设置运行环境,秒级完成
|
||||
docker build \
|
||||
--cache-from "$IMAGE_NAME:latest" \
|
||||
--cache-from "$LOCAL_HARBOR_REG/$LOCAL_HARBOR_PROJ/$IMAGE_NAME:latest" \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg VERSION="$APP_VERSION" \
|
||||
--build-arg BUILD_TIME="$(TZ=Asia/Shanghai date '+%Y-%m-%d %H:%M')" \
|
||||
-t "$IMAGE_NAME:$BUILD_VERSION" \
|
||||
-t "$IMAGE_NAME:latest" \
|
||||
-f par-api/Dockerfile \
|
||||
-f Dockerfile \
|
||||
.
|
||||
|
||||
echo "Docker 镜像构建完成。"
|
||||
|
||||
38
Dockerfile
Normal file
38
Dockerfile
Normal file
@@ -0,0 +1,38 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# PAR Server - CI 专用精简镜像
|
||||
# 参考 mediabot 的优化思路:Drone 流水线已完成编译,此处仅打包产物
|
||||
# 完整多阶段构建版本见 par-api/Dockerfile(适用于本地独立构建)
|
||||
|
||||
FROM 192.168.31.253/library/eclipse-temurin:21-jre-alpine
|
||||
|
||||
ARG VERSION=unknown
|
||||
ARG BUILD_TIME=unknown
|
||||
ARG BUILDKIT_INLINE_CACHE=1
|
||||
|
||||
LABEL maintainer="PAR Team"
|
||||
LABEL description="PT Adapter Registry Server"
|
||||
LABEL version="${VERSION}"
|
||||
LABEL build-time="${BUILD_TIME}"
|
||||
|
||||
# 创建非 root 用户
|
||||
RUN addgroup -S par && adduser -S par -G par
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 创建静态文件目录
|
||||
RUN mkdir -p /app/static/configs && chown -R par:par /app
|
||||
|
||||
# 直接复制 drone 已构建好的 jar(无需在 Docker 内重新编译)
|
||||
COPY par-api/target/*.jar app.jar
|
||||
|
||||
USER par
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8080
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
|
||||
CMD wget -qO- http://localhost:8080/health || exit 1
|
||||
|
||||
# 启动参数
|
||||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||
@@ -1,6 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# PAR Server - 前后端一体化 Docker 镜像
|
||||
# 参考 mediabot 的多阶段构建方式
|
||||
# PAR Server - 前后端一体化 Docker 镜像(完整多阶段构建)
|
||||
# 参考 mediabot 的多阶段构建方式,适用于本地独立构建(不依赖 Drone CI 预编译)
|
||||
# CI 流水线请使用项目根目录的 Dockerfile(精简版,仅打包 drone 预编译产物)
|
||||
# 启用 BuildKit 以支持 cache mount
|
||||
|
||||
# 第一阶段:构建前端
|
||||
|
||||
Reference in New Issue
Block a user