buildpacks/rfcs

Default value of $PORT

zmackie opened this issue · 13 comments

It's a common source of confusion that the containers we produce don't start, because they're waiting for a port to bind to. Should we have a way for there to be a default value of $PORT?

Basically , we always require folks to invoke their container with some version of -e PORT=3000. It would be nice if they would just turn on without this needing to be set, and for the default to be something sane.

My vote is for PORT=8080

Can you please provide some examples of this confusion?

i'm trying to get cnb for dotnet to build local docker container. so far what i'm getting doesn't run, i assume it binds to IPv6. is there a way to override listening interface, and what sets the launch command in for this buildpack - i'm unable to find it.

i actually just figured it out - it requires you set PORT env var


Me:

When we're booting the app in the httpd-cnb, where does $PORT come from?

wouldn't there be a default listening port if the app doesn't set it?

Rackup apps with the ruby buildpack assumes PORT be specified in runtime environment and it seems to not get set

I was able to get farther, I’m having trouble getting it to map to a specific port. (which I suspect is more an error in my usage)

(The above unattributed comments are from internal users on corp. slack)

Understood on the lack of attribution. Do you have a read on how many of those are side-effects of the buildpacks requiring $PORT (e.g. putting it into a command line or a .profile.d) versus the frameworks themselves expecting it?

My reason for this line of questioning is that there's a set of buildpacks for a specific language (😉) for which this hasn't come up and it was because we made an explicit effort to remove our dependency on $PORT. If this can be solved via updates to buildpacks rather than more specification, I'd prefer to go that route.

So the buildpacks have a default value for $PORT? That's a viable solution.

It seems like if there was a way for a platform to set this default, it would be a more wide-ranging solution to the "the container turns on without me having to set anything" problem. If I had 10 cents for every app I've seen in the wild that binds to $PORT I'd be sitting on a beach somewhere.

Not that buildpacks have a default, but rather the buildpacks don't depend on $PORT being defined. If there's no expectation of $PORT, there's no need for a default.

In the Java world, none of the frameworks depend on $PORT and typically simply default to 8080. When the frameworks default to something else, they still don't depend on $PORT. It does require a user to know based on their application, they may need to know -p 8080:8080 or -p 8888:8888, but at the very least there's no dependency on a set, valid $PORT.

I think what I'm trying to say is that for many applications and language families (I'm counting nodejs, dotnet, and ruby above), we're getting feedback that they're authored in such a way that there is an expectation that $PORT is set during runtime. Ideally this wouldn't be the case, but here we are. I think it would be a better experience for our users if we could provide that value.

The thing I'm suggesting is not really coming from opinion, it's that I've heard enough cases where apps don't start without $PORT being defined that I'm suggesting we define a mechanism for setting that default or a simple, sane, default.

@sclevine I recall you had some opinions here.

PORT has become a common enough standard that it is jarring for users when it's not set by default. Because Spring doesn't pick it up by default, many apps will have --server.port=$PORT in their java command, which creates a rocky experience with CNB.

Anecdotally, there has historically been pushback against frameworks understanding $PORT directly. I don't think this is as universal of a behavior as you'd expect.

I generally feel that the era of platforms pushing values into containers (e.g. picking the port that will be exported) is waning. We're much more seeing platforms that allow arbitrary configuration or transparent mapping for these ports. For example, there's no $PORT in the postgres image, there's a straight assumption that Postgresql will always be exposed on 5432 and you configure your execution of the container to expose that properly. I think we should be adopting the same pattern; stick with the default ports that frameworks choose, and use configuration to map those out to the world.

Closing to focus discussion on the PR