簡體   English   中英

我的 Spring Boot 應用程序容器無法連接到我的 postgresql 數據庫

[英]my spring boot app container can't connect to my postgresql database

我正在嘗試對使用 postgresql 的 Spring Boot 應用程序進行 dockerize,所以我在執行cp target/ docker -spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/ docker之后首先運行./mvnw clean package -DskipTests

這是我的代碼

docker-compose.yml

version: '2'

services:
  app:
    image: 'demo:latest'
    build:
      context: .
    container_name: app
    depends_on:
      - db
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/postgreTest
      - SPRING_DATASOURCE_USERNAME=postgres
      - SPRING_DATASOURCE_PASSWORD=B123456789
      - SPRING_JPA_HIBERNATE_DDL_AUTO=update

  db:
    image: 'postgres:alpine'
    container_name: db
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=B123456789

文件

FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} application.jar
ENTRYPOINT ["java", "-jar", "application.jar"]

application.props

spring.datasource.url=jdbc:postgresql://db:5432/postgreTest?serverTimezone=UTC
spring.datasource.username=postgres
spring.datasource.password=B123456789
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

但我不斷收到同樣的錯誤

2021-07-16 15:25:31.986 WARN 1 --- [main] ohejeiJdbcEnvironmentInitiator:HHH000342:無法獲得查詢元數據應用程序的連接| 應用程序| org.postgresql.util.PSQLException: 與 db:5432 的連接被拒絕。 檢查主機名和端口是否正確以及 postmaster 是否正在接受 TCP/IP 連接。

多么好的問題啊! 乍一看你的配置,我看不出任何明顯錯誤的地方。 我相信您有可能在postgres完全啟動之前嘗試連接到您的db

等待您的 postgres 進程啟動(而不僅僅是您的容器)

如果這是問題所在,您很可能會被建議不要使用原始的depends_on (它只會等到container本身啟動,而是使用帶有條件和healthcheckdepends_on

使用這種方法,您可以確保檢查postgres是否真的啟動,不僅僅是容器,還有數據庫本身。 即您可以執行以下操作:

// ...
services:
  postgres:
    // ...
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 1s    

  app:
    //... do your springboot app stuff here
    depends_on: 
      postgres:
        condition: service_healthy

編輯:確保下面的數據庫確實存在

您在評論中提到,現在您收到另一個錯誤,說它找不到您的數據庫。 這很可能是因為當postgres進程本身啟動時,您的 jdbc 連接字符串所引用的數據庫並未創建。

默認情況下,您開箱即用的postgres數據庫是:

  • template0
  • template1
  • postgres

另請參閱此鏈接以獲取更多信息。

由於您的jdbc字符串連接/期望連接到另一個數據庫: jdbc:postgresql://db:5432/postgreTest ,您很可能需要事先創建該數據庫。

如何事先創建postgreTest數據庫?

嗯,有多種方法:

  • 更多 spring-y/java-y方法:在 spring 上下文中使用原始 jdbc 連接並在其余上下文啟動之前創建數據庫語句
  • 更多docker-y :確保您的容器在啟動時具有您需要的數據庫。 這是我將在下面描述如何做的。

postgres-docker 容器支持多種屬性,此外還有:

POSTGRES_USER=xyz
POSTGRES_PASSWORD=xxxxx

你也可以覆蓋創建的默認數據庫名稱(這是postgres ,如果你的用戶也是postgres )利用POSTGRES_DB財產。 文檔中寫道:

此可選環境變量可用於為首次啟動映像時創建的默認數據庫定義不同的名稱。 如果未指定,則將使用POSTGRES_USER的值

基本上,你會做這樣的事情:

  db:
    image: 'postgres:alpine'
    container_name: db
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 1s 
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=B123456789
      - POSTGRES_DB=postgreTest

這將最終創建您的數據庫,等待它完全啟動(由於健康檢查),然后還創建postgresTest數據庫,然后才被認為是健康的。 然后你的 spring 應用程序將擁有它的所有依賴項,並准備開始。

Docker-compose 規范版本

注意:順便說一句,我注意到您使用了 compose 規范的version 2 ,我會切換到 最新的 3,因為 2(和 1)非常笨重,並且通常不允許某些在新版本中很容易實現的可能性規格版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM