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 down6. 創建客户實體和倉庫
為了在我們的應用程序中使用 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屬性,以及兩個必填屬性: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());
}
}<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: 1Spring Boot 發現我們的空客户倉庫。因此,我們從沒有客户開始,但隨後成功地創建了一個。
8. 結論
在本文中,我們首先創建了一個用於 PostgreSQL 的 Spring Boot 應用程序。接下來,我們編寫了一個 Docker Compose 文件,用於運行我們的應用程序容器與 PostgreSQL 容器。
最後,我們創建了一個客户實體和存儲庫,這使我們能夠將客户保存到 PostgreSQL 中。