简体   繁体   English

我的 Spring Boot 应用程序容器无法连接到我的 postgresql 数据库

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

I'm trying to dockerize my spring boot app that uses postgresql so I first run ./mvnw clean package -DskipTests after I did cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker我正在尝试对使用 postgresql 的 Spring Boot 应用程序进行 dockerize,所以我在执行cp target/ docker -spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/ docker之后首先运行./mvnw clean package -DskipTests

here's my code这是我的代码

docker-compose.yml 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

dockerfile文件

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

application.props 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

but i keep getting the same error但我不断收到同样的错误

2021-07-16 15:25:31.986 WARN 1 --- [ main] ohejeiJdbcEnvironmentInitiator : HHH000342: Could not obtain connection to query metadata app | 2021-07-16 15:25:31.986 WARN 1 --- [main] ohejeiJdbcEnvironmentInitiator:HHH000342:无法获得查询元数据应用程序的连接| app |应用程序| org.postgresql.util.PSQLException: Connection to db:5432 refused. org.postgresql.util.PSQLException: 与 db:5432 的连接被拒绝。 Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.检查主机名和端口是否正确以及 postmaster 是否正在接受 TCP/IP 连接。

What a nice question!多么好的问题啊! At first glance at your config, I can't see anything that stands out as outright wrong.乍一看你的配置,我看不出任何明显错误的地方。 I believe it's possible that you are trying to connect to your db before postgres is fully started.我相信您有可能在postgres完全启动之前尝试连接到您的db

Waiting for your postgres process to start (rather than simply your container)等待您的 postgres 进程启动(而不仅仅是您的容器)

Provided that's the problem, you are most likely advised to not use a raw depends_on (which will just wait till the container itself is started, but rather a depends_on with a condition and a healthcheck .如果这是问题所在,您很可能会被建议不要使用原始的depends_on (它只会等到container本身启动,而是使用带有条件和healthcheckdepends_on

With that approach you make sure you check whether postgres is really started, not just the container, but the database itself.使用这种方法,您可以确保检查postgres是否真的启动,不仅仅是容器,还有数据库本身。 Ie you can do something like:即您可以执行以下操作:

// ...
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

EDIT: Making sure the database underneath actually exists编辑:确保下面的数据库确实存在

You mentioned in your comment that now you get another error saying it can't find your database.您在评论中提到,现在您收到另一个错误,说它找不到您的数据库。 That's most likely because while the postgres process itself is started, the database your jdbc connection string refers to is not created.这很可能是因为当postgres进程本身启动时,您的 jdbc 连接字符串所引用的数据库并未创建。

By default, postgres databases you get out of the box are:默认情况下,您开箱即用的postgres数据库是:

  • template0
  • template1
  • postgres

See also this link for more information.另请参阅此链接以获取更多信息。

Since your jdbc string connects/expects to connect to another database: jdbc:postgresql://db:5432/postgreTest , you most likely need to create that database beforehand.由于您的jdbc字符串连接/期望连接到另一个数据库: jdbc:postgresql://db:5432/postgreTest ,您很可能需要事先创建该数据库。

How to create the postgreTest database beforehand?如何事先创建postgreTest数据库?

Well, there are multiple ways:嗯,有多种方法:

  • more spring-y/java-y approach: using a raw jdbc connection in your spring context and doing create database statements before the rest of your context starts up更多 spring-y/java-y方法:在 spring 上下文中使用原始 jdbc 连接并在其余上下文启动之前创建数据库语句
  • more docker-y : Make sure your container has the database you need upon startup.更多docker-y :确保您的容器在启动时具有您需要的数据库。 This is the one I'd describe how to do below.这是我将在下面描述如何做的。

The postgres-docker container supports multiple properties , in addition to: postgres-docker 容器支持多种属性,此外还有:

POSTGRES_USER=xyz
POSTGRES_PASSWORD=xxxxx

you can also override the default database name created (which is postgres , if your user is also postgres ) by utilizing the POSTGRES_DB property.你也可以覆盖创建的默认数据库名称(这是postgres ,如果你的用户也是postgres )利用POSTGRES_DB财产。 The documentation reads:文档中写道:

This optional environment variable can be used to define a different name for the default database that is created when the image is first started.此可选环境变量可用于为首次启动映像时创建的默认数据库定义不同的名称。 If it is not specified, then the value of POSTGRES_USER will be used如果未指定,则将使用POSTGRES_USER的值

Basically, you'd do something like:基本上,你会做这样的事情:

  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

Which would end up creating your database, waiting for it to fully start (due to the healthcheck), and then also create the postgresTest database, and only then be considered healthy.这将最终创建您的数据库,等待它完全启动(由于健康检查),然后还创建postgresTest数据库,然后才被认为是健康的。 Then your spring app would have its all dependencies and would be ready to start.然后你的 spring 应用程序将拥有它的所有依赖项,并准备开始。

Docker-compose spec version Docker-compose 规范版本

Note : btw, I notice you use version 2 of the compose specification, I'd switch to latest 3, as 2 (and 1) are very clunky and often don't allow for some possibilities which are fairly easy to achieve in the new spec version.注意:顺便说一句,我注意到您使用了 compose 规范的version 2 ,我会切换到 最新的 3,因为 2(和 1)非常笨重,并且通常不允许某些在新版本中很容易实现的可能性规格版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM