两个Docker容器无法通信。

9
我有两个docker容器。一个容器是数据库,另一个容器是Web应用程序。Web应用程序通过此链接http://localhost:7200调用数据库。但是,Web应用程序docker容器无法访问数据库容器。
我尝试过这个docker-compose.yml,但不起作用:
version: '3'
services:
  web:
    # will build ./docker/web/Dockerfile
    build: 
       context: .
       dockerfile: ./docker/web/Dockerfile
    links:
      - graph-db
    depends_on:
     - graph-db
    ports:
     - "8080:8080"
    environment:
      - WAIT_HOSTS=graph-db:7200
    networks: 
      - backend

  graph-db:
    # will build ./docker/graph-db/Dockerfile
    build:
        ./docker/graph-db
    hostname: graph-db
    ports:
      - "7200:7200"

networks:
  backend:
    driver: "bridge"

我有两个容器: Web应用程序:http://localhost:8080/reasoner,该容器调用位于不同容器中的http://localhost:7200的数据库。 但是,Web容器无法访问数据库容器。

解决方案:

version: '3'
services:
  web:
    # will build ./docker/web/Dockerfile
    build: 
       context: .
       dockerfile: ./docker/web/Dockerfile
    depends_on:
     - graph-db
    ports:
     - "8080:8080"
    environment:
      - WAIT_HOSTS=graph-db:7200


  graph-db:
    # will build ./docker/graph-db/Dockerfile
    build:
        ./docker/graph-db
    ports:
      - "7200:7200"

将web应用程序代码中的http://localhost:7200替换为http://graph-db:7200


尝试将图形数据库中的主机名更改为localhost。 - lanxion
2个回答

15
不要使用localhost在容器之间进行通信。网络是docker中的命名空间之一,因此容器内部的localhost仅连接到该容器本身,而不是外部主机或另一个容器。在这种情况下,请在您的应用程序中使用服务名称“graph-db”而不是“localhost”来连接数据库。

在 Web 应用程序的代码中使用 http://graph-db:7200 是有效的!感谢提供解决方案。 此外,我从 docker-compose.yml 中删除了网络,并保留了链接。我不知道这是否是一个好习惯。因此,现在我的 Web 应用程序的代码将使用 http://graph-db:7200 来使用 Docker 容器;但是,当我在本地运行它而没有 Docker 容器时,需要在 URL 中使用 localhost。当然,这是一个不同的问题,我会调查一下。感谢提供 Docker 问题的解决方案。 - zoe vas
1
@zoevas 不需要链接,那是一个遗留功能,会将条目注入到 /etc/hosts 文件中。当容器 IP 由于重新部署、更新或扩展而发生变化时,这种方法就不起作用了。默认情况下,您可以在网络组合创建时获得 DNS,以解析服务名称。如果您没有指定网络,则会看到一个名为 ${project}_default 的网络。 - BMitch
好的,我已经删除了链接,它仍然可以工作。我想这是因为默认情况下服务属于同一个网络,就像你说的${project}_default一样,所以它们可以相互通信。 - zoe vas
只是一个问题,hostname 定义了服务的名称对吗? - Levent Divilioglu
我建议使用服务名称而不是主机名。每个副本可能有唯一的主机名,但共享服务名称和DNS别名。 - BMitch

1
你的数据库主机是 graph-db,在应用程序的数据库配置中应使用该名称。例如:http://graph-db:7200 从 Docker 网络文档(桥接网络 - Docker 的默认网络驱动程序)中可以看到:
想象一个具有 Web 前端和数据库后端的应用程序。 如果您将容器命名为 webdb,则 Web 容器可以连接到位于 db 上的 db 容器,无论应用程序堆栈在哪个 Docker 主机上运行。

我尝试在我的docker-compose中使用主机名,但仍然无法通信。 - user2439278

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接