Node.js Express.js app port overwritten by Render?

Hey!

I have a nodejs app with express and dotenv package to make use of a local .env file with env vars. Locally on my machine everything works well, but on Render it doesn’t. I uploaded my .env in my web service’s Environment settings, but PORT variable from this file is not taken into account (I set it to 3000, as I know that ports 80 and 443 are restricted). Render overrides it with 10000.

Why? :slight_smile:

Therefore, my static app cannot receive valid responses (it’s trying to reach /api/xxxxx-like urls without a port specified).

PS. I have loved Render at first sight :heart_eyes: :wink:

EDIT:
Perhaps I need to always specify the host in the URL instead of just a context path? Or I can proxy requests somehow from app to app?

Cheers

Hey!

From my understanding of hosting services like this, your port environment will always be overridden. To work around this I’d pull the generated port number into my app.

In my app, I assigned an env variable called PORT my desired port. However, whenever I wanted to reference it I’d use process.env.PORT. What I’m trying get to is don’t hard code your port number.
For example, change the /api/xxxxx to /api/${process.env.PORT}, which would allow your app to use render’s provided port, hope this helped.

1 Like

Hey,

You can override the default port (10000), by setting a PORT environment variable. It would have to be an env var and not a .env file, as secret files are not parsed by the platform. Your secret file could be anything, so a .env isn’t special to Render, it’s just another secret file and as such, these files are not parsed into the environment. It would only be read when you add something to read it (e.g. the dotenv package when booting Node).

As David mentioned, it makes a lot of sense to just look for the PORT env var by default and fallback to another value if it’s not set, like our Express example shows:

const port = process.env.PORT || 3000;

And then use that in the listen

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

With that in place, you don’t need to worry about setting the port, it just uses the Render platform default. And locally, it’ll use your .env PORT value if you’ve set that up, or finally just fallback to 3000 if no PORT is set.

Alan

1 Like

Thanks guys. @al_ps could you please also answer my question regarding communication between both my services in terms of url/host/context path and port? Thanks

You haven’t fully described your set up, but I’ll assume you referring to a Static Site frontend trying to talk to a Web Service backend/API.

Static Sites don’t have a “backend”, so any requests are being made from the client side (browser). The client side would need to know the full URL of the endpoint, as it’s on a separate service, e.g. my-frontend-123.onrender.com is just a flat React app, so when it wants to make a request to my Node/Express API on my-backend-123.onrender.com/data it’ll need to know the full URL.

However, there is a way to make the API appear as a path within the Static Site, using Redirects and Rewrites. Continuing the example above, if I add a rewrite rule to the Static Site, with a source of /api/* and a destination of my-backend-123.onrender.com/*. Then calling my-frontend-123.onrender.com/api/data would actually be calling my-backend-123.onrender.com/data so the client-site could reference the call as just /api/data.

Don’t worry about ports for external/public use. They’re only used internally when the proxy is passing a request to your Web Service instance or if you making service-to-service calls on the private network. But that doesn’t sound like what you’re doing here.

Alan

1 Like

The destination URL should have https:// at the beginning. Works then. Thanks

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.