8

I'm trying to run a flask app on a remote server, so I can access it from other computers. The server has a public IP and I configured the flask to run on that IP. But when I run the script I get the following traceback

Note: I've removed the public IP from the traceback and my code.

 * Running on **public ip** 
Traceback (most recent call last):
  File "testServer.py", line 14, in <module>
    app.run(host='62.60.19.189',port=5000)
  File "/usr/lib/python2.6/site-packages/flask/app.py", line 772, in run
    run_simple(host, port, self, **options)
  File "/usr/lib/python2.6/site-packages/werkzeug/serving.py", line 710, in run_simple
    inner()
  File "/usr/lib/python2.6/site-packages/werkzeug/serving.py", line 692, in inner
    passthrough_errors, ssl_context).serve_forever()
  File "/usr/lib/python2.6/site-packages/werkzeug/serving.py", line 486, in make_server
    passthrough_errors, ssl_context)
  File "/usr/lib/python2.6/site-packages/werkzeug/serving.py", line 410, in __init__
    HTTPServer.__init__(self, (host, int(port)), handler)
  File "/usr/lib64/python2.6/SocketServer.py", line 402, in __init__
    self.server_bind()
  File "/usr/lib64/python2.6/BaseHTTPServer.py", line 108, in server_bind
    SocketServer.TCPServer.server_bind(self)
  File "/usr/lib64/python2.6/SocketServer.py", line 413, in server_bind
    self.socket.bind(self.server_address)
  File "<string>", line 1, in bind
socket.error: [Errno 99] Cannot assign requested address

Here is my code

import flask

app = flask.Flask("My app")

@app.route('/myroute', methods=['POST'])
def foobar():
        print flask.request.form
        return '<br>'.join('{0}: {1}'.format(*pair) for pair in flask.request.form.items())




if __name__ == '__main__':
    app.run(host='public IP',port=5000)
cyberbemon
  • 3,000
  • 11
  • 37
  • 62
  • 1
    Is that server *directly* configured to run on that IP address, or are you running behind a router and *it* has the IP address (e.g. your server has a private IP address and the router uses NAT - network address translation)? – Martijn Pieters Oct 09 '14 at 14:22
  • This is *not* a problem unique to Flask, by the way. – Martijn Pieters Oct 09 '14 at 14:22
  • No, I connect to the server using a different IP after I'm connected to a VPN, I'm running the python code in the remote server and was given a public IP to run flask on it. – cyberbemon Oct 09 '14 at 14:25

2 Answers2

12

You can only directly bind to an IP address that the server has been configured for; behind a router running Network Address Translation (NAT) your internal IP address will be different.

Either bind directly to that internal IP address, or use '0.0.0.0' to listen on all interfaces. You may still need to configure the router to forward a specific port to your internal server.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Tried using `0.0.0.0` but that seems to return `Address already in use` error – cyberbemon Oct 09 '14 at 15:59
  • 1
    @cyberbemon: which would mean there is already something bound to that port. See [Finding the process that is using a certain port in Linux](http://superuser.com/q/42843) to figure out what is bound to the port. – Martijn Pieters Oct 09 '14 at 16:05
  • Thanks, I managed to get it running on '0.0.0.0' – cyberbemon Oct 09 '14 at 16:34
  • @Cleb: So `192.x.y.z` is not a valid IP address **on your computer**. Something else maps that IP address to your computer, *or* you got your IP address wrong somehow. – Martijn Pieters Apr 01 '18 at 18:21
  • @Cleb: No, that doesn't mean it is correct. Network address translation (NAT) on a router can rewrite your IP addresses. You need to look at your computer configuration directly. It depends on your OS how you do that. – Martijn Pieters Apr 01 '18 at 18:38
2

The IP you want to bind a socket to must be directly available on an interface of the machine. This seems not be the case here.

  • If you're behind a NAT: use port-forwarding
  • If you're using a VPN and the VPN adapter of the server is not always up, try using "0.0.0.0" as an address. Beware: It will listen on all interfaces available. Create firewall rules to block access via interfaces you don't want to listen to when using this.
dom0
  • 7,356
  • 3
  • 28
  • 50