赛尔校园公共服务平台 Logo
平台使用
阿里云
百度云
移动云
智算服务
教育生态
登录 →
赛尔校园公共服务平台 Logo
平台使用 阿里云 百度云 移动云 智算服务 教育生态
登录
  1. 首页
  2. 阿里云
  3. 容器镜像服务
  4. 实践教程
  5. Java项目容器化构建最佳实践

Java项目容器化构建最佳实践

  • 实践教程
  • 发布于 2025-04-18
  • 0 次阅读
文档编辑
文档编辑

使用Dockerfile将源代码构建成容器镜像,进行镜像分发、部署。相比于Golang或Python项目,Java项目因企业一般会选择自建依赖仓库(如Maven)导致容器化构建难度高,因不熟悉Dockerfile缓存机制导致构建速度较慢。本文从典型用户场景(云上自建GitLab代码仓库、自建Maven仓库)出发,介绍如何利用Dockerfile构建Java项目,如何提速构建过程以及如何利用ACR-EE构建服务来进行自动化镜像构建。

前提条件

  • 已创建GitLab代码仓库。

  • 已创建Maven仓库。本文选择云效Maven仓库,更多内容,请参见云效Maven仓库。

  • 已创建ACR-EE企业版,更多内容,请参见创建企业版实例。

项目介绍

本文使用具有依赖的两个Java项目进行演示。分别有以下两个项目:

  • Provider:提供服务,供调用。

    • Core模块:提供公共接口。

    • Service模块:服务实现模块。

  • Consumer:调用Provider服务。

    • Service模块:需要依赖Provide项目里的Core模块。参考代码如下:

      .
      ├── consumer
      │ ├── Dockerfile
      │ ├── consumer.iml
      │ ├── pom.xml
      │ └── service
      │     ├── pom.xml
      │     ├── src
      │     └── target
      └── provider
          ├── Dockerfile
          ├── core
          │ ├── pom.xml
          │ ├── src
          │ └── target
          ├── pom.xml
          ├── provider.iml
          └── service
              ├── pom.xml
              ├── src
              └── target

构建产物:

  • 基于Provider工程构建出生产者应用镜像。

  • 基于Consumer工程构建出消费者应用镜像。

步骤一:确定公共依赖包已上传

项目引用的公共依赖包需要提前上传到自建Maven仓库。以这里的Provider为例,您可以在Provider目录下执行以下上传命令:

mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests

步骤二:制作专属Maven基础镜像

为了在容器化构建环境内能访问到自建Maven仓库,需要把Maven仓库配置放到基础镜像内。这里建议基于官方Maven镜像来打造您的企业专属公共Maven基础镜像,应用项目直接引用该基础镜像即可访问Maven仓库。

  1. 将以下文件保存成Dockerfile并和Maven仓库的《settings.xml》文件放到同一目录。

    FROM maven:3.8-openjdk-8 #指定与项目匹配的Maven镜像,该示例环境为3.8版本的Maven。
    
    ADD settings.xml /root/.m2/ #将自建Maven仓库配置放到对应位置。
  2. 执行以下命令构建并推送到远程镜像仓库。

    ls
    Dockerfile   settings.xml
    
    docker build -t demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 -f Dockerfile .
    Sending build context to Docker daemon   7.68kB
    Step 1/2 : FROM maven:3.8-openjdk-8
     ---> a3f42bfde036
    Step 2/2 : ADD settings.xml /root/.m2/
     ---> db0d5a5192e3
    Successfully built db0d5a5192e3
    Successfully tagged demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8
    
    docker push demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8

步骤三:构建Consumer应用镜像(Provider项目略过)

执行以下命令。(建议将构建过程中需要的基础镜像全部推送到阿里云镜像仓库。)

FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder

# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./service service/

# package jar
RUN mvn clean package

# Second stage: minimal runtime environment
From demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine

# copy jar from the first stage
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar

EXPOSE 8080

CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]

步骤四:优化构建速度

在步骤三:构建Consumer应用镜像(Provider项目略过)中,您已经能构建出镜像,但是当您修改代码、重复构建时会发现每次都会重复拉取JAR包,而无法利用到JAR包缓存,构建速度比较缓慢。这是因为Dockerfile有自己的缓存生效机制,当修改源代码后,ADD指令内的文件内容hash后出现了值变化导致RUN指令需要重新构建,没办法利用到先前的构建结果缓存。更多内容,请参见关于缓存和Dockerfile最佳实践。

