Port Variable implemented as documentation will fail, why ?
yanyetang
FREEOP

a month ago

in my node+Nest.JS project

// node web server
const port = process.env.PORT || 3000;
await app.listen(port, "0.0.0.0");
// when deployed get 502 consistently

// but when changed to following,  will work 
await app.listen(3000, "0.0.0.0");

this is very strange, why ?
Solved$10 Bounty

Pinned Solution

darseen
HOBBYTop 5% Contributor

a month ago

I think that you need to change your target port. Go to your Service Settings > Networking > Public Network, and change it to 8080.

Attachments

14 Replies

Have you tried console.log-ing what process.env.PORT was?


yanyetang
FREEOP

a month ago

Yes, console.log says the app is running on 8080, and deployment is successful initially, but it fails after a few seconds. The log says health check failed, which I have no idea what that means.


yanyetang

Yes, console.log says the app is running on 8080, and deployment is successful initially, but it fails after a few seconds. The log says health check failed, which I have no idea what that means.

When your application was running on 8080, was your URL also mapped to 8080?


0x5b62656e5d

When your application was running on 8080, was your URL also mapped to 8080?

yanyetang
FREEOP

a month ago

Nah, I implemented the code as specified in the railway document; the URL was mapped to process.env.PORT, and 3000 if no match. I think Railway injected its port 8080 and ignored my port setting in the code.


yanyetang
FREEOP

a month ago

Thanks for explaining the mechanism. I believe Railway's default port is 8080, which overrides my hard-coded 3000 when built and deployed, as shown by the console.log.
I'm confused because when I set "const port = process.env.PORT || 3000" as per Railway's docs, the app fails the health check. Why does this happen, considering this is the recommended approach by the Railway and is widely accepted?


darseen
HOBBYTop 5% Contributor

a month ago

Try to use Number(PORT) when you pass the port to the listen method (process.env variables resolve to a string). And bind your app to IPv6, as it's recommended by Railway here.

Example:

const PORT = process.env.PORT || 3000;
await app.listen(Number(PORT), "::");

darseen

Try to use Number(PORT) when you pass the port to the listen method (process.env variables resolve to a string). And bind your app to IPv6, as it's recommended by Railway here.Example:const PORT = process.env.PORT || 3000; await app.listen(Number(PORT), "::");

yanyetang
FREEOP

a month ago

I tested Number(PORT) and parseInt(PORT), but both still result in the 502 error. I analyzed the 502 logs with various LLMs (GPT, Claud, Germini), and they tried different solutions, but none worked. The only straightforward workaround is to hard-code a port number instead of assigning PORT from process.env.PORT, as recommended in the Railway documentation, which makes me feel confused.

Attachments


darseen
HOBBYTop 5% Contributor

a month ago

I think that you need to change your target port. Go to your Service Settings > Networking > Public Network, and change it to 8080.

Attachments


darseen

Try to use Number(PORT) when you pass the port to the listen method (process.env variables resolve to a string). And bind your app to IPv6, as it's recommended by Railway here.Example:const PORT = process.env.PORT || 3000; await app.listen(Number(PORT), "::");

(IIRC you need to listen on IPv4, not v6 for public networking to work)


0x5b62656e5d

(IIRC you need to listen on IPv4, not v6 for public networking to work)

darseen
HOBBYTop 5% Contributor

a month ago

True, I shouldn't have said "Bind your app to IPv6" which implies excluding IPv4. :: listens on all interfaces. Thanks for the observation.


darseen

I think that you need to change your target port. Go to your Service Settings > Networking > Public Network, and change it to 8080.

yanyetang
FREEOP

a month ago

Yo, nailed it. The target port was somehow set to 3000, so assigning process.env.PORT to 8080 will create a conflict.


darseen
HOBBYTop 5% Contributor

a month ago

If your target port in your public url is set to 3000, you should use port 3000 in your app, either via hard-coding it, or setting PORT env var to 3000. However, process.env.PORT is set to 8080 by Railway. When you use it, your app is listening on port 8080, but the public url is mapped to port 3000.
If you want to use process.env.PORT change your target port to 8080, or set PORT to 3000 in your variables. Else, keep it 3000 in your code.


darseen
HOBBYTop 5% Contributor

a month ago

So, in short, target port must equal PORT env var.


darseen

So, in short, target port must equal PORT env var.

yanyetang
FREEOP

a month ago

Exactly, I just don't remember when the target port was set to 3000, so process.env.PORT was causing me issues all the time. 

Attachments


Status changed to Open brody about 1 month ago


Status changed to Solved brody about 1 month ago


Loading...