7 months 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: 111 Replies
Status changed to Awaiting User Response Railway • 7 months ago
jake
You cannot use the internal URL during the build
7 months 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 • 7 months ago
7 months ago
You would have to use the public database during build just to generate the static pages.
Status changed to Awaiting User Response Railway • 7 months ago
brody
You would have to use the public database during build just to generate the static pages.
7 months 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 • 7 months ago
7 months 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 buildThis 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 • 7 months 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
7 months 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 • 7 months ago
7 months 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 • 7 months 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!
7 months ago
Wow, awesome. Indeed such a common usecase so there must be a solution out there! :-)
7 months 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!
6 months 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.
oldo
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.
2 months ago
Hey Oldo, sharing this simpler solution incase you're still using the public db url as i've just set up my own payload project:
You can set the next.js build command so hat it uses dynamic pages only (removing the need for database during build) then, before starting the container, generate the static pages using a pre-deploy command which enables you to use the private network db url string.
build command: cross-env NODE_OPTIONS=--no-deprecation next build --experimental-build-mode compile --turbo
a pre-deploy command of: cross-env NODE_OPTIONS=--no-deprecation next build --experimental-build-mode generate --turbo`
Hope this helps if still relevant!

