1、概览 本文将带你了解如何利用 Docker 的多阶段构建功能高效地为多模块 Maven 项目构建 Docker 镜像,,以充分利用 Docker 的缓存机制。
然后,还会介绍 Google Jib Maven 插件,用于在没有 Dockerfile 或 Docker 的情况下构建 Docker 镜像。
2、多模块 Maven 项目 多模块 Maven 应用由不同功能的独立模块组成。Maven 通过管理依赖关系来构建应用,并将这些模块组装成一个可部署的单元。
在本文的代码示例中,我们将使用一个包含两个 Maven 模块的基本 Spring Boot 项目,这两个模块分别代表应用程序的 Domain 和 API。
Maven 项目的结构如下:
+-- parent +-- api | `-- src | `-- pom.xml +-- domain | `-- src | `-- pom.xml `-- pom.xml 查看父模块的 pom.xml 文件,就会发现它继承了 spring-boot-starter-parent,并包含了 domain 和 api 模块:
<project> <groupId>com.baeldung.docker-multi-module-maven</groupId> <artifactId>parent</artifactId> <packaging>pom</packaging> <version>0.
1、概览 随着越来越多的企业转向使用容器,Docker 在软件开发中的地位也越来越重要。为此,Spring Boot 2.3 的一大新功能就是为 Spring Boot 应用轻松创建 Docker 镜像提供了支持。
本文将带你了解如何为 Spring Boot 应用创建 Docker 镜像。
2、传统的 Docker 构建 使用 Spring Boot 构建 Docker 镜像的传统方法是使用 Dockerfile。
下面是一个简单的 Dockerfile 示例:
FROM openjdk:8-jdk-alpine EXPOSE 8080 ARG JAR_FILE=target/demo-app-1.0.0.jar ADD ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"] 然后,使用 docker build 命令创建 Docker 镜像。这对大多数应用都很有效,但也有一些缺点。
首先,我们使用的是 Spring Boot 创建的 Fat jar。这会影响启动时间,尤其是在容器化环境中。我们可以通过添加 Jar 文件的解压内容来节省启动时间。
其次,Docker 镜像是分层构建的。Spring Boot Fat Jar 的性质导致所有应用代码和第三方库都被放在一个层中。这意味着,即使只有一行代码发生变化,也必须重建整个层。
通过在构建之前解压 Jar 文件,应用代码和第三方库分别有自己的层。这使我们能够利用 Docker 的缓存机制,当更改一行代码时,只需要重新构建相应的层。
有了这个理念,让我们看看 Spring Boot 如何改进创建 Docker 镜像的过程。
1、简介 Docker 是创建独立应用的事实标准。从 2.3.0 版开始,Spring Boot 包含了多项增强功能,可帮助我们创建高效的 Docker 镜像。例如:它允许将应用分解成不同的层。
换句话说,源代码位于自己的层中。因此,它可以独立重建,从而提高效率并缩短启动时间。本文将带你了解如何利用 Spring Boot 重用 Docker 层。
2、Docker 中的分层 jar Docker 容器由基础镜像和额外的层组成。一旦层构建完成,它们将保持缓存状态。因此,后续的生成速度会更快:
对底层层级的更改也会重新构建上层层级。因此,不经常更改的层级应保持在底部,而经常更改的层级应放在顶部。
同样,Spring Boot 允许将工件(构建产物)内容映射到层中。默认的层映射如下:
你可以看到,应用有自己的层。修改源代码时,只会重新构建独立的层。loader 和依赖保持缓存,从而减少了 Docker 镜像的创建和启动时间。接下来看看如何使用 Spring Boot 实现这一点!
3、Spring Boot 创建高效的 Docker 镜像 在传统的构建 Docker 镜像的方式中,Spring Boot使用的是 “fat jar” 方法。一个工件就包含了所有依赖项和应用源代码。因此,源代码的任何变化都会迫使我们重建整个层。
3.1、Spring Boot 分层配置 Spring Boot 2.3.0 版引入了两个新功能来改进 Docker 镜像的生成:
Buildpack 支持提供了应用的 Java 运行时环境,因此现在可以跳过 Dockerfile,并自动构建 Docker 镜像。 分层 JAR 可以帮助我们最大限度地利用 Docker 层的生成 在本文中,我们将对分层 JAR 方法进行扩展。
首先,在 Maven 中设置分层 JAR 。在打包工件时,生成层。
1、概览 本文将带你了解如何使用 Docker Compose 来运行 Spring Boot 和 PostgreSQL。
2、创建 Spring Boot 应用 从 Spring Initializer 创建 Spring Boot 项目,添加 PostgreSQL 驱动和 Spring Data JPA 依赖。下载生成的 ZIP 文件并解压到文件夹后,就可以运行应用了:
./mvnw spring-boot:run 应用启动失败,因为连接数据库失败:
*************************** APPLICATION FAILED TO START *************************** Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class 3、Dockerfile 在使用 Docker Compose 启动 PostgreSQL 之前,需要将 Spring Boot 应用转化为 Docker 镜像。第一步是将应用打包为 JAR 文件:
1、简介 在容器化大行其道的今天,越来越多人选择把 Spring Boot 应用部署到 Docker 中。
本文将带你了解在 Docker 容器中启动 Spring Boot 应用时,如何设置其 Profile。
2、基本的 Dockerfile 一般来说,要容器化 Spring Boot 应用,只需提供一个 Dockerfile。
Spring Boot 应用的最小 Dockerfile,如下:
FROM openjdk:11 COPY target/*.jar app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] 然后,可以通过 docker build 来构建 Docker 镜像:
docker build --tag=docker-with-spring-profile:latest . 接着,我们就可以通过 docker-with-spring-profile 镜像运行应用了:
docker run docker-with-spring-profile:latest 你可以注意到,Spring Boot 应用以 “default” Profile 启动:
2022-04-22 22:34:25.268 INFO 1 --- [main] c.b.docker.spring.DemoApplication: Starting DemoApplication using Java 11.0.14.1 on ea8851bea75f with PID 1 (/app.
1、简介 GraalVM 使用其 Ahead-Of-Time(AOT)编译器将 Java 应用程序编译为机器可执行文件。这些可执行文件直接在目标机器上执行,而无需使用即时编译器 (JIT)。GraalVM生成的二进制文件体积较小,启动速度快,并且在没有任何预热的情况下提供最佳性能。此外,这些可执行文件相比在 JVM 上运行的应用程序而言,内存占用和 CPU 使用率较低。
通过 Docker,我们可以将软件组件打包成 Docker Image,并作为 Docker 容器运行。Docker 容器包含应用程序运行所需的一切,包括应用程序代码、运行时、系统工具和库。
在本教程中,我们将了解如何创建 Java 应用程序的 GraalVM 原生(native)镜像,以及如何将该原生镜像用作 Docker 镜像,并将其作为 Docker 容器运行。
2、原生镜像是什么? 原生镜像(Native Image)是一种将 Java 代码提前编译成原生可执行文件的技术。该原生可执行文件只包含运行时需要执行的代码。这包括应用程序类、标准库类、语言运行时和 JDK 中静态链接的本地代码。
原生镜像生成器(Native Image Builder)会扫描应用程序类和其他元数据,以创建一个特定于操作系统和体系结构的二进制文件。本地镜像工具会执行静态应用程序代码分析,以确定应用程序运行时可访问的类和方法。然后,它将所需的类、方法和资源编译成二进制可执行文件。
3、原生镜像的优点 原生镜像可执行文件有几个好处:
由于原生镜像生成器只编译运行时所需的资源,因此可执行文件的体积很小 本地可执行文件的启动时间极短,因为它们是在目标机器中直接执行的,无需使用 JIT 编译器 由于只打包所需的应用程序资源,暴漏的攻击面较小 将其打包为轻量级容器镜像(如 Docker Image),有助于快速高效地部署 4、构建 GraalVM 原生镜像 在本节中,我们将为 Spring Boot 应用构建 GraalVM 原生镜像。首先,需要安装 GraalVM 并设置 JAVA_HOME 环境变量。其次,创建一个包含 Spring Web 和 GraalVM Native Support 依赖的 Spring Boot 应用:
1、简介 在本教程中,我们将了解如何把使用 Spring Boot 创建的 Java 应用作为 Docker 容器运行,具体来说,我们将在 Alpaquita Linux 上使用 Liberica JDK 来创建运行我们应用的 Docker 镜像。
Liberica JDK 和 Alpaquita Linux 是 BellSoft 产品的一部分。BellSoft 的愿景是使 Java 成为云原生应用程序的首选语言。
2、简单的 Spring Boot 应用 先用 Java 创建一个简单的应用,然后将其容器化。通过 Spring Boot,我们只需进行最少的配置,就能轻松创建基于 Spring 的独立生产级应用。
初始化 Spring Boot 应用的最简单方法是使用 Spring Boot CLI。通过它,可以在命令行中使用 start.springboot.io 创建一个新项目:
$ spring init --build=gradle --dependencies=web spring-bellsoft 如上,添加了 web 依赖,以构建 RESTful API,并将 Apache Tomcat 作为默认的嵌入式容器。选择 Gradle 作为构建工具,默认的语言是 Java。
然后,可以将生成的项目导入 IDE(如 IntelliJ Idea),开始开发应用。
添加一个简单的 REST API,接收一个 Integer 参数,并返回等于或小于该数字的斐波纳契数列:
在本文中,你将学习如何使用 Spring Boot 内置的 Testcontainers 和 Docker Compose 支持,在开发模式下运行外部服务。Spring Boot 在当前的最新版本 3.1 中引入了这些功能,你已经可以在 Spring Boot 应用的测试中利用 Testcontainers。在应用程序启动时运行外部数据库、message broker 或其他外部服务的功能是我一直期待的。尤其是竞争框架 Quarkus 已经提供了名为 Dev Services 的类似功能,这在我的开发过程中非常有用。此外,还有另一个令人兴奋的功能 - 与 Docker Compose 集成。
源代码 如果你想自己尝试,可以查看我的源代码。因为我经常使用 Testcontainers,所以你可以在我的多个仓库中找到示例。下面是我们今天要使用的仓库列表:
https://github.com/piomin/sample-spring-boot-on-kubernetes.git https://github.com/piomin/sample-spring-microservices-advanced.git https://github.com/piomin/sample-spring-kafka-microservices.git 你可以克隆它们,然后按照指导查看如何在开发模式下使用 Spring Boot 内置的 Testcontainers 和 Docker Compose 支持。
在测试中使用 Testcontainers 让我们从标准使用示例开始。第一个仓库中有一个连接 Mongo 数据库的 Spring Boot 应用程序。为了构建自动测试,我们必须包含以下 Maven 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>mongodb</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> 现在,我们可以创建测试了。我们需要用 @Testcontainers 来注解我们的测试类。然后,我们必须声明 MongoDBContainer Bean。在 Spring Boot 3.
1、概览 在本教程中,我们将讨论 Spring Boot 3.1 中引入的增强型 Testcontainers 支持。
这个更新提供了一种更简化的配置容器的方法,并允许我们启动它们进行本地开发。因此,使用 Testcontainers 进行开发和运行测试变得更加无缝和高效。
2、SpringBoot 3.1 之前的 Testcontainers 在测试阶段,我们可以使用 Testcontainers 创建一个类似生产的环境。这样,我们就不需要模拟,就能写出与实现细节无关的高质量自动测试。
在本文的代码示例中,我们将使用一个简单的 Web 应用程序,其中包含一个 MongoDB 数据库作为持久层,并具有一个小型的 REST 接口。
@RestController @RequestMapping("characters") public class MiddleEarthCharactersController { private final MiddleEarthCharactersRepository repository; // constructor not shown @GetMapping public List<MiddleEarthCharacter> findByRace(@RequestParam String race) { return repository.findAllByRace(race); } @PostMapping public MiddleEarthCharacter save(@RequestBody MiddleEarthCharacter character) { return repository.save(character); } } 在集成测试期间,我们将启动一个包含数据库服务器的 Docker 容器。由于容器暴露的数据库端口将动态分配,我们无法在 properties 文件中定义数据库 URL。因此,对于版本早于 3.1 的 Spring Boot 应用程序,我们需要使用 @DynamicPropertySource 注解才能将这些属性添加到 DynamicPropertyRegistry 中:
1、概览 Spring Boot 3 具有一些新功能,比如将我们的应用程序构建为 GraalVM Native Image(原生镜像)。另一个相关支持是 Docker Compose。
在本教程中,我们将了解如何将 Docker Compose 工作流与 Spring Boot 3 整合。
2、Spring Boot 3 的 Docker Compose Support 提供了什么? 通常,我们会根据 docker-compose.yml 运行 docker-compose up 来启动和 docker-compose down 来停止我们的容器。现在,我们可以将这些 Docker Compose 命令委托给 Spring Boot 3。当 Spring Boot 应用程序启动或停止时,它也会管理我们的容器。
此外,它还内置了对多种服务的管理,如 SQL 数据库、MongoDB、Cassandra 等。因此,我们可能不需要在 application 资源文件中重复配置 class 或 properties。
最后,我们会看到如何在该支持中使用自定义 Docker 镜像和 Docker Compose profiles 。
3,设定 我们需要 Docker Compose 和 Spring Boot 3 来探索这种新的支持。
3.1、Docker Compose Docker Compose 需要已安装的 Docker 引擎。它们很容易安装,不过根据操作系统的不同可能会有差异。