【问题标题】:How to connect frontend to backend via docker-compose networks如何通过 docker-compose 网络将前端连接到后端
【发布时间】:2026-02-01 08:35:01
【问题描述】:

我正在尝试对我的 angular + express 应用程序进行 dockerize。我有一个创建两个容器的 docker-compose 文件,我可以从我的主机(使用我的浏览器)中访问容器,但是每当我尝试从 http 访问后端时,我只会得到一个“ERR_NAME_NOT_RESOLVED”我的前端提出的请求。

我查看了这个问题,似乎大多数人建议服务名称和容器端口应该足以在它们位于同一网络上时击中另一个容器。我尝试点击“http://express:8000/user?user=030f0e70-9a8f-11e9-b5d1-f5cb6c0f3616”,鉴于我从其他地方看到的情况,我认为它应该可以工作,但无论如何,我都会遇到同样的错误。

我的 docker-compose 文件看起来像

version: '3' # specify docker-compose version

# Define the services/containers to be run
services:
  angular: # name of the first service
    build: ./ # specify the directory of the Dockerfile
    ports:
      - "4200:80" # specify port forewarding
    links:
      - "express"
    depends_on:
      - "express"

  express: #name of the second service
    build:  # specify the directory of the Dockerfile
      context: ./
      dockerfile: dockerfile.be
    ports:
      - "8000:8000" #specify ports forewarding
    expose:
      - "8000"

理想情况下,我希望我的前端能够使用设置的端点访问另一个容器,这样我就可以以最少的更改部署应用程序。我会很感激任何建议。我觉得我错过了一些非常简单的东西,但是经过几个小时的修补,我仍然没有抓住它。

谢谢!

【问题讨论】:

  • 描述遇到ERR_NAME_NOT_RESOLVED,ajax时谁向哪个部分发送请求?以及详细的网址。
  • 我只是使用 Angular HttpClient 将请求发送到我的快递后端。不使用容器时,我可以点击“localhost:8000/user?user=030f0e70-9a8f-11e9-b5d1-f5cb6c0f3616”并从后端获取数据到我的 Angular 应用程序。

标签: docker docker-compose dockerfile


【解决方案1】:

一些事情:

  1. 通过使用expose,您使容器的已发布端口仅可用于链接/网络服务。这是您无法在本地访问它的原因之一。
  2. 您应该尝试点击http://localhost:8000,而不是点击http://express:8000/。该服务正在发布到您的 localhost 系统,并且默认情况下不提供任何服务(例如 IIS、NGINX)。
  3. 在您的撰写文件中添加自定义网络,而不是使用链接。这是现在network containers together的主要方式:

    version: '3' # specify docker-compose version
    
    services:
      angular: # name of the first service
        build: ./ # specify the directory of the Dockerfile
        ports:
          - "4200:80" # maps port 4200 on localhost to 80 in container
        network:
          - mynetwork
        depends_on:
          - "express"
    
      express: # name of the second service
        build:  # specify the directory of the Dockerfile
          context: ./
          dockerfile: dockerfile.be
        ports:
          - "8000:8000" # maps port 8000 on localhost to 8000 in container
        networks:
          - mynetwork
    
    networks:
      mynetwork:

    2:https://docs.docker.com/compose/compose-file/#expose

【讨论】:

    【解决方案2】:

    其实你的流量如下:

    1. 来自angular container的用户浏览器请求页面,然后所有页面将呈现给用户的浏览器。

    2. 前面的javascript代码使用angular HttpClientexpress container获取数据。

      虽然当时docker-compose为你设置了一个自定义的网络,可以提供auto-dns解析angular & express,但是这个dns只能在容器之间工作,对主机无效。

      但是,您调用 http://expressaugular HttpClient 发生在用户的浏览器上,而不是在容器中,因此自动 dns 绝对不能让您解析名称 express

    对你来说,如果你只是想从你的 docker 主机打开浏览器,你可以使用localhost,但如果你还想让其他机器的用户访问你的网站,你必须使用你的 dockerhost 的 ip。

    然后,在angular HttpClient 中你需要使用http://your_dockerhost_ip:8000 之类的东西来访问快递容器。

    有兴趣的可以访问thisUser-defined bridges provide automatic DNS resolution between containers

    【讨论】:

    • 对于 dockerhost_ip,我想这就是我运行 docker-machine ip 时得到的结果?我注意到我可以从前端点击它(在本例中为“192.168.99.100:8000"”),但我不知道在尝试在我的机器之外部署和运行容器时这是否是一个可行的解决方案(比如如果 ip在其他地方运行时发生变化)或者是否有某种方式可以动态获取 ip 而不管它在哪里运行
    • docker-compose.yaml中的angular要设置env_file,见this,然后,如果部署到其他机器,你可以在up之前自定义ip。另一种方法是包装一个脚本start.sh,在其中使用ip a s 来获取当前机器的ip,例如192.168.99.100,然后执行export HOST_IP=192.168.99.100 docker compose up -d,在compose.yaml中,加上environment= - ip=${HOST_IP},指的是docs.docker.com/compose/environment-variables/…
    • 然后在angular容器程序中你应该从环境中读取ip的值并在渲染模板时用这个值填写javascript代码。
    • 因为容器在同一个主机上运行,​​我能够将我的所有请求从我的角度前端定位到“http://”+ location.hostname +“:8000”,这适用于实际上击中后端。感谢您的帮助!
    【解决方案3】:
        **sample docker-compose.yaml**
          version: '3.5'
          services:     
            angular:
              image: "angular-alpine:0.0.1"
              container_name: angular 
              tty: true
              stdin_open: true
              networks:
                app_net:
                ipv4_address: 172.16.238.05
              depends_on:
                - express
    
           express:
             image: "express:0.0.1"
             container_name: express
             tty: true
             stdin_open: true
             networks:
               app_net:
               ipv4_address: 172.16.238.10
    
          networks:
            app_net:
              driver: bridge
            ipam:
            driver: default
            config:
              - subnet: 172.16.238.0/24
    

    >"1. Angular 将在 172.16.238.05:4200 上运行,而 express 将在 172.16.238.10:some-port 上运行。 2.修改你的config.ts或parameter.ts或你配置express url的任何文件为172.16.238.10:some-port。现在你的角度将连接到表达。”

    【讨论】:

      最近更新 更多