在Docker Compose中使用PostgreSQL運行Spring Boot
- Docker
- Spring Boot
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。