7

I am trying to teach myself Flask in a Vagrant environment. I understand that Flask runs a server on port 5000 by default. In my Vagrantfile I have:

config.vm.network :forwarded_port, guest: 80, host: 8080
config.vm.network :forwarded_port, guest: 5000, host: 5000

I have a simple tutorial Flask app:

from flask import Flask 
app = Flask(__name__)

@app.route('/hello')
def hello_world():
    return 'Hello world!'

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

Yet when I run python hello.py in my Vagrant environment and subsequently go to 127.0.0.1:5000/hello in Chrome on my desktop, I can't connect.

I don't know nearly enough about networking. What am I missing?

verbsintransit
  • 888
  • 3
  • 8
  • 18

6 Answers6

16

If you are accessing from Chrome in your desktop, you are technically accessing from a different computer (hence you need to place host='0.0.0.0' as argument to app.run() to tell the guest OS to accept connections from all public (external) IPs.

This is what worked for me (for both 127.0.0.1:5000/hello and localhost:5000/hello in Chrome):

from flask import Flask
app = Flask(__name__)

@app.route("/hello")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0')
fhdrsdg
  • 10,297
  • 2
  • 41
  • 62
Joben R. Ilagan
  • 1,900
  • 1
  • 15
  • 10
12

You possibly need to get Flask to serve on an externally-visible URL: see the docs

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thanks for your answer, but I replaced the debug argument with the host as suggested in that link to no avail. – verbsintransit Apr 22 '14 at 21:56
  • All the answers were helpful despite my limited understanding of them. I went back and tried this again (running `app.run(host='0.0.0.0')`) but this time I tacked on the port number (so `localhost:5000/hello`) and it worked. – verbsintransit Apr 23 '14 at 18:56
2

This may be caused by Vagrant (VirtualBox) NAT Port forwarding not working properly (port conflicts).

To narrow down the issue, you may want to make sure that port 5000 is open correctly on both end, this can be done by using nmap, nc (netcat) or netstat etc.

e.g. on host

nmap 127.0.0.1

nc -vz 127.0.0.1 5000

curl http://127.0.0.1:5000

Within the guest

nmap GUEST_IP

nc -vz GUEST_IP 5000

curl http://GUEST_IP:5000

NOTE: GUEST_IP is most likely in the 10.0.2.0/24 network (vbox NAT engine default).

Running these commands on both your host and within the VM (guest box) will tell you if the ports are open.

Make sure your python hello world binds NOT ONLY to the loopback device so that it can serve requests from external clients.

Use lsof -i :5000 or netstat -nap | grep :5000 to determine which program is binding the port for further troubleshooting.

Terry Wang
  • 13,840
  • 3
  • 50
  • 43
1

Do you have curl installed in your vagrant box? If not install it and try curl http://127.0.0.1:5000/hello. If you get a response and you see Hello world! in your console, then on flask side everything is fine. Back to the virtual box - When you open the network settings, from what you said above, I assume you are using a NAT address. In that case you will need to set the host address to 127.0.0.1, port 5000, leave the guest address empty and put port 5000 again and that should do the trick(port forwarding). One thing I've noticed about vagrant in those situations is that it works best if you use virtualhosts. Take a look here.

Alexander Ejbekov
  • 5,594
  • 1
  • 26
  • 26
  • Thanks for your answer. You are differentiating between "virtual" and "vagrant" boxes, and so I am assuming that the `curl` command must be run on my normal operating system (otherwise I don't understand how I can be running `python hello.py` at the same time). When I run your `curl` suggestion, I get a "connection refused" error. As far as your other suggestions go, I'm afraid you lost me at the 'leave the guest address empty and put port 5000 again'; I just don't know where I would actually put it. Any further advice is certainly appreciated. – verbsintransit Apr 22 '14 at 22:01
  • I'll be honest - I haven't used vagrant much. The way I had to use it was with a [base box](https://docs.vagrantup.com/v2/virtualbox/boxes.html) . That provides a lot more customization and ssh. That's what I assumed you were doing. What I meant was to do a `vagrant ssh`, and execute curl from there. And setting up the port forwarding is as easy as it could possibly get. – Alexander Ejbekov Apr 22 '14 at 22:17
1

I was using Vagrant and solved it by adding this line of code to Vagrantfile:

  config.vm.network "forwarded_port", guest: 5000, host: 5000, host_ip: "127.0.0.1"
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
Xoel
  • 318
  • 4
  • 15
0

make sure to 'vagrant reload' after you change your Vagrantfile

zachary
  • 108
  • 1
  • 9