知識庫 / Spring / Spring Boot RSS 訂閱

使用 Docker Compose 運行 Spring Boot 與 PostgreSQL

Docker,Persistence,Spring Boot
HongKong
4
12:43 PM · Dec 06 ,2025

1. 簡介

本教程將運行一個 Spring Boot 應用程序,並使用流行的開源數據庫 PostgreSQL。 在上一篇文章中,我們探討了 Docker Compose 如何同時處理多個容器。 因此,我們不直接安裝 PostgreSQL 作為單獨的應用程序,而是將使用 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 文件:

./mvnw clean package -DskipTests

在這裏,我們首先清理之前的構建,然後再打包應用程序。此外,由於測試在沒有 PostgreSQL 時會失敗,因此我們跳過測試。

現在,我們有一個應用程序 JAR 文件位於 target 目錄中。該文件在名稱中包含項目名稱和版本號,並以 -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 應用程序。它使用 Java 11 來自 AdoptOpenJDK,並將應用程序 JAR 文件複製到 application.jar。然後運行該 JAR 文件以啓動我們的 Spring Boot 應用程序。

4. Docker Compose 文件

現在我們來編寫 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 行)。Docker 從當前目錄的 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;

客户擁有一個生成的id屬性,以及兩個必填屬性:firstNamelastName

現在我們可以編寫該實體的倉庫接口

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());
    }
}
<ul>
 <li>我們通過依賴注入訪問我們的<em title="Customer">客户</em>倉庫。</li>
 <li>我們使用倉庫查詢現有客户的數量,這將為零。</li>
 <li>然後我們創建並保存一個客户。</li>
 <li>當我們再次查詢現有客户時,我們應該能夠找到我們剛剛創建的客户。</li>
</ul>

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-compose.yml 中指定的 Docker 鏡像,這會強制 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 中。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.