Docker - 将 http 请求从一个容器发送到另一个容器

sym*_*mpi 5 docker reactjs

当我在 AWS 服务器生产中运行应用程序时,我无法向后端容器发送 HTTP 请求。但是,当我在本地运行应用程序时,我可以向后端发出请求。为了提出请求,我使用 fetch:

fetch('http://localhost:8000/something')
Run Code Online (Sandbox Code Playgroud)

这是项目结构的样子:

.
??? docker-compose.yml
|
??? backend
?   ??? Dockerfile
?   ??? server.js
|
??? frontend
    ??? Dockerfile
    ??? package.json
    ??? public
    ?   ??? index.html
    ??? src
       ??? components
       ??? data
       ??? index.js
       ??? routes.js
       ??? static
       ??? tests
       ??? views
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml:

version: '3'

services:
  frontend:
    build:
      context: .
      dockerfile: frontend/Dockerfile
    volumes:
      - ./frontend:/frontend
    ports:
      - "80:5000"
    links:
      - backend
  backend:
    build:
      context: .
      dockerfile: backend/Dockerfile
    volumes:
      - ./backend:/backend
    ports:
      - "8000:8000"
Run Code Online (Sandbox Code Playgroud)

前端的 Dockerfile:

FROM node:latest

RUN mkdir -p /frontend

WORKDIR /frontend

ADD . /frontend

VOLUME ["/frontend"]

EXPOSE 5000

CMD yarn && yarn build && yarn global add serve && serve -s build
Run Code Online (Sandbox Code Playgroud)

后端的 Dockerfile:

FROM node:latest

RUN mkdir -p /backend

WORKDIR /backend

ADD . /backend

VOLUME ["/backend"]

EXPOSE 8000

CMD yarn && yarn start
Run Code Online (Sandbox Code Playgroud)

有人可以解释我的配置有什么问题吗?我很困惑,因为它在本地没有任何问题。

C J*_*nes 11

TLDR:需要更改前端代码以调用当前主机而不是“localhost”

问题是,当从您的浏览器访问时,您的应用程序说“嘿 localhost”而不是“嘿 VPS ip”。您需要编辑前端代码才能访问您正在访问的当前主机。这就是您在本地主机服务器上收到请求的原因。

而不是fetch("http:///localhost:8000/something")将其更改为fetch("http://"+location.host+":8000")(有更好的方法,这可以完成)。

另请注意,docker 容器在网络方面也略有不同。Docker 容器并不像非 Docker 容器应用程序那样真正具有“本地主机”的概念。在服务器之间进行呼叫时,您必须使用 VPS 的 IP/本地 IP。我使用的一个技巧是使用 docker 的默认 docker0 网桥 172.17.0.1。

我倾向于通过“链接”使用网络,实际上无法对其进行完全评论,但是当容器位于同一个 docker 网络上时,您可以使用容器的名称访问其他容器。然而,这仅适用于服务器端代码,即:node.js 服务器 -> node.js 服务器/mongo db。示例 mongodb 连接是mongodb://mongo_server:27017/mydatabase,mongo_server 将解析为容器的 IP。

尝试使用 IP 时您可能会遇到的另一件事是您的防火墙,您还必须允许该特定 IP/端口通过您的防火墙。

  • 在 EC2 本身上,它理解“localhost”是什么,因此“curl localhost:8000”将起作用。您正在访问的浏览器将访问您的“本地主机”,如果您关闭服务器,它将无法工作。另一个问题可能是 EC2 的某些内置功能。在数字海洋上,没有内置防火墙,您可以公开任何您想要的端口,但是在 Azure 上,您需要在其 GUI 中添加显式“端点”以允许连接到这些端口。我从未使用过 EC2,所以我无法对此发表评论。 (2认同)