obayral
obayral

Reputation: 141

Node.js upload error to Heroku, Web process failed to bind to $PORT within 60 seconds of launch

I am trying to upload a basic node.js server application to heroku. In localhost it works very well. However, when I upload it to the Heroku the application does not work somehow. Here is my code and my logs. Thank you very much.

var DEFAULT_PORT = process.env.PORT || 8080;
var DEFAULT_HOST = '127.0.0.1'
var SERVER_NAME = 'healthrecords'
var getRequestCounter = 0;
var postRequestCounter = 0;
var putRequestCounter = 0;
var deleteRequestCounter = 0;
var patientArray = [];

var http = require ('http');
var mongoose = require ("mongoose");

var port = process.env.PORT;
var ipaddress = process.env.IP; // TODO: figure out which IP to use for the heroku

// Here we find an appropriate database to connect to, defaulting to
// localhost if we don't find one.  
var uristring = 
  process.env.MONGODB_URI || 
  'mongodb://tekstil:[email protected]:51753/mapd713groupproject';
  //'mongodb://localhost/e-health-db';

// Makes connection asynchronously.  Mongoose will queue up database
// operations and release them when the connection is complete.
mongoose.connect(uristring, function (err, res) {
  if (err) { 
    console.log ('ERROR connecting to: ' + uristring + '. ' + err);
  } else {
    console.log ('Successfully connected to: ' + uristring);
  }
});

// This is the schema.  Note the types, validation and trim
// statements.  They enforce useful constraints on the data.
var patientSchema = new mongoose.Schema({
  first_name: String,
  last_name: String, 
  blood_gorup: String, 
  address: String, 
  date_of_birth: String, 
  date_admitted: String, 
  department: String, 
  doctor: String, 
  ailment:String, 
});

// Compiles the schema into a model, opening (or creating, if
// nonexistent) the 'Patients' collection in the MongoDB database
var Patient = mongoose.model('Patient', patientSchema);

var restify = require('restify')
  // Create the restify server
  , server = restify.createServer({ name: SERVER_NAME})

    if (typeof ipaddress === "undefined") {
        //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
        //  allows us to run/test the app locally.
        console.warn('No process.env.IP var, using default: ' + DEFAULT_HOST);
        ipaddress = DEFAULT_HOST;
    };

    if (typeof port === "undefined") {
        console.warn('No process.env.PORT var, using default port: ' + DEFAULT_PORT);
        port = DEFAULT_PORT;
    };


  server.listen(port, ipaddress, function () {
  console.log('Server %s listening at %s', server.name, server.url)
  console.log('Resources:')
  console.log(' /patients')
  console.log(' /patients/:id')
})


  server
    // Allow the use of POST
    .use(restify.plugins.fullResponse())

    // Maps req.body to req.params so there is no switching between them
    .use(restify.plugins.bodyParser())




   // Get all patients in the system
server.get('/patients', function (req, res, next) {
  getRequestCounter++;
  console.log('received GET request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Find every entity within the given collection
  Patient.find({}, function (error, patients) {

    // Return all of the patients in the system
    res.send(patients)
    console.log('Sending response to GET request.');
  })
})

// Get a single patient by its patient id
server.get('/patients/:id', function (req, res, next) {
  getRequestCounter++;
  console.log('received GET request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);
  // Find a single patient by their id within save
  Patient.findOne({ _id: req.params.id }, function (error, patient) {

    // If there are any errors, pass them to next in the correct format
    if (error) return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)))

    if (patients) {
      // Send the patient if no issues
      res.send(patient)
      console.log('Sending response to GET request.');
    } else {
      // Send 404 header if the patient doesn't exist
      res.send(404)
      console.log("Error occurred in sending Response.");
    }
  })
})

// Create a new patient
server.post('/patients', function (req, res, next) {
  postRequestCounter++;
  console.log('received POST request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Make sure first_name is defined
  if (req.params.first_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('first_name must be supplied'))
  }
  if (req.params.last_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('last_name must be supplied'))
  }
  if (req.params.blood_group === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('blood_group must be supplied'))
  }
  if (req.params.address === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('address must be supplied'))
  }
  if (req.params.date_of_birth === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_of_birth must be supplied'))
  }
  if (req.params.date_admitted === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_admitted must be supplied'))
  }
  if (req.params.department === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('department must be supplied'))
  }
  if (req.params.doctor === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('doctor must be supplied'))
  }
  if (req.params.ailment === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('ailment must be supplied'))
  }
  var newpatient = {
        first_name: req.params.first_name, 
    last_name: req.params.last_name,
    blood_gorup: req.params.blood_gorup,
    address: req.params.address,
    date_of_birth: req.params.date_of_birth,
    date_admitted: req.params.date_admitted,
    department: req.params.department,
    doctor: req.params.doctor,
    ailment:req.params.ailment
    }

  // Create the patient using the persistence engine
  Patient.create( newpatient, function (error, patient) {

    // If there are any errors, pass them to next in the correct format
    if (error) {
      console.log('Error on creating patient.');
      return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)));
    }

    // Send the patient if no issues
    res.send(201, patient)
    patientArray.push(patient);
    console.log('patient Array: ' + patientArray);

  })
  console.log('Sending response to POST request.');
})

