【问题标题】:How to address backend host with axios, when frontend and backend are in virtual docker network当前端和后端位于虚拟 Docker 网络中时,如何使用 axios 寻址后端主机
【发布时间】:2019-10-15 21:55:05
【问题描述】:

我正在构建一个简单的登录网站,我的 vue-frontend 需要从连接到 sql 数据库的 nodejs-backend 检索用户数据。 我决定为此使用 docker-compose,据我了解,docker-compose 会自动为我的 docker-compose.yml 中提到的服务设置网络。

似乎不起作用的是我在代码中处理后端的方式。 我怀疑这可能是因为我使用 axios 向我的后端发送请求的方式。

我已经检查了默认的 docker-network 并且能够使用我在网络配置中找到的 dns 名称从我的前端 ping 到我的后端。 但是在我的代码中使用相同的名称不起作用。

有效的方法是将主机端口映射到我公开的 api 端口并使用http://localhost:5000 作为地址,但这违背了 docker 网络的目的。

我的 docker-compose.yml:

version: '3.3'

services:
    vue-frontend:
        image: flowmotion/vue-js-frontend
        ports:
            - 8070:80
        depends_on:
            - db-user-api

    db-user-api:
        image: flowmotion/user-db-api
        environment:
            - PORT=5000
        ports:
            - 5000:5000 #only needed if docker network connection can't be established 

有问题的 Vue-fontend 文件:

登录.vue

methods: {
    async login() {
      try {
        const response = await authenticationService.login({
          email: this.email,
          password: this.password
        });
        this.$store.dispatch("setToken", response.data.token);
        this.$store.dispatch("setUser", response.data.user);
        this.$router.push({ path: "/" });
      } catch (error) {
        this.showError = true;
        this.error = error.response.data.error;
      }
    }
  }
};
</script>

authenticationService.js

import api from "@/services/api";

export default {
  login(credentials) {
    return api().post("login", credentials);
  }
};

api.js

import axios from 'axios';
import config from '../config/config';
export default () => {
    return axios.create({
        baseURL: config.userBackendServer
    });
};

config.js()

module.exports = {
    userBackendServer: 'http://cl-dashboard_db-user-api_1:5000' //this doesn't seem to work
};

//using 'http://localhost:5000' works if ports are mapped to host machine.

预期结果将是我的后端进行 sql 查找。

实际结果是,我的前端没有连接到我的后端,而是给了我一个 404 状态并且我的后端永远无法到达

【问题讨论】:

    标签: node.js docker vue.js docker-compose axios


    【解决方案1】:

    你是正确的假设 docker 网络中的容器可以在不向外部世界开放任何端口的情况下相互通信。

    要点是-您的 vue 应用程序不在任何容器中-它作为 js 脚本文件从容器提供给您的浏览器,它是将请求发送到您的节点后端的那个。因为您的浏览器无论如何都不在 docker 网络内 - 您必须使用外部端口映射(在您的情况下为 localhost:5000)才能到达后端。

    如果您对此还有任何疑问,请告诉我。

    【讨论】:

    • 好的,这是有道理的。因此,对于部署,我是否需要使用 docker-compose.yml 中指定的端口指定服务 ip 地址/URI?像这样: userBackendServer: 'URItoMyApp:5000'
    • 把它作为环境变量放在你的.env文件中,在vue应用根目录下。现在它将是VUE_APP_API_ROOT=http://localhost:500/,并在生产中将其更改为您的服务器主机名。您的后端生产容器应该映射到主机默认端口(80 和 443),因此您不需要指定任何端口号。
    • @hudac 正确,CORS 标头不应在生产中使用。通常的架构会放置一个代理服务器(比如 nginx)来为前端文件提供服务,并将/api/* 请求重定向到后端服务器。例如:cli.vuejs.org/guide/deployment.html#docker-nginx
    • 好的,我找到了这个例子 github.com/wkrzywiec/kanban-board/blob/master/kanban-ui/… - nginx 反向代理,它在内部重定向 /api/* 的调用。谢谢!
    • @Vivere 在生产中,您通常会使用代理来实现前端和后端的相同域名(否则您将面临 CORS),因此您可以从请求的 URL 中删除主机名,默认情况下浏览器将使用前端域名作为主机名(例如,您将 AJAX 发送到“/api/image1.png”),不带主机名。
    猜你喜欢
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 2019-07-06
    • 2019-02-17
    • 2020-03-05
    • 2022-10-06
    相关资源
    最近更新 更多