docker-compose:spring-boot web 服务访问 postgres db 服务

Posted

技术标签:

【中文标题】docker-compose:spring-boot web 服务访问 postgres db 服务【英文标题】:docker-compose: spring-boot web service access postgres db service 【发布时间】:2017-09-19 15:28:22 【问题描述】:

在我的 docker-compose.yal 文件中,我定义了一个基于 spring-boot 的 Web 服务和一个 postgresql 数据库服务。 Web 服务引用了 db 服务,并且有一个用于数据库数据源 URL 的环境变量,它需要在其中引用数据库服务的主机名。这是它的样子:

version: '3'
services:

  web:
    container_name: medmap-server
    hostname: medmap-server
    build: ../../../build/docker
    ports: ["8090:8090"]
    links:
      - db:database
    environment:
      - spring.datasource.url=jdbc:postgresql://medmap-db:5433/medmapdb
      - spring.datasource.username=docker
      - spring.datasource.password=docker      
      - logging.level.org.hibernate=DEBUG

  db:
    container_name: medmap-db
    hostname: medmap-db
    image: postgres:9.6.2
    ports:
      - "5433:5433"
    volumes:
      - /var/lib/medmap/data
    environment:
      - POSTGRES_PASSWORD=docker
      - POSTGRES_USER=docker
      - POSTGRES_DB=medmapdb
      - PGDATA=/var/lib/medmap/data/pgdata

当我使用 docker-compose up 启动此应用程序时,我收到以下错误:

medmap-server | Caused by: org.postgresql.util.PSQLException: Connection to medmap-db:5433 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections
.
medmap-server |         at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:239) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:127) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:29) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:21) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:41) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.Driver.makeConnection(Driver.java:414) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.Driver.connect(Driver.java:282) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:310) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:732) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:664) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:479) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) ~[tomcat-jdbc-8.5.11.jar!/:na]
medmap-server |         at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.0.12.Final.jar!/:
5.0.12.Final]
medmap-server |         at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5
.0.12.Final.jar!/:5.0.12.Final]
medmap-server |         at org.hibernate.tool.schema.extract.internal.ExtractionContextImpl.getJdbcConnection(ExtractionContextImpl.java:62) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final]
medmap-server |         ... 38 common frames omitted
medmap-server | Caused by: java.net.ConnectException: Connection refused (Connection refused)
medmap-server |         at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_121]
medmap-server |         at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_121]
medmap-server |         at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_121]
medmap-server |         at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_121]
medmap-server |         at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_121]
medmap-server |         at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_121]
medmap-server |         at org.postgresql.core.PGStream.<init>(PGStream.java:61) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:121) ~[postgresql-9.4-1200-jdbc41.jar!/:9.4]
medmap-server |         ... 58 common frames omitted
medmap-server |
medmap-server exited with code 1

我不知道的是如何创建 pg_hba.conf 文件以允许一个容器中的 Web 服务访问另一个容器中的 db 服务。 TIA 对此有任何帮助。

【问题讨论】:

postgres 日志中有什么内容?你确定端口?默认是 5432,而不是 5433 好建议。 Postgresql 在 5432 上运行。谢谢。 【参考方案1】:

default port for postgres is 5432,尝试定义它而不是 5433

port (integer) 服务器监听的 TCP 端口;默认为 5432。 请注意,相同的端口号用于服务器的所有 IP 地址 听着。该参数只能在服务器启动时设置。

【讨论】:

【参考方案2】:

感谢 @vao-tsun 建议我查看 postgres 端口。

我查看了我的数据库服务中 postgres 使用的端口,方法是盯着数据库服务的容器上的 bash shell 使用:

docker exec -i -t medmap-db /bin/bash

然后在 bash shell 中执行以下 psql 命令:

psql -U postgres -c "SELECT * FROM pg_settings WHERE name = 'port';"

这表明我使用的是端口 5432 而不是 5423,这是我的 Web 服务在 spring.datasource.url 环境变量指定的 IDBC URL 中使用的端口。

为了解决这个问题,我需要在我的数据库服务中指定 PGPORT=5433 环境变量。一个常见的错误是假设 docker-compose 中的 ports 字段告诉服务应该使用哪个端口。端口字段仅声明服务使用的端口。您需要以特定于服务的方式为您的服务配置端口(对于 postgres,它是环境变量 PGPORT)。

下面是我修改后的 docker-compose.yml 文件:

version: '3'
services:

  web:
    container_name: medmap-server
    hostname: medmap-server
    build: ../../../build/docker
    ports: ["8090:8090"]
    links:
      - db:database
    environment:
      - server.port=8090
      - spring.datasource.url=jdbc:postgresql://medmap-db:5433/medmapdb
      - spring.datasource.username=postgres
      - spring.datasource.password=postgres      
#      - logging.level.org.hibernate=DEBUG

  db:
    container_name: medmap-db
    hostname: medmap-db
    image: postgres:9.6.2
    ports:
      - "5433:5433"
    volumes:
      - /var/lib/medmap/data
    environment:
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_DB=medmapdb
      - PGDATA=/var/lib/medmap/data/pgdata
      - PGPORT=5433

【讨论】:

以上是关于docker-compose:spring-boot web 服务访问 postgres db 服务的主要内容,如果未能解决你的问题,请参考以下文章

Docker-compose容器

Docker-compose容器

Docker-compose容器

docker-compose.yml文件

Docker-Compose介绍,安装和使用

“docker-compose”命令为 docker-compose.yml 文件设置路径