拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 在Docker Compose中使用PostgreSQL运行Spring Boot

在Docker Compose中使用PostgreSQL运行Spring Boot

白鹭 - 2021-11-09 2161 0 2

1.简介

在本教程中,我们想使用流行的开源数据库PostgreSQL运行Spring Boot应用程序。在上一篇文章中,我们研究了Docker Compose一次处理多个容器。因此,我们将使用Docker Compose来运行Spring Boot和PostgreSQL ,而不是将PostgreSQL作为单独的应用程序安装。

2.创建Spring Boot项目

让我们转到Spring Initializer并创建我们的Spring Boot项目。我们将添加PostgreSQL Driver和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文件:

./mvnw clean package -DskipTests

在这里,在打包应用程序之前,我们首先清理以前的版本。另外,我们跳过了测试,因为它们在没有PostgreSQL的情况下失败了。


target目录中有一个应用程序JAR文件。该文件的名称中包含项目名称和版本号,并以-SNAPSHOT.jar 。因此其名称可能是docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar 。


让我们创建新的src/main/docker目录。之后,我们将应用程序JAR文件复制到此处:

cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker

最後,我們在同一目錄中Dockerfile

FROM adoptopenjdk:11-jre-hotspot

 ARG JAR_FILE=*.jar

 COPY ${JAR_FILE} application.jar

 ENTRYPOINT ["java", "-jar", "application.jar"]

这个文件描述了Docker应该如何运行我们的Spring Boot应用程序。它使用AdoptOpenJDK中的Java 11,并将应用程序JAR文件复制到application.jar 。然后,它将运行该JAR文件以启动我们的Spring Boot应用程序。

4. Docker撰写文件

现在,让我们编写我们的Docker Compose文件docker-compose.yml ,并将其保存在src/main/docker :

version: '2'



 services:

 app:

 image: 'docker-spring-boot-postgres:latest'

 build:

 context: .

 container_name: app

 depends_on:

 - db

 environment:

 - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/compose-postgres

 - SPRING_DATASOURCE_USERNAME=compose-postgres

 - SPRING_DATASOURCE_PASSWORD=compose-postgres

 - SPRING_JPA_HIBERNATE_DDL_AUTO=update



 db:

 image: 'postgres:13.1-alpine'

 container_name: db

 environment:

 - POSTGRES_USER=compose-postgres

 - POSTGRES_PASSWORD=compose-postgres

我们应用程序的名称是app.这是两项服务中的第一个(第4-15行):

  • Spring Boot Docker映像的名称为docker-spring-boot-postgres:latest (第5行)。 Dockerfile构建该映像(第6-7行)

  • 容器名称是app (第8行)。它取决于db服务(第10行)。这就是为什么它在db容器之后开始

  • 我们的应用程序使用db PostgreSQL容器作为数据源(第12行)。数据库名称,用户名和密码均为compose-postgres (第12-14行)

  • Hibernate将自动创建或更新所需的任何数据库表(第15行)

PostgreSQL数据库的名称为db ,是第二个服务(第17-22行):

  • 我们使用PostgreSQL 13.1(第18行)

  • 容器名称是db (第19行)

  • 用户名和密码均为compose-postgres (第21-22行)

5.使用Docker Compose运行

让我们使用Docker Compose运行我们的Spring Boot应用程序和PostgreSQL :

docker-compose up

首先,这将为我们的Spring Boot应用程序构建Docker映像。接下来,它将启动一个PostgreSQL容器。最后,它将启动我们的应用程序Docker映像。这次,我们的应用程序运行良好:

Starting DemoApplication v0.0.1-SNAPSHOT using Java 11.0.9 on f94e79a2c9fc with PID 1 (/application.jar started by root in /)

 [...]

 Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces.

 [...]

 Started DemoApplication in 4.751 seconds (JVM running for 6.512)

如我们所见,Spring Data找不到存储库接口。没错-我们还没有创建一个!


如果要停止所有容器,则需要先按[Ctrl-C]。然后,我们可以停止Docker Compose:

docker-compose down

6.创建客户实体和存储库

要在我们的应用程序中使用PostgreSQL数据库,我们将创建一个简单的客户实体:

@Entity

 @Table(name = "customer")

 public class Customer { @Id

 @GeneratedValue

 private long id; @Column(name = "first_name", nullable = false)

 private String firstName; @Column(name = "last_name", nullable = false)

 private String lastName;

Customer具有一个生成的id属性和两个必需属性: firstName和lastName 。


现在,我们可以为该实体编写存储库接口:

public interface CustomerRepository extends JpaRepository<Customer, Long> { }

通过简单地扩展JpaRepository ,我们继承了用于创建和查询Customer实体的方法。


最后,我们将在我们的应用程序中使用以下方法:

@SpringBootApplication

 public class DemoApplication { @Autowired

 private CustomerRepository repository; @EventListener(ApplicationReadyEvent.class)

 public void runAfterStartup() {

 List allCustomers = this.repository.findAll();

 logger.info("Number of customers: " + allCustomers.size());



 Customer newCustomer = new Customer();

 newCustomer.setFirstName("John");

 newCustomer.setLastName("Doe");

 logger.info("Saving new customer..."); this.repository.save(newCustomer);



 allCustomers = this.repository.findAll();

 logger.info("Number of customers: " + allCustomers.size());

 }

 }
  • 我们通过依赖注入访问我们的Customer

  • 我们使用存储库查询现有客户的数量-这将为零

  • 然后我们创建并保存客户

  • 当我们再次查询现有客户时,我们希望找到刚才创建的客户

7.再次运行Docker Compose

运行更新的Spring Boot应用程序,我们需要首先对其进行重建。因此,我们在项目根目录中再次执行以下命令:

./mvnw clean package -DskipTests

 cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker

我们如何使用此更新的应用程序JAR文件重建Docker映像?最好的方法是删除现有的Docker映像,该映像的名称我们在docker-compose.yml指定。这将迫使Docker在下次启动Docker Compose文件时再次构建映像:

cd src/main/docker

 docker-compose down

 docker rmi docker-spring-boot-postgres:latest

 docker-compose up

因此,在停止容器后,我们将删除应用程序Docker映像。然后,我们再次启动Docker Compose文件,该文件将重建应用程序映像。


这是应用程序的输出:

Finished Spring Data repository scanning in 180 ms. Found 1 JPA repository interfaces.

 [...]

 Number of customers: 0

 Saving new customer...

 Number of customers: 1

Spring Boot找到了我们空的客户仓库。因此,我们从没有客户开始,然后成功创建一个客户。

8.结论

在这个简短的教程中,我们首先为PostgreSQL创建一个Spring Boot应用程序。接下来,我们编写了一个Docker Compose文件,以将我们的应用程序容器与PostgreSQL容器一起运行。


最后,我们创建了一个客户实体和存储库,这使我们可以将客户保存到PostgreSQL。


0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *