1

I have a web application which uses node.js and communicates with a Flask application to retrieve some configurations and send jobs to the back-end. The Flask returns a JSON with the information

Flask file (REST.PY):

from flask import Flask, jsonify, request, redirect, url_for
import subprocess

import os
import json
from cross_domain import *
app = Flask(__name__)

...

@app.route('/api/v1.0/proteins', methods=['GET', 'OPTIONS'])
@crossdomain(origin='*')
def get_protein_names():
proteins = os.walk(TARGET).next()[1]
protein_lst = [{"filename": protein} for protein in sorted(proteins) if  protein != "scripts"]
return jsonify({"files": protein_lst})

if __name__ == '__main__':
app.run(debug=True,port=9000)

and here is the js code:

...

this.restAddr = "http://127.0.0.1:9000";

...

this.httpGet = function(url, callback) {
var xmlHttp;
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
  if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
    callback(xmlHttp.responseText);
  }
};

...

httpGet(restAddr + "/api/v1.0/proteins", populateProteins);

I'm currently using this buildback in order to run both commands in the Procfile. It works when I run locally with foreman start, but when I deploy to Heroku the frameworks doesn't communicate with each other anymore and there is no response in the XMLHTTPRequests. I can still work with the node.js part, though.

Here is the Heroku logs:

...
2016-06-16T20:08:59.174025+00:00 app[web.1]: buildpack=runit ps=python at=start
2016-06-16T20:08:59.174156+00:00 app[web.1]: buildpack=runit ps=node at=start
2016-06-16T20:09:04.490687+00:00 app[web.1]:  * Running on http://127.0.0.1:9000/ (Press CTRL+C to quit)
2016-06-16T20:09:04.515389+00:00 app[web.1]:  * Restarting with stat
2016-06-16T20:09:05.138990+00:00 heroku[web.1]: State changed from starting to up
2016-06-16T20:09:05.568687+00:00 app[web.1]:  * Debugger is active!
2016-06-16T20:09:05.593316+00:00 app[web.1]:  * Debugger pin code: 237-920-039
2016-06-16T20:09:06.730693+00:00 app[web.1]: Succeeded connected to: <MONGODB_URI> in port 35556

Here is what appears when running Foreman:

 $ foreman start -f Procfile.local 
14:59:30 node.1   | started with pid 21241
14:59:30 python.1 | started with pid 21242
14:59:31 python.1 |  * Running on http://127.0.0.1:9000/ (Press CTRL+C to quit)
14:59:31 python.1 |  * Restarting with stat
14:59:31 python.1 |  * Debugger is active!
14:59:31 python.1 |  * Debugger pin code: 215-168-436
14:59:31 node.1   | Succeeded connected to: mongodb://localhost/algdock in port 3000

I need an insight about why is not working when it's deployed or if there is some another better approach to this problem.

EDIT: using gunicorn for python it gives the Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

Procfile.web

web: node gui/web_app/AlGDock/bin/www
web: gunicorn --pythonpath gui/api --bind 127.0.0.1:9000 wsgi:app

wsgi.py

from REST import app
if __name__ == "__main__":
    app.run()

Heroku Logs:

2016-06-17T00:35:25.808594+00:00 heroku[web.1]: Starting process with command `bin/runsvdir-dyno`
2016-06-17T00:35:26.398041+00:00 heroku[web.1]: Process exited with status 0
2016-06-17T00:35:28.003708+00:00 app[web.1]: buildpack=runit ps=web at=start
2016-06-17T00:35:28.376799+00:00 app[web.1]: [2016-06-17 00:35:28 +0000] [15] [INFO] Starting gunicorn 19.6.0
2016-06-17T00:35:28.377454+00:00 app[web.1]: [2016-06-17 00:35:28 +0000] [15] [INFO] Listening at: http://127.0.0.1:9000 (15)
2016-06-17T00:35:28.377583+00:00 app[web.1]: [2016-06-17 00:35:28 +0000] [15] [INFO] Using worker: sync
2016-06-17T00:35:28.385995+00:00 app[web.1]: [2016-06-17 00:35:28 +0000] [20] [INFO] Booting worker with pid: 20
2016-06-17T00:35:28.826322+00:00 app[web.1]: /app/target/
2016-06-17T00:35:28.826340+00:00 app[web.1]: /app/AlGDock/
2016-06-17T00:36:25.826633+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
acell22
  • 11
  • 3
  • Sanity check, you _are_ changing `restAddr` to the new server location aren't you? – slugonamission Jun 16 '16 at 20:24
  • @slugonamission Shouldn't the `http://127.0.0.1:9000` address works since they are in the same place? – acell22 Jun 16 '16 at 20:29
  • Are you hosting both files on the same (virtual) server? Otherwise you need to get the other server address and assign it to restAddr like restAddr=module.gettingPort()||127.0.0.1 for example. You could probably get the idea from a new Heroku app template. – sp3 Jun 17 '16 at 01:29
  • yes @sp3 I'm hosting them in the same server and using `localhost` as the `restAddr`. I tried [this](https://engineering.heroku.com/blogs/2014-10-29-heroku-django-node/) solution but using Flask instead of Django. Maybe I should try to change it and see if it works. – acell22 Jun 20 '16 at 20:30
  • Are you running Node in development environment or production environment ? Run node in development environment on heroku. – Mohammad Sayeed Jun 21 '16 at 07:02

1 Answers1

0

If you are running a web dyno then heroku needs to be able to connect to it within 60s or it assumes that it isn't working and shuts down the dyno. The port heroku uses isn't set so you need to grab the port from the dynos environment I had the same error when starting out as you have no control over what port heroku assigns.

The node + express version is app.set('port', (process.env.PORT));

This question shows the how to grab this value when using flask Deploying Flask app to Heroku

Edit: Also from heroku python docs

port = int(os.environ.get("PORT", 5000)) app.run(host='0.0.0.0', port=port)

Community
  • 1
  • 1
Matthew Salt
  • 125
  • 6