无法从另一个容器连接到 Postgres 容器
Not able to connect to Postgres container from another container
这个问题已被问过很多次, here and here,但这些解决方案对我不起作用。
我已经用这个 docker-compose.yml
文件创建了一个 Postgres 和一个 AppServer 容器
version: "3.7"
services:
db:
image: postgres:alpine
container_name: db
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
POSTGRES_INITDB_ARGS: '-A md5'
volumes:
- ./pgdata:/var/lib/postgressql/data
ports:
- "5432:5432"
api:
build: api
container_name: api
volumes:
- ./database/migrations:/migrations
ports:
- "8080:8080"
links:
- db
depends_on:
- db
经过运行这个,我就可以成功了
docker exec -it db psql -U user mydb
我成功连接到 Postgres。我也可以使用
成功登录到两个容器的终端
docker exec -it api bash
docker exec -it db bash
从 api 的 bash 内部,我可以毫无问题地 ping db
但是,在我的 api 容器中,我无法与 Postgres 数据库建立 JDBC 连接。
api | Flyway Community Edition 7.3.2 by Redgate
api | ERROR:
api | Unable to obtain connection from database (jdbc:postgresql://db:5432/mydb) for user 'user': Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
api | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
api | SQL State : 08001
api | Error Code : 0
api | Message : Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
api |
api | Caused by: org.postgresql.util.PSQLException: Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
api | Caused by: java.net.ConnectException: Connection refused (Connection refused)
当我可以通过 psql 连接时,为什么我的连接被拒绝?这是我的飞路 conf
flyway.url=jdbc:postgresql://db:5432/mydb
flyway.user=user
flyway.password=password
flyway.locations=filesystem:/migrations
Edit:: 因此,如果我等待,然后在 docker exec -it api bash
一段时间后执行 flyway migrate
,一切正常。我认为上面发生的事情是我的 flyway migrate
命令是 运行 甚至在数据库准备好之前。
为什么会这样?因为我指定了依赖关系,所以我的 API 容器应该只在数据库完全启动时启动。但似乎并非如此。
将数据库容器指定为依赖项并不能保证它会在其他 services/containers 之前 就绪 。它只保证它将 在您的其他服务之前启动 。
解决此问题的一种方法是在启动期间无法连接到数据库时在 API 应用程序中实施重试。
这是一篇使用 shell 脚本等待服务准备就绪的文章的 link。
IMO 您的应用程序应该足够聪明,可以在无法建立数据库连接时重试几次。无论如何它都会使它更健壮。
这个问题已被问过很多次
我已经用这个 docker-compose.yml
文件创建了一个 Postgres 和一个 AppServer 容器
version: "3.7"
services:
db:
image: postgres:alpine
container_name: db
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
POSTGRES_INITDB_ARGS: '-A md5'
volumes:
- ./pgdata:/var/lib/postgressql/data
ports:
- "5432:5432"
api:
build: api
container_name: api
volumes:
- ./database/migrations:/migrations
ports:
- "8080:8080"
links:
- db
depends_on:
- db
经过运行这个,我就可以成功了
docker exec -it db psql -U user mydb
我成功连接到 Postgres。我也可以使用
成功登录到两个容器的终端docker exec -it api bash
docker exec -it db bash
从 api 的 bash 内部,我可以毫无问题地 ping db
但是,在我的 api 容器中,我无法与 Postgres 数据库建立 JDBC 连接。
api | Flyway Community Edition 7.3.2 by Redgate
api | ERROR:
api | Unable to obtain connection from database (jdbc:postgresql://db:5432/mydb) for user 'user': Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
api | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
api | SQL State : 08001
api | Error Code : 0
api | Message : Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
api |
api | Caused by: org.postgresql.util.PSQLException: Connection to db:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
api | Caused by: java.net.ConnectException: Connection refused (Connection refused)
当我可以通过 psql 连接时,为什么我的连接被拒绝?这是我的飞路 conf
flyway.url=jdbc:postgresql://db:5432/mydb
flyway.user=user
flyway.password=password
flyway.locations=filesystem:/migrations
Edit:: 因此,如果我等待,然后在 docker exec -it api bash
一段时间后执行 flyway migrate
,一切正常。我认为上面发生的事情是我的 flyway migrate
命令是 运行 甚至在数据库准备好之前。
为什么会这样?因为我指定了依赖关系,所以我的 API 容器应该只在数据库完全启动时启动。但似乎并非如此。
将数据库容器指定为依赖项并不能保证它会在其他 services/containers 之前 就绪 。它只保证它将 在您的其他服务之前启动 。
解决此问题的一种方法是在启动期间无法连接到数据库时在 API 应用程序中实施重试。
这是一篇使用 shell 脚本等待服务准备就绪的文章的 link。
IMO 您的应用程序应该足够聪明,可以在无法建立数据库连接时重试几次。无论如何它都会使它更健壮。