【问题标题】:How to connect java app in docker container with database in another container?如何将docker容器中的java应用程序与另一个容器中的数据库连接起来?
【发布时间】:2023-03-13 22:32:01
【问题描述】:

我有一个简单的 Springboot 应用程序连接到两个不同的 SQL Server 数据库。当它们都在本地托管时,我没有问题。但是我需要将它们中的每一个都放在一个单独的 docker 容器中,当我这样做时,我在 Springboot 应用程序开始时收到一个 SQLServerException 告诉我:

 com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host '172.21.0.3', port 1434 has failed. Error: "'172.21.0.3'. Verify the connection properties.

172.21.0.3 是我的一个数据库的 IP,1434 是端口。

当我执行时,我使用一个名为 network_gls(似乎不起作用)的 docker 网络将我的容器(gls_appmssql_1mssql_2)连接在一起:

docker inspect network_gls

(注意:此行的执行是在 Springboot 应用容器启动之后和出错之前)

我得到以下结果:

[
{
    "Name": "network_gls",
    "Id": "88895acb2247b3b63b0cc29656fcb6d1a0d4a8192a8c7c1bb7b79362509e0742",
    "Created": "2020-09-28T15:21:39.995019917Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
        "Driver": "default",
        "Options": {},
        "Config": [
            {
                "Subnet": "172.21.0.0/16",
                "Gateway": "172.21.0.1"
            }
        ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
        "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
        "0754d8766736806549e99500c143420c556e9370c14f897f6beb82c24a3c1124": {
            "Name": "mssql_1",
            "EndpointID": "6d886cf8f2aed256d8cbc7141d9ea5242f7ce61d95ae5412c16905d1b490f133",
            "MacAddress": "02:42:ac:15:00:02",
            "IPv4Address": "172.21.0.2/16",
            "IPv6Address": ""
        },
        "54d20a9a409053eaf53eb5c7e73e340ab29c12ceaf8ac20b109d1403cba0c3d3": {
            "Name": "mssql_2",
            "EndpointID": "e675f72fc6c737201a31dd485496e749d386165eaa90a6647e0bf13507683028",
            "MacAddress": "02:42:ac:15:00:03",
            "IPv4Address": "172.21.0.3/16",
            "IPv6Address": ""
        },
        "7e4ae1a46358fe9081c5277cb52ec49681b44631d6d9c1cdcaf6116326277d37": {
            "Name": "gls_app",
            "EndpointID": "d9051cd0134f5074b2b756b44b60cced85d2cac2fd04653e0f52ddb9ada339b9",
            "MacAddress": "02:42:ac:15:00:04",
            "IPv4Address": "172.21.0.4/16",
            "IPv6Address": ""
        }
    },
    "Options": {},
    "Labels": {}
}
]

在我的 Springboot 应用程序中,我的连接字符串如下所示(mssql_2 中的数据库示例):

 jdbc:sqlserver://172.21.0.3:1433;DatabaseName=gls

docker 网络方面对我来说是新的,如果我在这个问题中遗漏了重要信息,请告诉我

提前致谢

【问题讨论】:

  • 如何启动 3 个容器? docker-compose?
  • @DuyPhan 我将docker-compose up 用于我的数据库,docker run 用于 Springboot 应用程序,您认为这可能是个问题吗?
  • 您是否阅读过背景资料,例如 Docker 文档中的 Networking in Compose?您能否提供一个minimal reproducible example,包括docker-compose.yml 和完整的docker run 命令? (如果您不在 Compose 创建的网络上使用 docker run --net,它将无法正常工作;docker inspect 通常不需要容器来查找其 IP 地址或最佳实践。)

标签: spring-boot docker docker-networking


【解决方案1】:

在我的情况下,当我使用容器名称而不是 IP 地址时,它确实有效。 所以而不是:

 jdbc:sqlserver://172.21.0.3:1433;DatabaseName=gls

试试这个:

 jdbc:sqlserver://mssql_2:1433;DatabaseName=gls

如果您想测试您的网络是否有问题,您也可以尝试发布您的端口。 https://docs.docker.com/config/containers/container-networking/

【讨论】:

  • 这对我不起作用,仍然有相同的 SQLServerException
  • 您是否尝试发布您的端口以查看是否是网络问题?数据库 docker 是否正常运行?我建议发布数据库端口并尝试连接数据库客户端,以确认数据库服务器运行正常。要同时对两个数据库进行测试,您需要使用映射到每个数据库的不同端口。例如-p 1433:1433 和 -p 1434:1433
  • 是的,尝试过:docker-compose -f ./mssql_2.yml -p 1434:1434 up
  • 我可以使用 SQL Server Management Studio 连接到容器中运行的数据库
  • 我的另一个数据库在 1433:1433
【解决方案2】:

编辑:感谢 David 指出不需要 container_name。可以使用服务名连接。

您可以创建一个 docker compose 并使用它来启动您的数据库。给出的是你使用的 docker compose 和 application.properties 的示例。

您可以在从另一个容器连接到 db 时使用您的 docker 服务名称。从 localhost 连接,大多数情况下端口暴露为port:port,可以作为 localhost 访问。

docker-compose build web .
docker-compose up db
docker-compose up web   

docker-compose up

  • 不从容器访问时可以使用localhost

Docker 编写文件

version: "3.3"
services:
  web:
    build:
      context: ./
      dockerfile: Dockerfile
    image: web:latest
    ports:
      - 8080:8080
    environment:
      POSTGRES_JDBC_USER: UASENAME
      POSTGRES_JDBC_PASS: PASSWORD
      SPRING_DATASOURCE_URL: "jdbc:postgresql://db:5432/DATABASE"
      SPRING_PROFILES_ACTIVE: dev

    command: mvn spring-boot:run -Dspring.profiles.active=dev
    depends_on:
      - db
      - rabbitmq

  db:
    image: "postgres:9.6-alpine"
    ports:
      - 5432:5432
    expose:
      - 5432
    volumes:
      - postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: USERNAME
      POSTGRES_PASSWORD: PASSWORD
      POSTGRES_DB: DATABASE


volumes:
  postgres:
  app:

这是应用程序属性(用于本地开发):

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=USERNAME
spring.datasource.password=PASSWORD

希望这会回答。

【讨论】:

  • 在典型使用中,您无需指定links:container_name:command:。数据库 URL 不会是 localhost: 在 Docker 中几乎总是意味着“这个容器”,所以它会导致 Spring 容器连接到 Spring 容器而不是数据库容器。
  • @David - links 已删除(不是必需的)。 command - 不需要。 localhost - 是从本地机器连接而不是从容器连接,而是与其他容器连接 container_name 是必需的。
  • 您可以使用其服务块的名称连接到其他 Compose 服务:如果该块被命名为 db:,您可以使用主机名连接到 db,而无需使用 container_name:。这在 Docker 文档中的 Networking in Compose 中有更多描述。
猜你喜欢
  • 1970-01-01
  • 2020-10-05
  • 2016-09-22
  • 2019-03-17
  • 2020-03-08
  • 2018-12-12
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
相关资源
最近更新 更多