skip to Main Content

New to Docker here. I’ve been experiencing a confusing roadblock with my Nextjs app, which is running in its own container alongside API and database containers.

My Nextjs app consumes data from the API container. This works great server-side: the Nextjs app resolves the container hostname as it should. Client-side, however, the app breaks because the container hostname means nothing to the browser (I think?). I’m rather lost as to how I can handle this. Ideas?

Here’s my Docker Compose file, in the case that it helps elucidate my question. Note that I’m passing the hostname to the Nextjs app via the environment field:

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

Additional information:

  • Using curl on my API, as “localhost:5000”, works.

  • In dev console, Nextjs app makes a call to “localhost:3000/” to fetch data server-side. This makes sense given how Nextjs works.

  • In dev console, Nextjs app makes call to “mywebapp-api:5000/” to fetch data client-side. Obviously, this doesn’t work.

2

Answers


  1. Okay so i found a solution/workaround. I was reading online and i found only 1 way. And that’s to setup reverse-proxy to nextjs server sth like this: Proxy to backend with default Next.js dev server. But i fixed it differently: so nextjs has 2 types of env variables, the ones that are exposed only to SERVER(BACKEND_URL=http://servicename:port) and ones that are exposed to SERVER AND CLIENT(NEXT_PUBLIC_BACKEND_URL=http://localhost:port) – here i define localhost so the browser can read the api. And you only do this to setup axios:

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

    Now on client side it will use http://localhost:port and on SSR will use http://servicename:port.

    Login or Signup to reply.
  2. If you want to work in your computer(local environment), you can change the IP for the backend in next.config.js. For example if your computer has the IP 192.168.1.23 and the container for the backend is running in the port 3000, then you next.config.js must have the next:

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

    Also for you axios configuration can look like the next:

    import axios from 'axios';
    
    const wrapperAxios = axios.create({
      baseURL: process.env.backendUrl,
      headers: { 'Content-type': 'application/json' },
    });
    export default wrapperAxios;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search