My attempts to implement multi-container service deployment using NextJS and a backend node app have been unsuccessful

Currently, I am delving into the world of docker. Within my repertoire, I possess a mix of a next.js app and a node.js app.

Within my next.js application, specifically in page.tsx, I have incorporated a call to my backend API.

export const revalidate = 0;

export default async function Home() {
  const response = await fetch("/api/getRandomNumber");
  const data = await response.json();
  console.log(data);

  return (
    <main className={styles.main}>
      <h1>{data.lastInfo.randomNumber}</h1>
    </main>
  );
}

In the realm of nodejs, I have constructed an endpoint labeled as getRandomNumber utilizing expressjs.

router.get("/getRandomNumber", async (req, res) => {
  const randNumber = `${Math.random() * 100}`;
  const info = new Info({ randomNumber: randNumber });
  await info.save();
  const lastInfo = await Info.findOne({
    where: { randomNumber: randNumber },
  });

  return res.status(200).send({ lastInfo });
});

Though aware that next.js functions as a comprehensive framework, here I strive to comprehend the process of dockerizing multiple services by creating a dedicated node.js application.

Below showcases my Dockerfile for the next.js app:

FROM node:18-alpine

WORKDIR /usr/app

COPY ./package.json ./

RUN npm install

COPY ./ ./

CMD ["npm","run","dev"]

The subsequent segment highlights my Dockerfile for the node.js app:

FROM node:18-alpine

WORKDIR /usr/app

COPY ./package.json ./

RUN npm install

COPY ./ ./

CMD ["npm","run","dev"]

Pursuing this, I have gone ahead with nginx integration. As part of the process, I have generated a directory which holds both default.conf and Dockerfile.dev.

My approach involved appending /api to my nodejs app through default.conf.

Contained within Dockerfile.dev:

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/

Following this progression is the construction of a single docker-compose.yml file accommodating next.js, nginx, and node.js.

version: "3"
services:
  postgres:
    image: "postgres:latest"
    environment:
      - POSTGRES_PASSWORD=postgres_password
  nginx:
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - "3050:80"
    depends_on:
      - nodeapp
      - nextapp
  nodeapp:
    build:
      dockerfile: Dockerfile.dev
      context: ./nodeapp
    volumes:
      - /app/node_modules #don't try to override this folder
      - ./nodeapp:/app
    environment:
      - PGUSER=postgres
      - PGHOST=postgres
      - PGDATABASE=postgres
      - PGPASSWORD=postgres_password
      - PGPORT=5432
  nextapp:
    build:
      dockerfile: Dockerfile.dev
      context: ./nextapp
    volumes:
      - /app/node_modules
      - ./nextapp:/app
    environment:
      - WDS_SOCKET_PORT=0

While successful in accessing my node.js app via

http://localhost:3050/api/getRandomNumber
, encountering issues emerged when attempting to call the node.js API from my next.js app. By disabling the fetch call within my next.js application, operations proceed smoothly on http://localhost:3050/.

An endeavor to contact

http://localhost:3050/api/getRandomNumber
using fetch triggers an error stating "Error: fetch failed."

Moreover, attempts at simply reaching out to /api/getRandomNumber yield the message "Failed to parse URL."

For further insights, refer to the Github repository here.

Additional screenshots can be found below:

https://i.stack.imgur.com/7MRQF.png

https://i.stack.imgur.com/POSKA.png

https://i.stack.imgur.com/MuV2d.png

Answer №1

When making a fetch() call in a NextJS server-side environment, it is important to use the full URL. For example, it should be something like

fetch('http://localhost:3050/api/getRandomNumber')
.

By default, compose creates a network where all containers join. However, if you update your code to use localhost as the base URL, you may encounter an ECONNREFUSED error. This is because localhost is not understood by Docker and points to the container's internal network.

Docker understands service names better than localhost. If you use the service name as the base URL, then it should work properly.

Here is the modified code snippet:


const response = await fetch("http://nginx/api/getRandomNumber", { method: 'GET' });

Of course, using hard-coded URLs is not recommended for production. It is advisable to use environment variables for the base URL. In a production environment, running containers in compose may not be ideal. Standalone EC2/S or Droplet instances are typically preferred.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Sequelize - Establishing relationships and querying data from related tables

I have successfully implemented 3 SQL tables with Sequalize, and here are the schemas: Loans id: DataTypes.INTEGER, book_id: DataTypes.INTEGER, patron_id: DataTypes.INTEGER, loaned_on: DataTypes.DATE, return_by: DataTypes.DATE, returned_on: DataTypes.DA ...

403 You are prohibited from adding more Parents in Google Drive API for React Native

For the past 4 months, my code with react-native-google-drive-api-wrapper was functioning perfectly. However, recently I encountered an issue where I am unable to upload files to any folder in Google Drive using my React Native app. Strangely, I can still ...

