【问题标题】:How to connect two docker containers together如何将两个 docker 容器连接在一起
【发布时间】:2021-02-11 08:29:49
【问题描述】:

我有一个reactjs 前端应用程序和一个简单的python flask。我正在使用docker-compose.yml 来启动两个容器,就像这样:

version: "3.2"

services:

  frontend:
    build: .
    environment:
      CHOKIDAR_USEPOLLING: "true"
    ports:
      - 80:80
    links:
      - "backend:backend"
    depends_on:
      - backend 

  backend: 
    build: ./api
    # volumes:
      # - ./api:/usr/src/app
    environment:
      # CHOKIDAR_USEPOLLING: "true"
      FLASK_APP: /usr/src/app/server.py
      FLASK_DEBUG: 1
    ports: 
      - 8083:8083

我使用了links,因此frontend 服务可以使用axiosbackend 服务通信,如下所示:

axio.get("http://backend:8083/monitors").then(res => {
      this.setState({
        status: res.data
      });
    });

我使用docker-compose up --build -d 构建并启动了两个容器,它们启动时没有任何问题并且运行良好。

但现在frontend 无法与backend 对话。

我正在使用AWS ec2 实例。当页面加载时,我尝试查看任何控制台错误并收到此错误:

VM167:1 GET http://backend:8083/monitors net::ERR_NAME_NOT_RESOLVED

有人可以帮帮我吗?

backend 服务已启动并正在运行。

【问题讨论】:

  • Javascript 在客户端运行,主机名backend 只有容器知道,客户端不知道。这仅在您在容器本身(服务器端)上运行代码时才有效。
  • 那么解决方法是什么?我的容器不能互相通信吗?如果服务器IP改变了怎么办?不过我不想使用静态 ip。
  • 您的容器可以相互通信,但客户端不能。我建议在两者前面放置一个反向代理(如 nginx)并使用它。如果代理也是一个容器,你可以使用后端主机名
  • 我正在使用nginx 代理。配置应该是什么样子?
  • @Spirit 客户端能够... 客户端可以通过ports 指令直接使用从容器公开的端口。

标签: docker docker-compose


【解决方案1】:

您可以将 nginx 用作两者的反向代理

撰写文件

version: "3.2"

services:
  frontend:
    build: .
    environment:
      CHOKIDAR_USEPOLLING: "true"
    depends_on:
      - backend 

  backend: 
    build: ./api
    # volumes:
      # - ./api:/usr/src/app
    environment:
      # CHOKIDAR_USEPOLLING: "true"
      FLASK_APP: /usr/src/app/server.py
      FLASK_DEBUG: 1

  proxy: 
    image: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/example.conf
    ports: 
      - 80:80

最小的 nginx 配置(nginx.conf):

server {
    server_name example.com;
    server_tokens off;

    location / {
        proxy_pass http://frontend:80;
    }
}

server {
    server_name api.example.com;
    server_tokens off;

    location / {
        proxy_pass http://backend:8083;
    }
}

请求命中 nginx 容器,并根据域路由到正确的容器。

要使用 example.com 和 api.example.com,您需要编辑您的 hosts 文件:

Linux:/etc/hosts
视窗:c:\windows\system32\drivers\etc\hosts
麦克:/private/etc/hosts

127.0.0.1 example.com api.example.com

【讨论】:

  • 我应该在哪里进行更改 /etc/hosts ?在我的本地计算机(客户端计算机?)或?
  • 是的,你的客户端机器,如果这段代码要投入生产,你需要一个有效的域和一个 dns 条目。
  • 与添加 127.0.0.1 backend 和前端相同的优势是什么?它会带来更多的复杂性,但我们不知道作者是否想向客户公开后端。
  • @DanielHornik 您也可以在生产中使用此设置。作者需要把后端暴露给客户,因为客户需要和后端对话。您映射backend 的解决方案除了使用内部主机名映射之外什么都不做。您还可以使用 nginx 应用更多限制。
  • 但是为什么我需要在/etc/hosts 中输入任何条目。那么这意味着,访问该页面的任何人都需要将条目放入他们的机器中?这实际上是不可能的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 2018-03-01
  • 1970-01-01
  • 2021-11-24
  • 2021-01-26
  • 2018-06-16
相关资源
最近更新 更多