【问题标题】:How can I pass host IP address to Docker Compose file?如何将主机 IP 地址传递给 Docker Compose 文件?
【发布时间】:2021-05-02 05:26:08
【问题描述】:

我正在使用 docker-compose(文件 1)构建一个应用程序,我想知道如何将主机 IP 地址传送到 docker-compose 文件。该应用程序由数据库、前端和后端组成。它的目的是我想从本地网络上的其他计算机访问我的应用程序。它在前端工作正常,但是当我想与后端通信时,它不再工作了。我怀疑这是因为前端正试图将数据发送到本地主机(对于本地网络上的另一台计算机来说,这不是正确的)。因此,我想直接在 docker-compose 文件中与前端应用程序通信主机的 IP 地址,以便它可以与后端通信!有什么想法吗?

文件 1

    version: "3.7"

    services:
      db:
        build: 
          context: ./database
        command: --default-authentication-plugin=mysql_native_password  --sql_mode=""
        restart: always
        cap_add:
          - SYS_NICE  # CAP_SYS_NICE
        volumes:
          - db_data:/var/lib/mysql
        ports:
          - ${MYSQL_PORT}:${MYSQL_PORT}
        environment:
          MYSQL_DATABASE: ${MYSQL_DATABASE}
          MYSQL_PASSWORD: ${MYSQL_PASSWORD}
          MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
          MYSQL_TCP_PORT: ${MYSQL_PORT}
        env_file: ./.env

      back:
        depends_on:
          - db
        build: 
          context: ./backend
          target: development
        volumes: 
          - ./backend:/app
          - /app/node_modules
        restart: "no"
        ports:
          - ${BACKEND_PORT}:${BACKEND_PORT}
        env_file: ./.env

      front:
        depends_on:
          - back
          - db
        build:
          context: ./frontend
          target: development
        stdin_open: true
        volumes:
          - ./frontend:/app
          - /app/node_modules
        restart: "no"
        ports:
          - ${FRONTEND_PORT}:${FRONTEND_PORT}
        env_file: ./.env

    volumes:
      db_data: {}

这是我在前端环境中用于与后端通信的 api url,我将动态替换为主机 IP。

文件 2

const dev = {
    ...env,
    apiUrl: "http://localhost:3000/api",
};

非常感谢您的帮助! 最好的

【问题讨论】:

    标签: docker docker-compose ip host local-network


    【解决方案1】:

    环境变量是一种简单的方式来传递像这样的少量配置。

    对于这种特殊情况,我可能会配置一个 URL 而不是主机的 IP 地址。您可能非常希望将此应用程序部署在负载均衡器后面;该负载均衡器可能会终止 TLS,因此您可以发布 https: URL;您的客户可能无法直接访问您的本地 IP 地址;如果你有一个 IP 地址,你宁愿公布一个 DNS 名称而不是一个 IP 地址。

    在Node代码中你可以在process.env找到环境变量:

    const dev = {
      ...env,
      apiUrl: process.env.API_URL || 'http://localhost:3000/api'
    };
    

    然后在您的docker-compose.yml 中您可以直接设置该网址:

    services:
      front:
        environment:
          API_URL: http://10.20.30.40/api
          # API_URL: https://example.com/myapp/api
    

    【讨论】:

    • 感谢您的回答大卫;这正是我想要做的,但我也想动态添加 ip 地址10.20.30.40/api,而不必每次在新网络上手动指定 ip.. 不确定是否有可能
    【解决方案2】:

    你想要的是shell command substitution
    比如:MYVAR=$(ip route get 1 | awk '{print $NF;exit}')

    很遗憾,compose 不支持命令替换。
    Compose 仅​​支持“静态”shell 变量,即 shell variable expansion
    最好的办法是声明强制变量并带有适当的错误消息。

    # requires for the var to be pre-declared in shell
    environment:
      API_URL: ${API_URL:?"Variable API_URL must present in shell."}
    
    # alternatively you could provide some default value
    environment:
      API_URL: ${API_URL:-192.0.2.2}
    

    另一种解决方案可能是使用envsubst 就地编辑您的撰写文件。
    示例请查看this answer


    还请注意,没有“主机的 ip 地址”之类的东西 :)
    这有点传统而且很模糊term

    “Primary IP”是“无论您的系统何时使用它的别名” 将流量发起到默认路由”。在没有源的情况下 该路由上的短语,这是使用的接口的第一个地址 (或多或少)。

    因此,在编写命令来定义“主机的 IP”时需要小心。
    在简单的网络配置中,这可能或多或少都可以正常工作。
    ip route get 1 | awk '{print $NF;exit}'
    但最好检查一下 discussion 并确保您的最终命令返回您所期望的。

    【讨论】:

      【解决方案3】:

      通过在像这样的特定服务的环境变量中添加 HOST_IP=http://host.docker.internal:PORT

      environment:
        - HOST_IP=http://host.docker.internal:4001/
      

      您可以通过访问节点js代码中的环境变量来访问docker内部的主机ip,例如

      var host_url=process.env.HOST_IP
      

      注意:由于您只能访问主机 ip,因此您需要在 url 末尾手动添加端口,它仅适用于开发服务器,不适用于生产。

      【讨论】:

        【解决方案4】:

        您应该在前端配置中添加一个环境变量,该变量指定 api 端点的 URL,并在 URL 中使用后端容器的主机名。 Networking in Compose 的文档详细介绍了容器使用的默认主机名和网络。

        如下修改你的 docker compose 文件:

        services:
          front:
            environment:
              API_URL: http://back:${BACKEND_PORT}/api
        

        修改你的javascript文件如下:

        const dev = {
          ...env,
          apiUrl: process.env.API_URL || 'http://localhost:3000/api'
        };
        

        【讨论】:

          猜你喜欢
          • 2016-01-17
          • 1970-01-01
          • 2020-05-25
          • 2018-11-13
          • 1970-01-01
          • 2022-06-14
          • 2016-04-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多