I have 2 microservices: frontend with next.js and a backend with node.js from where I fetch data via REST-APIs from the frontend.

I now have the problem, that my 2 services don't seem to communicate directly to eachother, the thing is, it works when I fetch the data at the beginnning with the getinitialProps() Method with the fetch-API. My server-side frontend finds the backend via its service-name. However, when I am doing a http-request from the client to the backend (e.g via browser form inputs). It cannot find the backend anymore? Why is that?

here is my docker-compose.yml:

version: '3'

    container_name: dcbackend
      context: ./dcbackend
      dockerfile: Dockerfile
    image: dcbackend
    hostname: dcbackend
      - '7766:7766'

    container_name: dcfrontend
      context: ./dcfrontend
      dockerfile: Dockerfile
    image: dcfrontend
      - /app/node_modules
      - ./dcfrontend:/app      
    hostname: dcfrontend
      - '6677:6677'

Here is one of my browser-client side methods to send data to the backend (via the browser, my url is http:dcbackend... so normally it should find the other docker environment where the backend is, but it does not...

    if (environment == 'dev') {
  url_link = `http://localhost:${port}`;  
} else {
  url_link = `http://dcbackend:${port}`;

let doublettenListe_link = `${url_link}/doubletten/`;

 finishDocumentHandler = (anzeige,index) => {
    let thisDocumentID = anzeige.id;
    const requestOptions = {
        method: 'PUT'

    fetch(doublettenListe_link + thisDocumentID, requestOptions)
    .then((response) => {   
        this.setState({finishSuccess: 'Dubletten in Datenbank eintragen erfolgreich!'});
        this.setState({finishFail: ''});
    .catch((error) => {   
        this.setState({finishSuccess: ''});  
        this.setState({finishFail : `Error beim Erzeugen des Eintrags! Eintrag wurde nicht in Datenbank gespeichert. Bitte prüfen, ob der Server läuft. ${error}`});

Response from network tab from my request is:

Request URL: http://dcbackend:7766/doubletten/304699981
Referrer Policy: no-referrer-when-downgrade
Provisional headers are shown
Access-Control-Request-Method: PUT
Origin: http://localhost:6677
Referer: http://localhost:6677/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36

does it have something to do with docker-configuration, or with CORS() or with anything else? I can't do a client http request to backend, however, the initial fetch from the backend to get some data works...

1 Answers

Tibi02 On Best Solutions

You have to separate the server side and the client side requests. You need to use your host address for the client side requests (eg. http://localhost:7766), because your browser will not be able to reach the backend via docker alias.

You can define the server-only and public runtime config with next.config.js.

For example:

// next.config.js
module.exports = {
  serverRuntimeConfig: {
    // Will only be available on the server side
    apiUrl: 'http://dcbackend:7766'
  publicRuntimeConfig: {
    // Will be available on both server and client
    apiUrl: 'http://localhost:7766'

Then you need get the apiUrl from nextjs with getConfig()

// pages/index.js
import getConfig from 'next/config';

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

const apiUrl = serverRuntimeConfig.apiUrl || publicRuntimeConfig.apiUrl;

const Index = ({ json }) => <div>Index</div>;

Index.getInitialProps = async () => {
    try {
       const res = await fetch(`${apiUrl}/doubletten/304699981`);
       const json = await res.json();
       return { json };
    } catch(e) {
       console.log('Failed to fetch', e);
       return { json: null };

export default Index;