首页 > 解决方案 > 从服务器端调用 API 需要服务名称作为 API 主机,但在客户端无法访问

问题描述

我正在使用 docker-compose 设置 Laravel API 和 Nuxt 前端。我有两个单独的项目(和两个 docker-compose.yml),我通过网络连接它们。问题是,当我在 Nuxt 的服务器端调用 API 时,API 主机名是 Laravel 的服务,但在客户端无法访问该服务。

API 从容器中的 80 端口映射到我主机上的 8080。在客户端,我可以通过调用http://localhost:8080/api/来访问 API,但我也在 Nuxt 服务器端进行了一些调用,它无法从容器访问主机,因此它必须在http 上调用 API: //应用开发/api

#backend.yml
version: '3.5'
services:
  database:
    image: mariadb:10.3
    networks:
    - my-network
    #...

  app-dev:
    depends_on:
      - "database"
    ports:
    - 8080:80
    networks:
    - my-network
    #...

networks:
  my-network:
    name: my-network
#------------------------
#frontend.yml
version: '3.5'
services:
  front-app-dev:
    ports:
      - ${FRONTEND_SERVER_PORT}:${FRONTEND_SERVER_PORT}
    networks:
      - my-network
    #...

networks:
  my-network:
    external: true

如何统一从服务器端和客户端调用 API?我可以轻松地将节点服务器配置为代理从客户端到 app-dev 的调用(例如代理调用http://localhost :{FRONTEND_SERVER_PORT}/api 到http://app-dev/api)?或者有什么方法可以在前端应用程序开发中访问主机的端口 8080,以便服务器端可以在那里进行调用?

标签: node.jsapidocker-composenuxt.js

解决方案


我设法用 traefik 做到了这一点。我添加了服务:

traefik:
  image: traefik:alpine
  ports:
    - 8000:80
  volumes:
    - ./docker/traefik:/etc/traefik
    - /var/run/docker.sock:/var/run/docker.sock
  networks:
    - my-network
  restart: always

我的 ./docker/traefik.toml:

defaultEntryPoints = ["http"]

[entryPoints]
  [entryPoints.http]
    address = ":80"

[docker]
watch = true
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false
debug = true

我更改了 app-dev 容器,因此 apache 在端口 8000 上提供 API。在 compose 中,我在 app-dev 中添加了以下几行:

labels:
  - "traefik.enable=true"
  - "traefik.docker.network=my-network"
  - "traefik.port=8000"
  - "traefik.frontend.rule=Host:app-dev"

我还将 app-dev 添加到 /etc/hosts,它指向 127.0.0.1。因此,当我在浏览器中输入 app-dev:8000(或客户端调用它时)时,traefik 会将我重定向到 app-dev 容器中的端口 8000。当我在服务器上调用 API 时,它也会调用 app-dev:8000 并像以前一样直接指向容器。所以客户端和服务器都使用相同的地址。


推荐阅读