前提
Python、Node.js、Go项目使用docker构建镜像的时候,在有 Docker cache 的情况下,连续构建镜像的速度是可以很快的。
一般的优化方式是先安装依赖模块,然后再编译打包代码库。这样安装依赖的 image layer 可以被 Docker 缓存,下次再构建就不用安装依赖。
但目前主流的java打包(这里不说像GraalVM等技术)方式都是将源码和依赖包打在一起, 这导致无法充分利用缓存层加快镜像的构建速度
思路
按照node项目打包思路, 先copy package*文件进行构建, 再copy源码
先弄一份初始化springboot start工程放在所需项目里
然后需要写两份dockerfile文件
第一份用来copy springboot start工程以及pom文件
然后执行maven命令打包, 这里我们不需要源码正确与否, 因为我们已经将pom内的jar包打到了本地
第二份dockerfile以第一份镜像为基准,
将基础镜像的springboot start工程删掉
然后把源项目工程copy过来,再进行打包
这个时候再打包会优先从本地基础镜像下载, 所以速度会很快
操作
这里以gitlab-runner的cicd举例
gitlab-ci.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| build-release: stage: build variables: IMAGE: release/${CI_PROJECT_NAME}:v${CI_PIPELINE_ID} BASIC_IMAGE: release/basic-${CI_PROJECT_NAME}:v${CI_PIPELINE_ID} script: - echo "Building application..." - echo "$REGISTRY_PASSWORD" | sudo docker login -u ${REGISTRY_USERNAME} --password-stdin ${REGISTRY_ADDRESS} - echo "registry login success" - echo "构建基础镜像..." - sudo BUILDKIT_INLINE_CACHE=1 docker build -f Dockerfile-light -t ${REGISTRY_ADDRESS}/${BASIC_IMAGE} . - echo "构建项目" - sudo BUILDKIT_INLINE_CACHE=1 docker build --build-arg IMG="${REGISTRY_ADDRESS}/${BASIC_IMAGE}" -t ${REGISTRY_ADDRESS}/${IMAGE} . - sudo docker push ${REGISTRY_ADDRESS}/${IMAGE} - echo "docker push && push success"
|
第一份dockerfile: Dockerfile-light
1 2 3 4 5 6 7 8 9
|
FROM maven:3.8.3-openjdk-8 WORKDIR /user/src/app COPY settings.xml ~/.m2/settings-docker.xml COPY settings.xml /usr/share/maven/conf/settings.xml COPY ./pom.xml pom.xml COPY ./light/src ./src RUN mvn dependency:resolve && mvn clean package -DskipTests
|
第二份dockerfile: Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
ARG IMG FROM ${IMG} as build WORKDIR /user/src/app RUN rm -rf ./src COPY . . RUN mvn clean package -DskipTests FROM openjdk:8-alpine as runtime WORKDIR /user/src/app RUN set -eux \ && apk add --no-cache tzdata \ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && apk del tzdata ARG JAR_FILE=/user/src/app/target/*.jar ENV JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom" COPY --from=build ${JAR_FILE} app.jar CMD ["sh","-c","java -jar app.jar ${JAVA_OPTS}"]
|