Heroku + node.js error (Web process failed to bind

2018-12-31 17:26发布

问题:

I have my first node.js app (runs fine locally) - but I am unable to deploy it via heroku (first time w/ heroku as well). The code is below. SO doesn\'t let me write so much code, so I would just say that the running the code locally as well within my network shows no issue.

 var http = require(\'http\');
 var fs = require(\'fs\');
 var path = require(\'path\');

 http.createServer(function (request, response) {

    console.log(\'request starting for \');
    console.log(request);

    var filePath = \'.\' + request.url;
    if (filePath == \'./\')
        filePath = \'./index.html\';

    console.log(filePath);
    var extname = path.extname(filePath);
    var contentType = \'text/html\';
    switch (extname) {
        case \'.js\':
            contentType = \'text/javascript\';
            break;
        case \'.css\':
            contentType = \'text/css\';
            break;
    }

    path.exists(filePath, function(exists) {

        if (exists) {
            fs.readFile(filePath, function(error, content) {
                if (error) {
                    response.writeHead(500);
                    response.end();
                }
                else {
                    response.writeHead(200, { \'Content-Type\': contentType });
                    response.end(content, \'utf-8\');
                }
            });
        }
        else {
            response.writeHead(404);
            response.end();
        }
    });

 }).listen(5000);

 console.log(\'Server running at http://127.0.0.1:5000/\');

Any idea ?

回答1:

Heroku dynamically assigns your app a port, so you can\'t set the port to a fixed number. Heroku adds the port to the env, so you can pull it from there. Switch your listen to this:

.listen(process.env.PORT || 5000)

That way it\'ll still listen to port 5000 when you test locally, but it will also work on Heroku.

You can check out the Heroku docs on Node.js here.



回答2:

I had same issue while using yeoman\'s angular-fullstack generated project and removing the IP parameter worked for me.

I replaced this code

server.listen(config.port, config.ip, function () {
  console.log(\'Express server listening on %d, in %s mode\', config.port, app.get(\'env\'));
});

with

server.listen(config.port, function () {
  console.log(\'Express server listening on %d, in %s mode\', config.port, app.get(\'env\'));
});


回答3:

The error happens when Heroku failed to bind the port or hostname at server.listen(port, [host], [backlog], [callback]).

What Heroku requires is .listen(process.env.PORT) or .listen(process.env.PORT, \'0.0.0.0\')

So more generically, to support other environments, use this:

var server_port = process.env.YOUR_PORT || process.env.PORT || 80;
var server_host = process.env.YOUR_HOST || \'0.0.0.0\';
server.listen(server_port, server_host, function() {
    console.log(\'Listening on port %d\', server_port);
});


回答4:

It\'s worth mentioning that if your code doesn\'t specify a port, then it shouldn\'t be a web process and probably should be a worker process instead.

So, change your Procfile to read (with your specific command filled in):

worker: YOUR_COMMAND

and then also run on CLI:

$ heroku scale worker=1



回答5:

For those that are passing both a port and a host, keep in mind that Heroku will not bind to localhost.

You must pass 0.0.0.0 for host.

Even if you\'re using the correct port. We had to make this adjustment:

# port (as described above) and host are both wrong
const host = \'localhost\';
const port = 3000;

# use alternate localhost and the port Heroku assigns to $PORT
const host = \'0.0.0.0\';
const port = process.env.PORT || 3000;

Then you can start the server, as usual:

app.listen(port, host, function() {
  console.log(\"Server started.......\");
});

You can see more details here: https://help.heroku.com/P1AVPANS/why-is-my-node-js-app-crashing-with-an-r10-error



回答6:

In my case, I was using example from https://hapijs.com/

To fix the problem I replaced

server.connection({ 
    host: \'localhost\', 
    port: 8000 
});

with

server.connection({
    port: process.env.PORT || 3000 
});


回答7:

I had the same problem and changing my listening port from 3000 to (process.env.PORT || 5000) solved the problem!!



回答8:

In my case, I was using Babel with the babel-plugin-transform-inline-environment-variables plugin. Apparently, Heroku does not set the PORT env variable when doing a deployment, so process.env.PORT will be replaced by undefined, and your code will fallback to the development port which Heroku does not know anything about.



回答9:

The below steps resolved my solution:

Editing package.json as:

...
\"engines\": {
\"node\": \"5.0.0\",
\"npm\": \"4.6.1\"
},
...

and Server.js as:

...
var port = process.env.PORT || 3000;
app.listen(port, \"0.0.0.0\", function() {
console.log(\"Listening on Port 3000\");
});
...


回答10:

At of all the solution i have tried no one work as expected, i study heroku by default the .env File should maintain the convention PORT, the process.env.PORT, heroku by default will look for the Keyword PORT.

Cancel any renaming such as APP_PORT= instead use PORT= in your env file.



回答11:

I had same issue I could resolved issue with replace \'localhost\' with IP which is \'0.0.0.0\'



回答12:

A fixed number can\'t be set for port, heroku assigns it dynamically using process.env.PORT. But you can add them both, like this process.env.PORT || 5000. Heroku will use the first one, and your localhost will use the second one.

You can even add your call back function. Look at the code below

app.listen(process.env.PORT || 5000, function() {
    console.log(\"Server started.......\");
});


回答13:

From the heroku bash process, pass down the value of $PORT to your node app using an options parser like yargs.

Here is an example of how you might do that. On the scripts object, inside package.json, add a start method \"node server --port $PORT\".

In your server file, use yargs to get the value from the port option (--port $PORT) of the start method:

const argv = require(\'yargs\').argv;
const app = require(\'express\')();

const port = argv.port || 8081;

app.listen(argv.port, ()=>{
    console.log(\'Probably listening to heroku $PORT now \', argv.port); // unless $PORT is undefined, in which case you\'re listening to 8081.
});

Now when your app starts, it will bind to the dynamically set value of $PORT.



回答14:

If, like me, you\'re configuring Heroku to run a script from your package.json file on deploy, make sure you haven\'t hard-coded the value of PORT in that script! If you do, you\'ll end up like me and spend an hour trying to figure out why you\'re getting this error.



回答15:

I had same issue but with express and apollo-server. The solution from here:

The only special consideration that needs to be made is to allow heroku to choose the port that the server is deployed to. Otherwise, there may be errors, such as a request timeout.

To configure apollo-server to use a port defined by Heroku at runtime, the listen function in your setup file can be called with a port defined by the PORT environment variable:

> server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => { 
> console.log(`Server ready at ${url}`); });


回答16:

I had the same issue because I didn\'t define Procfile. Commit a text file to your app’s root directory that is named Procfile without a file extension. This file tells Heroku which command(s) to run to start your app.
web: node app.js