[英]Spring Boot, PostgreSQL, and Docker - Connection Refused whil Running in Container
I am attempting to build a "service" consisting of a Spring Boot application and PostgreSQL database.我正在尝试构建一个由 Spring Boot 应用程序和 PostgreSQL 数据库组成的“服务”。 I have been able to access the database (running in a container) from the Spring Boot app while the Spring Boot application was running on my local machine.
当 Spring Boot 应用程序在我的本地机器上运行时,我已经能够从 Spring Boot 应用程序访问数据库(在容器中运行)。 Now, when I attempt to move the Spring Boot application to a container, I am received the following error:
现在,当我尝试将 Spring Boot 应用程序移动到容器时,收到以下错误:
inventory_1 | 2018-01-20 18:43:06.108 ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection] with root cause
inventory_1 |
inventory_1 | java.net.ConnectException: Connection refused (Connection refused)
However, I am able to connect to DB from my local machine: psql -h localhost -p 5000 -U kelly_psql -d leisurely_diversion
但是,我可以从我的本地机器连接到数据库:
psql -h localhost -p 5000 -U kelly_psql -d leisurely_diversion
My application.properties file:我的 application.properties 文件:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:5432/leisurely_diversion
spring.datasource.username=kelly_psql
spring.datasource.password=pass
spring.datasource.driver-class-name=org.postgresql.Driver
My docker-compose file:我的 docker-compose 文件:
# Use postgres/example user/password credentials
version: '3.2'
services:
db:
image: postgres
ports:
- 5000:5432
environment:
POSTGRES_PASSWORD: example
volumes:
- type: volume
source: psql_data
target: /var/lib/postgresql/data
networks:
- app
restart: always
inventory:
image: kellymarchewa/inventory_api
depends_on:
- db
ports:
- 8080:8080
networks:
- app
restart: always
volumes:
psql_data:
networks:
app:
My Dockerfile (from the Spring website )我的 Dockerfile(来自Spring 网站)
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
I suspect the issue lies in a misunderstanding (on my part) of Docker or containers, but I am not sure.我怀疑问题在于对 Docker 或容器的误解(就我而言),但我不确定。 Any advice would be appreciated.
任何建议将不胜感激。
You are pointing your application towards localhost
, but this is not shared between containers.您将应用程序指向
localhost
,但这不在容器之间共享。
To access another container you have to refer to its hostname
.要访问另一个容器,您必须引用其
hostname
。
In your case, I understand that you want the inventory
service to access the db
service.在您的情况下,我了解您希望
inventory
服务访问db
服务。 So you should use the following datasource
url:所以你应该使用以下
datasource
网址:
spring.datasource.url=jdbc:postgresql://db:5432/leisurely_diversion
See this simple tutorial about connecting to a container from another container with docker compose: https://docs.docker.com/compose/gettingstarted/请参阅有关使用 docker compose 从另一个容器连接到容器的简单教程: https : //docs.docker.com/compose/gettingstarted/
Like in my case if you are using Docker Toolbox for windows 8.1 then you cannot use "localhost",就像在我的情况下,如果您使用的是 Windows 8.1 的Docker Toolbox ,那么您不能使用“localhost”,
Instead you have to use docker machine ip;相反,您必须使用 docker machine ip;
host> docker-machine ip default
192.168.99.100
After that your url will look like;之后,您的网址将如下所示;
spring.datasource.url=jdbc:postgresql://192.168.99.100:5432/bankdb
This will successfully connect to docker Postgres DB.这将成功连接到 docker Postgres DB。
Cheers!!干杯!!
Elaborating a little upon the answer given by ESala:详细说明 ESala 给出的答案:
I agree, it is a networking issue and the given solution works fine, but you can also use localhost
(eg if you really really want to), by switching to network host mode when running your containers (cf here ).我同意,这是一个网络问题,给定的解决方案工作正常,但您也可以使用
localhost
(例如,如果您真的想要),通过在运行容器时切换到网络主机模式(参见此处)。 Like done here for nginx.就像这里为 nginx 所做的那样。
I'd say you won't want this most of the time, since it messes with the sandbox you gain.我会说大多数时候你不会想要这个,因为它会干扰你获得的沙箱。 But the option exists.
但是这个选项是存在的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.