我们优化构建速度的思路是将Maven依赖能缓存并重复利用:

  1. 首先将项目的《pom.xml》文件拷贝进容器,下载依赖。只要项目不改动《pom.xml》文件,后续构建都能利用到缓存。

  2. 拷贝项目的源码并编译。

一个改进的Dockerfile如下所示,项目首次构建耗时43s,后续如果仅仅是改动源代码构建时间可以缩短到7s。

FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder

# To resolve dependencies in a safe way (no re-download when the source code changes)
ADD ./pom.xml pom.xml
ADD ./service/pom.xml service/pom.xml
RUN  mvn install

ADD ./service service/

# package jar
RUN mvn clean package

# Second stage: minimal runtime environment
From demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine

# copy jar from the first stage
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar

EXPOSE 8080

CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]

步骤五:基于ACR-EE的自动化构建流程

ACR-EE提供了企业级构建服务能力,推荐企业客户使用,更多内容,请参见使用企业版实例构建镜像。

以下将为您介绍几个在使用过程中会用到的最佳实践。

  • 使用VPC内网构建模式

    针对云上自建GitLab,建议使用VPC内网安全构建模式来构建镜像, 避免向公网暴露服务。更多内容,请参见使用VPC安全构建模式构建容器镜像。

  • 使用镜像版本不可变功能

    推荐仓库打开版本不可变功能,以防止线上版本被覆盖。创建镜像仓库

  • 创建基于Commit ID的构建规则

    每次构建生成两个镜像版本,一个版本使用代码Commit ID来表示,方便镜像版本和代码版本对应起来;另一个版本使用latest表示最新版本。修改构建规则

    提交代码并触发构建。下图是提交两次代码后自动触发的两次构建过程,每次都生成了两个镜像,并且因为缓存命中加速原因,第二次构建更快。1

相关文章

使用OCI v1.1.0规范管理和关联容器镜像及其衍生制品 2025-04-18 15:15

从2024年04月起,新创建的ACR企业版实例将支持OCI的Image和Distribution规范v1.1.0,包括对Reference Types的支持。这意味着您除了可以存储和分发容器镜像外,还能管理和分发非容器镜像内容的OCI制品,如镜像签名和软件物料清单(SBOM)。这使您能够像管理容器镜

使用触发器构建容器DevOps 2025-04-18 15:15

通过容器镜像服务可以便捷地构建基于容器的DevOps开发环境。本文介绍如何使用触发实现镜像代码被修改后,自动触发镜像构建,且自动触发容器服务上应用的重新部署。 前提条件 已绑定企业版实例与阿里云Codeup代码平台。<

使用Jenkins实现镜像的CICD 2025-04-18 15:15

若您期望实现从源代码自动构建、推送镜像到最终部署应用的一体化自动化操作。您可以使用Jenkins实现镜像的CI/CD,只要您在GitLab中提交源代码,容器镜像会自动使用源代码构建镜像,容器服务会自动拉取镜像部署应用,并自动发送事件通知到钉钉群。 前提条件

Java项目容器化构建最佳实践 2025-04-18 15:15

使用Dockerfile将源代码构建成容器镜像,进行镜像分发、部署。相比于Golang或Python项目,Java项目因企业一般会选择自建依赖仓库(如Maven)导致容器化构建难度高,因不熟悉Dockerfile缓存机制导致构建速度较慢。本文从典型用户场景(云上自建GitLab代码仓库、自建Mave

在Dockerfile中使用构建打包镜像并运行 2025-04-18 15:15

通过使用多阶段构建应用以及结合阿里云容器镜像服务(ACR)的镜像构建服务,可以使Java应用具有构建安全、构建速度快、镜像文件体积小等优点。 前提条件

本地构建和推送多架构镜像到容器镜像服务 2025-04-18 15:15

使用ARM架构资源部署容器通常可以节省不少成本,但也可能导致维护成本增加,您可能需要面向x86、ARM架构分别构建镜像并设置不同的Tag。您可以使用docker buildx来构建多架构镜像,并通过docker manifest实现一个Tag管理多架构的容器镜像。 前提条件

目录
Copyright © 2025 your company All Rights Reserved. Powered by 赛尔网络.
京ICP备14022346号-15
gongan beian 京公网安备11010802041014号