7 months ago
While deploying the multiplied-next
service on Railway, the deployment fails with an error indicating an inability to resolve the PostgreSQL service hostname (postgres.railway.internal
).
This issue persists even though the PostgreSQL service is running without any problems, as shown in the attached screenshot below.
The error occurs whether the DATABASE_URL
is set using an environment variable reference (`DATABASE_URL="${{Postgres.DATABASE_URL}}"`) or by hardcoding the URL directly (`postgresql://[REDACTED]:[REDACTED]@postgres.railway.internal:5432/railway`). However, the error does not occur when using the Postgres.DATABASE_PUBLIC_URL
environment variable reference.
The error prevents the multiplied-next
service from successfully completing the deployment process.
Expected Behavior: The service should be able to connect to the PostgreSQL instance using the postgres.railway.internal
hostname and complete the deployment successfully.
Actual Behavior: The deployment fails with the following error message in the logs:
#12 7.119 [16:00:16] ERROR: Error: cannot connect to Postgres. Details: getaddrinfo ENOTFOUND postgres.railway.internal
#12 7.119 err: {
#12 7.119 "type": "Error",
#12 7.119 "message": "getaddrinfo ENOTFOUND postgres.railway.internal",
#12 7.119 "hostname": "postgres.railway.internal"
#12 7.119 }
The PostgreSQL service is active and running, as seen in the attached screenshot (below), but the application cannot resolve the internal hostname.
Logs:
#12 5.219
#12 7.119 [16:00:16] ERROR: Error: cannot connect to Postgres. Details: getaddrinfo ENOTFOUND postgres.railway.internal
#12 7.119 err: {
#12 7.119 "type": "Error",
#12 7.119 "message": "getaddrinfo ENOTFOUND postgres.railway.internal",
#12 7.119 "errno": -3008,
#12 7.119 "code": "ENOTFOUND",
#12 7.119 "syscall": "getaddrinfo",
#12 7.119 "hostname": "postgres.railway.internal"
#12 7.119 }
#12 7.160 ELIFECYCLE Command failed with exit code 1.
#12 ERROR: process "/bin/bash -ol pipefail -c pnpm install --frozen-lockfile && pnpm run build || pnpm run payload migrate:down" did not complete successfully: exit code: 1
Environment:
Service:
multiplied-next
Database: PostgreSQL
Deployment method: Railway dashboard with Docker build
Build command:
pnpm install --frozen-lockfile && pnpm run build || pnpm run payload migrate:down
Additional Information:
Attached a screenshot showing the state of services in the Railway dashboard, indicating that PostgreSQL is running, while the
multiplied-next
service is failing.The issue seems to be related to DNS resolution within the Railway private network.
Attachment:
13 Replies
7 months ago
Hello,
The private network is not available during build -
https://docs.railway.app/guides/private-networking#caveats
Please run the migrations during runtime before starting your application.
As long as you use a readiness type health check Railway wont switch over traffic until your application is ready to handle traffic.
Status changed to Awaiting User Response railway[bot] • 7 months ago
Status changed to Awaiting Railway Response railway[bot] • 7 months ago
Status changed to In Progress brody • 7 months ago
Status changed to Solved brody • 7 months ago
Status changed to Awaiting Railway Response brianfryer • 7 months ago
7 months ago
Hi Brody,
Thanks again for the clarification regarding the unavailability of the private network during the build phase. I understand that I need to run the migrations during runtime before starting the application.
However, I have a follow-up question: how can I conditionally use different database URLs during build time and runtime? For instance, during the build phase, when the internal database is unavailable, I want to use the DATABASE_PUBLIC_URL (to leverage Next.js' static route optimization). Here’s a code snippet that illustrates what I have in mind:
```
db: postgresAdapter({
pool: {
connectionString: process.env.IS_BUILD === 'true'
? env.DATABASE_PUBLIC_URL
: env.DATABASE_URL,
}
}),
```
This setup would allow the build process to use the public URL, avoiding the need for export const dynamic = 'force-dynamic';
in my Next.js page.tsx files. Once the application is deployed, it would switch to using DATABASE_URL to prevent egress fees and utilize Next.js' revalidation mechanisms for caching generated HTML.
Could you advise on whether this approach is feasible on Railway and, if so, any best practices for managing this conditional logic in the environment variables?
Thanks for your help!
7 months ago
Hey @brianfryer! Not Brody, but they can add some additional info when they see your message..
To answer the main question, it is totally acceptable to use the public URL during build and the internal URL at deployment, and some of our customers already do this. In the future, private network will be available at build time as well so you'll not have to manage this condition forever.
Status changed to Awaiting User Response railway[bot] • 7 months ago
7 months ago
I think your ternary operator would do great!
In your package.json you can prefix your build script with IS_BUILD=true
so that your code uses the correct URL with that ternary operator.
7 months ago
@melissa — awesome! thank you for letting me know!
@body — and thank you for chiming in as well.
Unfortunately, I'm getting an error when attempting to implement such logic.
In my environment, I have these variables set:
DATABASE_URL="${{Postgres.DATABASE_URL}}"
DATABASE_PUBLIC_URL="${{Postgres.DATABASE_PUBLIC_URL}}"
Here is my railway.json
config file:
{
"build": {
"buildCommand": "IS_BUILD=true pnpm install --frozen-lockfile && pnpm run build || pnpm run payload migrate:down",
"startCommand": "sleep 3 && pnpm run start"
},
"variables": {
"NIXPACKS_NODE_VERSION": "18"
}
}
And here is the relevant part of the logs:
#12 57.66 [23:05:40] ERROR: Error: cannot connect to Postgres. Details: getaddrinfo ENOTFOUND postgres.railway.internal
#12 57.66 err: {
#12 57.66 "type": "Error",
#12 57.66 "message": "getaddrinfo ENOTFOUND postgres.railway.internal",
#12 57.66 "stack":
#12 57.66 Error: getaddrinfo ENOTFOUND postgres.railway.internal
#12 57.66 at /app/node_modules/.pnpm/pg-pool@3.7.0_pg@8.11.3/node_modules/pg-pool/index.js:45:11
#12 57.66 at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
#12 57.66 at connectWithReconnect (/app/node_modules/.pnpm/@payloadcms+db-postgres@3.0.0-beta.116_payload@3.0.0-beta.116_graphql@16.9.0_monaco-editor@0._abenlmjs4wylc4gdw7q644nbea/node_modules/@payloadcms/db-postgres/src/connect.ts:22:14)
#12 57.66 at Object.connect (/app/node_modules/.pnpm/@payloadcms+db-postgres@3.0.0-beta.116_payload@3.0.0-beta.116_graphql@16.9.0_monaco-editor@0._abenlmjs4wylc4gdw7q644nbea/node_modules/@payloadcms/db-postgres/src/connect.ts:65:7)
#12 57.66 at BasePayload.init (/app/node_modules/.pnpm/payload@3.0.0-beta.116_graphql@16.9.0_monaco-editor@0.52.0_react-dom@19.0.0-rc-3edc000d-20240_evsx4covwley5xhuggvt42bcri/node_modules/payload/src/index.ts:518:7)
#12 57.66 at migrate (/app/node_modules/.pnpm/payload@3.0.0-beta.116_graphql@16.9.0_monaco-editor@0.52.0_react-dom@19.0.0-rc-3edc000d-20240_evsx4covwley5xhuggvt42bcri/node_modules/payload/src/bin/migrate.ts:45:3)
#12 57.66 at async start (file:///app/node_modules/.pnpm/payload@3.0.0-beta.116_graphql@16.9.0_monaco-editor@0.52.0_react-dom@19.0.0-rc-3edc000d-20240_evsx4covwley5xhuggvt42bcri/node_modules/payload/bin.js:30:7)
#12 57.66 "errno": -3008,
#12 57.66 "code": "ENOTFOUND",
#12 57.66 "syscall": "getaddrinfo",
#12 57.66 "hostname": "postgres.railway.internal"
#12 57.66 }
As you can see here, the build is failing because it couldn't connect to postgres.railway.internal
(the non-public database URL) even though IS_BUILD=true
is set in the buildCommand
setting.
Any ideas on what I might be doing wrong?
Status changed to Awaiting Railway Response railway[bot] • 7 months ago
7 months ago
Please don't run install commands in the build command, it's redundant as pnpm i --frozen-lockfile
is already being ran in the install phase.
Try moving IS_BUILD=true
into the build script in your package.json.
Status changed to Awaiting User Response railway[bot] • 7 months ago
7 months ago
Aha! Thank you @brody, that did the trick.
Wow, this is awesome.
Status changed to Awaiting Railway Response railway[bot] • 7 months ago
Status changed to Awaiting User Response railway[bot] • 7 months ago
7 months ago
Awesome, glad you got it working!
Similar issue but I have a remix app with the following vite.config.ts
where i inline environment variables at build time. is there any workaround?
export default defineConfig({
define: {
"process.env.API_URL": JSON.stringify(process.env.API_URL),
"process.env.WS_API_URL": JSON.stringify(process.env.WS_API_URL),
},
});
Status changed to Awaiting Railway Response railway[bot] • 7 months ago
Status changed to Awaiting User Response railway[bot] • 7 months ago
7 months ago
For Vite don't the variables need to be prefixed with
VITE_
?
Wow that must be new
Status changed to Awaiting Railway Response railway[bot] • 7 months ago
Status changed to Awaiting User Response railway[bot] • 7 months ago