Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js fetch get an ECONNREFUSED error in Docker (Strapi as backend)

Good day everyone. I set up a simple next.js page to get data from Strapi via API. It runs fine locally. But when I run them in Docker, I got a ECONNREFUSED error.

here is the error:

error - TypeError: fetch failed
frontend  |     at Object.fetch (node:internal/deps/undici/undici:11118:11)
frontend  |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
frontend  |     at async getStaticProps (webpack-internal:///./pages/index.tsx:38:17)
frontend  |     at async Object.renderToHTML (/usr/local/frontend/node_modules/next/dist/server/render.js:384:20)
frontend  |     at async doRender (/usr/local/frontend/node_modules/next/dist/server/base-server.js:708:34)
frontend  |     at async cacheEntry.responseCache.get.isManualRevalidate.isManualRevalidate (/usr/local/frontend/node_modules/next/dist/server/base-server.js:813:28)
frontend  |     at async /usr/local/frontend/node_modules/next/dist/server/response-cache/index.js:80:36 {
frontend  |   cause: Error: connect ECONNREFUSED 127.0.0.1:1337
frontend  |       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16) {
frontend  |     errno: -111,
frontend  |     code: 'ECONNREFUSED',
frontend  |     syscall: 'connect',
frontend  |     address: '127.0.0.1',
frontend  |     port: 1337
frontend  |   },
frontend  |   page: '/'
frontend  | }

And here is the code in Next.js:

export async function getStaticProps() {
  const res = await fetch('http://localhost:1337/api/posts')
  const data = await res.json()

  return {
    props: { data },
  }
}

My docker-compose.yml:

version: '3.8'
services:
  backend:
    container_name: backend
    build:
      context: backend
      dockerfile: .docker/dev.dockerfile
    image: backend:latest
    # restart: unless-stopped
    env_file: ./backend/.env
    volumes:
      - strapi_data:/usr/local/backend/strapi/.tmp
      - strapi_upload:/usr/local/backend/strapi/public/uploads
    ports:
      - '1337:1337'
  frontend:
    container_name: frontend
    build:
      context: frontend
      dockerfile: .docker/dev.dockerfile
    image: frontend:latest
    # restart: unless-stopped
    env_file: ./frontend/.env
    volumes:
      - node_modules_next:/usr/local/frontend/node_modules
      - next_folder:/usr/local/frontend
    ports:
      - '3000:3000'
    depends_on:
      - 'backend'
volumes:
  node_modules_next:
  next_folder:
  strapi_data:
  strapi_upload:

I followed this guide to set up the middleware in Strapi:

export default [
  "strapi::errors",
  "strapi::security",
  // 'strapi::cors',
  {
    name: "strapi::cors",
    config: {
      origin: "*",
      methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"],
      headers: ["Content-Type", "Authorization", "Origin", "Accept"],
      keepHeaderOnError: true,
    },
  },
  "strapi::poweredBy",

  "strapi::logger",
  "strapi::query",
  "strapi::body",
  "strapi::session",
  "strapi::favicon",
  "strapi::public",
];

But it doesn't work.

I also tried to change getStaticProps to getServerSideProps, no luck.

like image 200
ZackChim Avatar asked Oct 23 '25 11:10

ZackChim


2 Answers

Here is what actually happens

at the time you build your docker compose project. it's best practice to use your project service-name as host.

here is the example of networking in docker compose:

# this is your docker compose backend

backend:
    container_name: backend
    build:
      context: backend
      dockerfile: .docker/dev.dockerfile
    image: backend:latest
    # restart: unless-stopped
    env_file: ./backend/.env
    volumes:
      - strapi_data:/usr/local/backend/strapi/.tmp
      - strapi_upload:/usr/local/backend/strapi/public/uploads
    ports:
      - '1337:1337'

here is how you fetch from frontend:

const res = await fetch('http://backend:1337/api/posts')

but in your case it still will fail

here the explanation:

  1. you build a docker compose project of next js with getStaticProp
  2. its fetching the static params at built-time
  3. when the docker compose build the image the network not yet established

** if this help someone i will continue my explanation **

like image 106
Amirul Muminin Avatar answered Oct 25 '25 01:10

Amirul Muminin


Try to put a link on your frontend like that:

frontend:
    container_name: frontend
    build:
      context: frontend
      dockerfile: .docker/dev.dockerfile
    image: frontend:latest
    # restart: unless-stopped
    env_file: ./frontend/.env
    volumes:
      - node_modules_next:/usr/local/frontend/node_modules
      - next_folder:/usr/local/frontend
    ports:
      - '3000:3000'
    depends_on:
      - 'backend'
    links:
      - backend

And then connect to http://backend:1337/api/posts

like image 24
Sergio González Díaz Avatar answered Oct 25 '25 01:10

Sergio González Díaz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!