mdw7326
mdw7326

Reputation: 444

Docker Hostnames not resolving in next.js prod but working in dev mode (Error: getaddrinfo ENOTFOUND)

I'm running a next.js react app in a docker container. It's being composed with several other contains: one running Ghost (I'm using the API), one running mysql, and one running NGINX. I've got everything running in development mode.

It works perfectly when run using next dev. But when I run it by doing next build and next start, I start seeing errors like Error: getaddrinfo ENOTFOUND ghost-api when I try to make server-side HTTP requests to my Ghost API container. I'm not entirely sure what the issue is but it seems like there's some issue with how Node is making requests after being built. I've been digging through a lot of Docker/Node questions trying to figure this one out but haven't had any luck.

The entire project can be found here: https://github.com/MichaelWashburnJr/react-cms

Upvotes: 12

Views: 3724

Answers (4)

thegaram
thegaram

Reputation: 777

It seems that Docker's hostname resolution does not work during build time. That is why ghost-api is not found.

Instead of referencing the other container by its name (ghost-api), on Mac you can try host.docker.internal. On Linux, using host networking during build worked for me:

nextjs-app:
  build:
    network: "host"
  # ...
  network_mode: "host"

This way, you can reference the other container using localhost.

Upvotes: 1

Daniele Ricci
Daniele Ricci

Reputation: 15797

After cloning your repos:

$ grep -R ST_API *
frontend/.env.development:GHOST_API_URL=http://ghost-api:2368
frontend/.env.production:GHOST_API_URL=http://ghost-api:2368
frontend/src/constants/Config.js:export const getGhostApi = () => process.env.GHOST_API_URL || 'http://localhost:8000';

ghost-api is not a domain name: to make it work you need to edit your hosts file or (for a real production environment) to change http://ghost-api:2368 in frontend/.env.production file with the real deploy domain name.

If you are asking why you can't trust on docker compose networking, the answer is: you can, but only in the containers; while the front end will run in the browser of your application client, which is outside the containers.

Hope this helps.

Upvotes: 0

groot
groot

Reputation: 420

The problem may exist in the environment variable that you are using. In both getGhostApi and getGhostApiKey function, you are using the environment variable.

In NextJs you'll have to specify a next.config.js in which you define the variables that you need for

Ex. next.config.js

module.exports = {
  serverRuntimeConfig: {
    // Will only be available on the server side
    mySecret: 'secret',
    secondSecret: process.env.SECOND_SECRET, // Pass through env variables
  },
  publicRuntimeConfig: {
    // Will be available on both server and client
    staticFolder: '/static',
  },
}

You can also refer to the next documentation for the same. https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration

Upvotes: 1

Shashank V
Shashank V

Reputation: 11183

I'm not able to reproduce the error. How are you starting the frontend container in prod mode?

From the error it appears like you might be trying to start the frontend container or the frontend app as a separate process without starting it as part of the compose project. If that is the case, the name ghost-api won't be resolvable and you would get the Error: getaddrinfo ENOTFOUND ghost-api error.

I've changed the command key of frontend container as follows:

command:  [ "yarn", "start-prod" ]

Changed the "start-prod" script in frontend/package.json as follows:

"start-prod": "next build && NODE_ENV='production' next start"

and everything worked as it worked in dev mode. I got some UNKNOWN_CONTENT_API_KEY error in both dev and prod mode but definitely there is no ghost-api name resolution error.

Upvotes: 1

Related Questions