Fetch API failed in Docker, Setting CORS middleware doesn't work

System Information
  • Strapi Version: 4.5.3
  • Operating System: Mac
  • Database: SQLite
  • Node Version: 18
  • NPM Version: 8.15
  • Yarn Version:

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 an ECONNREFUSED 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  | }

I suspect it was caused by the CORS, so after some digging, including this forum, I set this in /config/middlewares.ts:

{
    name: "strapi::cors",
    config: {
      origin: "*",
      headers: "*",
    },
  },

Still not working. What could be the problem? And how can I fix it? Thank you very much.

Here is my fetch code:

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 figured it out myself. Once I run docker-compose on my server, I change the fetch link from http://localhost:1337/api/posts to http://{ip}:1337/api/posts

And it works.

Also they need to be on the same network. else 127.0.0.1 is on the machine not inside docker.
If they are on the same network, you can just say ‚Äúcontainername:1337‚ÄĚ

1 Like