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



我正在构建我的第一个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和以下配置数据。properties

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

我可以测试两个图像是否都已打开。此外,从docker日志和docker事件中,我看到postgres Container运行良好,甚至我可以访问它,还创建了一个DB。但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容器,该容器运行良好,具有适当的credentials。

尝试使用:

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

postgres数据库没有在localhost上运行,而是在具有其他IP(未知(的另一个容器中运行。

值得庆幸的是,docker-compose会自动创建一个在docker-compose.yml中所有容器之间共享的网络(除非明确表示不共享(,因此您可以神奇地将服务名称用作主机名

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

您将应用程序指向localhost,但这不是容器之间共享的。

要访问另一个容器,必须参考其hostname

您应该使用以下datasourceurl:

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

请参阅以下关于使用docker compose从另一个容器连接到容器的简单教程:https://docs.docker.com/compose/gettingstarted/

docker-compose.yml规范中缺少网络配置。通过使用"网络",您可以通过容器的服务名称(使用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等于服务名称的名称

除了提供上述解决方案外,具有上述配置的java容器(通过IP、localhost、servicename..连接postgres,并将postgres容器暴露在LAN中(仍然无法工作。升级到JDK最新版本(17当前(对我来说很有效-当您使用JDK 11并尝试使用java容器(docker(与postgres容器通信时,也要考虑这一点。

最新更新