Nextjs + Docker-Compose:如何解析客户端容器主机名?

gol*_*und 3 isomorphic-javascript docker-compose next.js docker-network

这里是 Docker 新手。我的 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
Run Code Online (Sandbox Code Playgroud)

附加信息:

  • 在我的 API 上使用curl“localhost:5000”是有效的。

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

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

Bla*_*rov 6

好吧,我找到了一个解决方案/解决方法。我在网上阅读,发现只有一种方法。这就是为 nextjs 服务器设置反向代理,如下所示:Proxy to backend with default Next.js dev server。但我以不同的方式修复了它:所以 nextjs 有 2 种类型的环境变量,一种只暴露给 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;
Run Code Online (Sandbox Code Playgroud)

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