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

时间:2020-05-30 05:53:00

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

这里是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

其他信息:

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

  • 在开发控制台中,Nextjs应用程序调用“ localhost:3000 /”以获取服务器端数据。鉴于Nextjs的工作原理,这很有意义。

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

2 个答案:

答案 0 :(得分:1)

好的,所以我找到了解决方案/解决方法。我在网上阅读,我发现只有一种方法。这就是为{。{3}}这样的nextjs服务器设置反向代理。但是我以不同的方式解决了这个问题: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。

答案 1 :(得分:1)

如果你想在你的电脑(本地环境)中工作,你可以在 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;