Using React Router in conjunction with Nginx

I've been struggling to configure nginx with react router. Despite trying various suggested solutions, none of them seem to address my specific case. Here is the directory structure on my filesystem served by nginx /path/to/my/app |- v1.0/index.html ...

Navigating from an error page to the homepage with Next.JS 13: A quick and easy guide

I'm currently working on implementing a feature that allows users to easily go back to the main page from an error page within the app folder. Specifically, in my weather app project, if a user enters an incorrect city, they should have the option to ...

The issue with Mocha/ Supertest is that it fails to exit once the tests are completed

While using the mocha testing framework, I encountered an issue where the test does not exit after running. I have tried using Promises and async await without success. Including --exit at the end of the mocha command helps to exit, but I am determined to ...

Ways to troubleshoot the error message "dyld: Library not loaded: /usr/lib/libc++.1.dylib Referenced from: /usr/local/bin/node Reason: image not found Trace/BPT trap"

I recently upgraded my Mac to version 10.6.8 and installed Node.js 10.15.3 via the pkg installer from nodejs.org. However, after installation, I encountered an issue when trying to use 'node' or 'npm' in the terminal: dyld: Library not ...

Create custom error messages for loopback instead of using the default ones

I am attempting to customize the default error messages provided by loopback. Here is my approach: server/middleware.json: { "initial:before": { "loopback#favicon": {} }, "initial": { "compression": {}, "cors": { "params": { ...

A beginner's guide to utilizing a node module that has been imported

Recently, I decided to dive into the world of node.js and am encountering some challenges. When it comes to importing modules using npm install (package name), everything seems to be working smoothly. The module appears in the node_modules folder as well a ...

What could be causing a blank page to appear after being redirected? (Using NextJS 13 API Route)

After struggling with this issue for 2 days, I'm throwing in the towel and reaching out to the community for assistance. I've been tasked with setting up a basic login system for a new project using NextJS v13. However, it seems like a lot has c ...

NextAuth is failing to create a session token for the Credential provider

Currently, I am in the process of developing an application using the t3 stack and am facing a challenge with implementing the credential provider from nextauth. Whenever I attempt to log a user in, I encounter an error in the console displaying the messag ...

Managing POST request data in Express: A step-by-step guide

Currently, I am facing an issue with my alert button on the client side, which has an event listener that is supposed to send data to the server. Below is the code snippet for the client side: alertBtn.addEventListener("click", () => { axios ...

New content appears in Material UI v4 Textfield after being typed

One interesting issue I'm facing is with a list of TextFields on the page where users can input text. The variable data holds the dataset. The problem is, as shown in the gif below, there is a delay in displaying the text after the user types. I initi ...

Error: The WebAssembly instantiation failed due to memory exhaustion in wasm allocation

Upon attempting to initiate my node js app in cpanel, I encountered the following error: RangeError: WebAssembly.instantiate(): Out of memory: wasm memory at internal/deps/cjs-module-lexer/dist/lexer.js:1:33573 Interestingly, when working on localhost, ev ...

The perplexing saga of Google Assistant and the WorldWeatherOnline API

I recently started developing API agents for Google Assistant. I followed the instructions provided in the api.ai documentation available at to create an agent that retrieves weather information and provides a response. While the code is functional, I w ...

Issues are arising with the for loop in an express node js app using ejs, as it is not displaying the intended data and

I am currently utilizing a for loop in JavaScript to display all the users from the database using ejs. I have included the code snippet below. This is within an express/node js application where SQL is used for data storage. <div class = "Contacts ...

Cease the execution of a task in Express.js once the request timeout has been

Suppose we have the following code snippet with a timeout of 5 seconds: router.get('/timeout', async (req, res, next) => { req.setTimeout(5000, () => { res.status(503) res.send() }) while (true) { ...

Steps for enabling a feature flag via API in specific environments

Within my project, I am working with three separate environments and I am looking to activate a feature flag only for a specific environment. Is it feasible to toggle an unleash feature flag using the API for just the development environment? The code snip ...

I prefer not to run the next.js SWR until after the initial rendering

Development Setup ・ next.js ・ typescript ・ swr This uses swr for communication purposes. I am looking to only trigger it when the query value changes. However, it is also being executed during the initial rendering. How can I prevent it ...

Unable to load the manually added module in the /node_modules/ folder

I'm trying to manually use a module that I placed in the /node_modules/ directory. After copying and pasting the files and installing dependencies with npm, I encountered an issue while using NWJS 0.16.0. When attempting var speech = require('sp ...

Troubleshooting the Speed Problem Between NextJs and GTM

After successfully integrating GTM into my NextJs project, I noticed a significant drop in my lighthouse performance score. Previously, I was scoring 96 but now I am only at 38. Is there a more efficient way to integrate GTM without negatively impacting th ...