【问题标题】:Nextjs + Docker-Compose: how to resolve container hostname client-side?Nextjs + Docker-Compose:如何在客户端解析容器主机名?
【发布时间】:2020-09-17 18:12:15
【问题描述】:

这里是 Docker 新手。我的 Nextjs 应用程序在我的 Nextjs 应用程序中遇到了一个令人困惑的障碍,该应用程序与 API 和数据库容器一起在自己的容器中运行。

我的 Nextjs 应用使用 API 容器中的数据。这在服务器端工作得很好:Nextjs 应用程序会按应有的方式解析容器主机名。但是,在客户端,应用程序会中断,因为容器主机名对浏览器没有任何意义(我认为?)。我对如何处理这个问题感到很迷茫。想法?

这是我的 Docker Compose 文件,它有助于阐明我的问题。请注意,我通过 environment 字段将主机名传递给 Nextjs 应用程序:

version: '3.8'

services:
    # Redis 
    redis:
        image: redis
        command: redis-server --requirepass ${REDIS_PASSWORD} --bind redis
        ports:
            - "6379:6379"
        networks:
            - mywebappio
    # Data Processing Service
    mywebapp-api:
        container_name: mywebapp-api
        restart: always
        build: 
            context: packages/dps-api
            dockerfile: Dockerfile
        command: npm run dev # npm start prod
        working_dir: /usr/src/dps-api
        env_file: 
            - .env
        volumes: 
            - ./packages/dps-api:/usr/src/dps-api
        ports:
            - "5000:5000"
        networks:
            - mywebappio
        depends_on:
            - redis
    # SSR 'client' app
    nextjs:
        container_name: mywebapp-client
        build:
            context: packages/next-server
            dockerfile: Dockerfile
        command: /bin/bash -c "./wait-for-it.sh mywebapp-api:5000 -- npm run build && npm run start"
        environment: 
            - NEXT_PUBLIC_API_BASE=mywebapp-api:5000
        volumes:
            - ./packages/next-server:/usr/src/app
        ports:
            - "3000:3000"
        networks:
            - mywebappio
        depends_on:
            - mywebapp-api
            - redis
networks:
    mywebappio:
        driver: bridge

附加信息:

  • 在我的 API 上使用 curl 作为“localhost:5000”,可以正常工作。

  • 在开发控制台中,Nextjs 应用程序调用“localhost:3000/”以在服务器端获取数据。考虑到 Nextjs 的工作原理,这是有道理的。

  • 在开发控制台中,Nextjs 应用程序调用“mywebapp-api:5000/”以在客户端获取数据。显然,这是行不通的。

【问题讨论】:

    标签: docker-compose next.js docker-networking isomorphic-javascript


    【解决方案1】:

    好的,所以我找到了解决方案/解决方法。我在网上阅读,我发现只有一种方式。那就是为 nextjs 服务器设置反向代理,如下所示:Proxy to backend with default Next.js dev server。但我以不同的方式修复它:所以 nextjs 有 2 种类型的 env 变量,那些只暴露给 SERVER(BACKEND_URL=http://servicename:port) 和那些暴露给 SERVER AND CLIENT(NEXT_PUBLIC_BACKEND_URL=http://localhost:port) - 这里我定义 localhost 以便浏览器可以读取 api。而你这样做只是为了设置 axios:

    import axios from 'axios';
    
    const instance = axios.create({
      baseURL: process.env.BACKEND_URL || process.env.NEXT_PUBLIC_BACKEND_URL,
    });
    
    export default instance;
    

    现在在客户端它将使用 http://localhost:port 而在 SSR 上将使用 http://servicename:port。

    【讨论】:

      【解决方案2】:

      如果您想在您的计算机(本地环境)中工作,您可以在 next.config.js 中更改后端的 IP。例如,如果您的计算机的 IP 为 192.168.1.23,并且后端的容器在端口 3000 中运行,那么您的 next.config.js 必须具有下一个:

        env: {
          backendUrl: 'http://192.168.1.23:3000/api/v1',
        },
      

      另外,你的 axios 配置可以如下所示:

      import axios from 'axios';
      
      const wrapperAxios = axios.create({
        baseURL: process.env.backendUrl,
        headers: { 'Content-type': 'application/json' },
      });
      export default wrapperAxios;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多