// Update a patient by their id
server.put('/patients/:id', function (req, res, next) {
  putRequestCounter++;
  console.log('received PUT request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Make sure first_name is defined
  if (req.params.first_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('first_name must be supplied'))
  }
  if (req.params.last_name === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('last_name must be supplied'))
  }
  if (req.params.blood_group === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('blood_group must be supplied'))
  }
  if (req.params.address === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('address must be supplied'))
  }
  if (req.params.date_of_birth === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_of_birth must be supplied'))
  }
  if (req.params.date_admitted === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('date_admitted must be supplied'))
  }
  if (req.params.department === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('department must be supplied'))
  }
  if (req.params.doctor === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('doctor must be supplied'))
  }
  if (req.params.ailment === undefined ) {
    // If there are any errors, pass them to next in the correct format
    return next(new restify.InvalidArgumentError('ailment must be supplied'))
  }

  var newpatient = {
        first_name: req.params.first_name, 
    last_name: req.params.last_name,
    blood_group: req.params.blood_group,
    address: req.params.address,
    date_of_birth: req.params.date_of_birth,
    date_admitted: req.params.date_admitted,
    department: req.params.department,
    doctor: req.params.doctor,
    ailment:req.params.ailment
    }

  // Update the patient with the persistence engine
  Patient.update(newpatient, function (error, patient) {
    // If there are any errors, pass them to next in the correct format
    if (error) return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)))

    console.log('Sending response to PUT request.');
    // Send a 200 OK response
    res.send(200)
  })
})

// Delete patient with the given id
server.del('/patients/:id', function (req, res, next) {

  deleteRequestCounter++;
  console.log('received DELETE request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Delete the patient with the persistence engine
  Patient.delete(req.params.id, function (error, patient) {

    // If there are any errors, pass them to next in the correct format
    if (error) return next(new restify.InvalidArgumentError(JSON.stringify(error.errors)))

    // Send a 200 OK response
    res.send()
    console.log('Sending response to DELETE request.');
  })
})

// Delete all patients in the system
server.del('/patients', function (req, res) {

  deleteRequestCounter++;
  console.log('received DELETE request.');
  console.log("Processed Request Counter --> GET: " +  getRequestCounter + ", POST: " + postRequestCounter + ", PUT: " + putRequestCounter +", DELETE: " +deleteRequestCounter);

  // Find every entity within the given collection
  Patient.deleteMany({}, function (error) {

    // Return all of the patients in the system
    res.send()
    console.log('Sending response to DELETE request.');
  })
})

My PACKAGE.JSON

{
    "name": "patients",
    "version": "1.0.0",
    "description": "REST API - Patients",
     "dependencies": {
       "mongod": "^2.0.0",
     "mongodb": "^3.1.8",
     "mongoose": "^5.3.9",
     "restify": "4.1.1",
     "save": "2.3.0"
 },
 "author": "Oguz Bayral",
 "private": true,
 "main": "index.js",
 "scripts": {
     "start": "node index.js"
 }

}

Also I have a Procfile which is like below:

web: node index.js

And the Heroku log is like below:

2018-11-14T23:56:12.120061+00:00 heroku[web.1]: State changed from 
 crashed to starting
2018-11-14T23:56:12.000000+00:00 app[api]: Build succeeded
2018-11-14T23:56:14.581822+00:00 heroku[web.1]: Starting process with 
command `node index.js`
2018-11-14T23:56:18.630046+00:00 app[web.1]: No process.env.IP var, 
using default: 127.0.0.1
2018-11-14T23:56:18.658574+00:00 app[web.1]: (node:4) 
DeprecationWarning: current URL string parser is deprecated, and will 
be removed in a future version. To use the new parser, pass option { 
useNewUrlParser: true } to MongoClient.connect.
2018-11-14T23:56:18.678981+00:00 app[web.1]: Server healthrecords 
listening at http://127.0.0.1:35354
2018-11-14T23:56:18.679175+00:00 app[web.1]: Resources:
2018-11-14T23:56:18.679289+00:00 app[web.1]:  /patients
2018-11-14T23:56:18.679422+00:00 app[web.1]:  /patients/:id
2018-11-14T23:56:18.982348+00:00 app[web.1]: Successfully connected to: 
mongodb://tekstil:[email protected]:51753/mapd713groupproject
2018-11-14T23:57:15.011331+00:00 heroku[web.1]: Error R10 (Boot 
timeout) -> Web process failed to bind to $PORT within 60 seconds of 
launch
2018-11-14T23:57:15.011331+00:00 heroku[web.1]: Stopping process with 
SIGKILL
2018-11-14T23:57:15.126155+00:00 heroku[web.1]: Process exited with 
status 137
2018-11-14T23:57:15.160113+00:00 heroku[web.1]: State changed from 
starting to crashed
2018-11-14T23:57:17.940918+00:00 heroku[router]: at=error code=H10 
desc="App crashed" method=GET path="/" host=mapd713prjct.herokuapp.com 
request_id=bfd7440d-f39b-4823-947f-41fe01b740f2 fwd="199.212.27.182" 
dyno= connect= service= status=503 bytes= protocol=https
2018-11-14T23:57:19.963685+00:00 heroku[router]: at=error code=H10 
desc="App crashed" method=GET path="/favicon.ico" 
host=mapd713prjct.herokuapp.com request_id=67de28c3-268f-4a8f-9f2e- 
5c09142df654 fwd="199.212.27.182" dyno= connect= service= status=503 
bytes= protocol=https

Upvotes: 0

Views: 112

Answers (1)

dotconnor
dotconnor

Reputation: 1786

With you're current config, you're binding your server to localhost (127.0.0.1), Heroku doesn't say what IP to bind to, so you'll just have to bind to all of the available network interfaces, now Heroku should be able to detect your app.

// change
server.listen(port, ipaddress, function () {
  console.log('Server %s listening at %s', server.name, server.url)
  console.log('Resources:')
  console.log(' /patients')
  console.log(' /patients/:id')
})
//to
server.listen(port, function () {
  console.log('Server %s listening at %s', server.name, server.url)
  console.log('Resources:')
  console.log(' /patients')
  console.log(' /patients/:id')
})

Upvotes: 2

Related Questions