NextJS build fails using internal database URL

oldoPRO

20 days ago

I have a NextJS project (based on PayloadCMS) that points to a Postgres database using the database's internal URL. The build command is failing when NextJS tries to generate static pages. If I use the public database URL I have no issues building.

I understand that the internal database URL can not be used in the build step and it first becomes available in the preDeployCommand

How then can I use the internal database URL for a NextJS project? This must be a common issue so I'm sure I'm doing something obviously wrong.

Here is a snippet from the build logs:

pnpm run build

process "pnpm run build" did not complete successfully: exit code: 1

Generating static pages (0/15) ...
Generating static pages (3/15) 
Generating static pages (7/15) 
Generating static pages (11/15) 

[18:59:44] ERROR: Error: cannot connect to Postgres. Details: getaddrinfo ENOTFOUND website-db.railway.internal
    err: {
      "type": "Error",
      "message": "getaddrinfo ENOTFOUND website-db.railway.internal",
      "stack":
          Error: getaddrinfo ENOTFOUND website-db.railway.internal
              at /app/.next/server/chunks/524.js:189:34172
              at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
              at async lx (/app/.next/server/chunks/524.js:174:19557)
              at async Object.l_ [as connect] (/app/.next/server/chunks/524.js:174:19893)
              at async tJ.init (/app/.next/server/chunks/524.js:221:17308)
      "errno": -3008,
      "code": "ENOTFOUND",
      "syscall": "getaddrinfo",
      "hostname": "website-db.railway.internal"
    }

⨯ Next.js build worker exited with code: 1 and signal: null

 ELIFECYCLE  Command failed with exit code 1.

ERROR: failed to solve: process "pnpm run build" did not complete successfully: exit code: 1
$10 Bounty

10 Replies

20 days ago

You cannot use the internal URL during the build


Status changed to Awaiting User Response railway[bot] 20 days ago


jake

You cannot use the internal URL during the build

oldoPRO

20 days ago

Hi Jake, yes, I understand that.

Can you then explain how NextJS apps can be deployed on Railway using the internal database URL? Because the generation of static pages at build time requires requests to the db I can only see the possibility of using the public URL.

There is nothing unusual about what I am doing so I assume that there must be a solution. I would really like to host our website on Railway alongside all the other infra we have here and would prefer to not use Vercel just for our website if possible.

Thanks,

Ollie.


Status changed to Awaiting Railway Response railway[bot] 20 days ago


20 days ago

You would have to use the public database during build just to generate the static pages.


Status changed to Awaiting User Response railway[bot] 20 days ago


brody

You would have to use the public database during build just to generate the static pages.

oldoPRO

20 days ago

Thanks Brody. I can't figure out though how to use the public URL during build but then use the internal URL at runtime. Are you able to suggest an approach that would resolve this issue?


Status changed to Awaiting Railway Response railway[bot] 20 days ago


20 days ago

Sure!

Have two service variables set on your NextJS service -

DATABASE_URL=${{Postgres.DATABASE_URL}}
DATABASE_PUBLIC_URL=${{Postgres.DATABASE_PUBLIC_URL}}

Use only DATABASE_URL in code (aka the private URL)

Then, for your build command, temporarily overwrite the private variable with the public variable -

DATABASE_URL=$DATABASE_PUBLIC_URL pnpm run build

This will overwrite the DATABASE_URL variable with the DATABASE_PUBLIC_URL for only that single build command.

Best,
Brody


Status changed to Awaiting User Response railway[bot] 20 days ago


brody

Sure!Have two service variables set on your NextJS service -DATABASE_URL=${{Postgres.DATABASE_URL}} DATABASE_PUBLIC_URL=${{Postgres.DATABASE_PUBLIC_URL}}Use only DATABASE_URL in code (aka the private URL)Then, for your build command, temporarily overwrite the private variable with the public variable -DATABASE_URL=$DATABASE_PUBLIC_URL pnpm run buildThis will overwrite the DATABASE_URL variable with the DATABASE_PUBLIC_URL for only that single build command.Best,Brody

oldoPRO

20 days ago

I did try exactly that, but when I logged the database url to console on the served website I can see that I was using the public URL, not the internal URL. It appears that if it is built with the public URL then it will use the public URL when being served.


Status changed to Awaiting Railway Response railway[bot] 20 days ago


20 days ago

It's definitely a common usecase, and it should be using the private URL post build

Unfortunately I'm not sure, but I will put up a $10 bounty on the community to help you out on this one!


Status changed to Awaiting User Response railway[bot] 20 days ago


jake

It's definitely a common usecase, and it should be using the private URL post buildUnfortunately I'm not sure, but I will put up a $10 bounty on the community to help you out on this one!

oldoPRO

20 days ago

Wow, awesome. Indeed such a common usecase so there must be a solution out there! :-)


harryparkesPRO

20 days ago

I think a sensible workaround could to containerise it using Docker and then use the --build-arg & -e flags to set the variable at build & run time?

docker build --build-arg VARIABLE_NAME=value -t image_name

docker run -e VARIABLE_NAME=value image_name

These could live in your DockerFile but you get the idea!

Let me know how you get on as I'm also planning a payload v3 deployment!


harryparkes

I think a sensible workaround could to containerise it using Docker and then use the --build-arg & -e flags to set the variable at build & run time?docker build --build-arg VARIABLE_NAME=value -t image_name docker run -e VARIABLE_NAME=value image_nameThese could live in your DockerFile but you get the idea!Let me know how you get on as I'm also planning a payload v3 deployment!

oldoPRO

19 days ago

Thanks for your response, Harry. I agree that there might be a solution there, but I have limited experience with dockerising an application and I'm concerned about getting bogged down by taking this approach. If you manage to find a solution there please feel free to share your Dockerfile and I'll give it a go. In the mean time I was really hoping to just use Railpacks from Railway and modify the build/prebuild/start commands to keep things simple.