Docker:Springboot容器无法连接到PostgreSQL容器连接错误。

6
我是一名有用的助手,可以为您翻译文本。
我正在构建我的第一个Springboot 2.0应用程序。我正在尝试将我的Springboot应用程序放入一个docker容器中,将我的PostgresDB放入另一个容器中。 我的Dockerfile:
    FROM frolvlad/alpine-oraclejdk8:slim
    VOLUME /tmp
    ADD springboot-api-demo-0.1*.jar app.jar
    RUN sh -c 'touch /app.jar'
    EXPOSE 9443
    ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/urandom -jar /app.jar" ]

我的docker-compose.yml文件

version: "2.1"

services:
  springboot-api-demo:
    image: "fw/springboot-api-demo"
    mem_limit: 1024m
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=local
      - AWS_REGION=local
      - ENVIRONMENT=local
      - AUTH_ENABLED=false
  postgres:
    container_name: pgdb
    image: postgres:9.6-alpine
    environment:
    - 'POSTGRES_ROOT_PASSWORD=postgres'
    - 'POSTGRES_USER=postgres'
    - 'POSTGRES_PASSWORD=postgres'
    ports:
    - "54321:5432"

我正在使用Springboot JPA Data 2.0,并在我的application.properties中使用以下配置数据。

spring.datasource.url= jdbc:postgresql://localhost:54321/java_learning
spring.datasource.username=postgres
spring.datasource.password=postgres

我可以测试两个图像都已启动。从docker日志和docker事件中,我看到postgres容器运行良好,我甚至可以访问它并创建了一个数据库。 但是springboot容器启动后立即停止,因为它无法连接到postgress并抛出以下错误。

无法从数据库获取连接:连接尝试失败

请注意,我的主机已经在端口5432上安装了Postgres,这就是为什么我在我的postgres容器上进行了端口映射到54321:5432的原因。这是证明:) -
➜  springboot-api-demo git:(master) ✗ lsof -i:54321              
COMMAND     PID             USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
com.docke 44345 shailendra.singh   18u  IPv4 0xf62897fbdd69e31d      0t0  TCP *:54321 (LISTEN)
com.docke 44345 shailendra.singh   21u  IPv6 0xf62897fbdd119975      0t0  TCP localhost:54321 (LISTEN)

➜  springboot-api-demo git:(master) ✗ lsof -i:5432 
COMMAND  PID             USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
postgres 715 shailendra.singh    5u  IPv6 0xf62897fbb43e03b5      0t0  TCP localhost:postgresql (LISTEN)
postgres 715 shailendra.singh    6u  IPv4 0xf62897fbbaeea9bd      0t0  TCP localhost:postgresql (LISTEN)

我不确定问题出在哪里。但是我的Springboot应用程序无法连接到我的Postgres容器,而该容器使用正确的凭据正在运行。

4个回答

7

请尝试以下内容:

spring.datasource.url= jdbc:postgresql://pgdb:5432/java_learning

Postgres数据库并不是在本地主机上运行,而是在另一个容器中运行,该容器具有另一个IP地址(但目前未知)。

值得庆幸的是,docker-compose会自动创建一个网络共享,使得docker-compose.yml文件中的所有容器都可以使用服务名称作为主机名

此外,您在端口上有一个拼写错误,Postgres默认使用5432端口,而不是54321


不行。我尝试使用主机名pgdb,但它显示错误消息:连接到pgdb:54321被拒绝。请检查主机名和端口是否正确,并且postmaster是否接受TCP/IP连接。 - Shailendra2014
糟糕,我错过了另一个错误,端口实际上是5432而不是54321。我已经编辑了我的答案。 - Anthony Raymond
2
除了@AnthonyRaymond的答案之外,您实际上不需要暴露数据库端口才能从springboot-api-demo服务连接,因为服务将通过内部网络通信。只有在您将从另一台机器远程连接到db端口时才需要暴露它。 - tftd

4

您的应用程序指向了localhost,但这并没有在容器之间共享。

要访问另一个容器,您必须引用其hostname

您应该使用以下datasource URL:

spring.datasource.url=jdbc:postgresql://pgdb:5432/java_learning

请参考这个简单的教程,了解如何使用Docker Compose从另一个容器连接到容器:https://docs.docker.com/compose/gettingstarted/

1
不行,它还是不工作。我尝试使用主机名pgdb,但它显示错误消息:连接到pgdb:54321被拒绝。请检查主机名和端口是否正确,并且postmaster是否接受TCP/IP连接。 - Shailendra2014
尝试使用5432而不是54321。 - Alien

2

您的docker-compose.yml规范中缺少网络配置。通过使用“networks”,您可以通过服务名称(使用dns,将服务名称作为主机名)在容器之间有效地进行通信。

这是更新后的docker-compose.yml

version: "2.1"

services:
  springboot-api-demo:
    image: "fw/springboot-api-demo"
    mem_limit: 1024m
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=local
      - AWS_REGION=local
      - ENVIRONMENT=local
      - AUTH_ENABLED=false
    networks:
      - mynet

  postgres:
    container_name: pgdb
    image: postgres:9.6-alpine
    environment:
    - 'POSTGRES_ROOT_PASSWORD=postgres'
    - 'POSTGRES_USER=postgres'
    - 'POSTGRES_PASSWORD=postgres'
    ports:
    - "54321:5432"
    networks:
    - mynet

networks:
  mynet:
    driver: bridge

您的数据库url应该像这样:spring.datasource.url=jdbc:postgresql://postgres:5432/java_learning(注意主机名postgres等于服务名称)。


此外,我强烈建议升级 docker-compose 至 >3.x 版本。 - yomateo

0
除了上述提供的解决方案之外,使用配置(通过IP、localhost、servicename连接postgres,并将postgres容器暴露给局域网)的JDK 11 Java容器仍然无法工作。升级到最新版本的JDK(目前为17)对我有用-当您使用JDK 11并尝试Java容器(Docker)与postgres容器通信时,请考虑此选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接