I'm running Ubuntu using Virtual Box Manager from windows machine. Inside the VM box ubuntu i'm running a python flask application which is running at http://localhost:5000.
I tried to access the VM box localhost URL on windows machine using the VM box IP which I got using ifconfig. But it's says :
Your Internet access is blocked
Am i accessing it the right way ?
here is my python flask code :
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
You need to specify a host='0.0.0.0' while starting your app. By default it will only accept requests from localhost. So if you are sending a request from some other IP then you must have to specify a host.
See below example.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0')
Also if you want to activate the debugging mode to analyse the exceptions/errors while you access your application. You can also set debug attribute to 'True'.
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
Below code will allow you to access Flask web from any public IP instead of 127.0.0.1
if __name__ == '__main__':
app.run(host='0.0.0.0', debug='TRUE')
By default Flask runs on port: 5000. Sometime on VM this port will be blocked. To allow traffic on this port execute below command.
iptables -I INPUT -p tcp --dport 5000 -j ACCEPT
Related
I want to change the host and port that my app runs on. I set host and port in app.run, but the flask run command still runs on the default 127.0.0.1:8000. How can I change the host and port that the flask command uses?
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
set FLASK_APP=onlinegame
set FLASK_DEBUG=true
python -m flask run
The flask command is separate from the flask.run method. It doesn't see the app or its configuration. To change the host and port, pass them as options to the command.
flask run -h localhost -p 3000
Pass --help for the full list of options.
Setting the SERVER_NAME config will not affect the command either, as the command can't see the app's config.
Never expose the dev server to the outside (such as binding to 0.0.0.0). Use a production WSGI server such as uWSGI or Gunicorn.
gunicorn -w 2 -b 0.0.0.0:3000 myapp:app
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(host="localhost", port=8000, debug=True)
Configure host and port like this in the script and run it with
python app.py
You can also use the environment variable FLASK_RUN_PORT, for instance:
export FLASK_RUN_PORT=8000
flask run
* Running on http://127.0.0.1:8000/
Source: The Flask docs.
When you run the application server using the flask run command, the __name__ of the module is not "__main__". So the if block in your code is not executed -- hence the server is not getting bound to 0.0.0.0, as you expect.
For using this command, you can bind a custom host using the --host flag.
flask run --host=0.0.0.0
Source
You can use this 2 environmental variables:
set FLASK_RUN_HOST=0.0.0.0
set FLASK_RUN_PORT=3000
You also can use it:
if __name__ == "__main__":
app.run(host='127.0.0.1', port=5002)
and then in the terminal run this
set FLASK_ENV=development
python app.py
After reading following docs and examples about deploying python app to evennode I've tried to do it with Flask application, but didn't succeed
https://www.evennode.com/docs/git-deployment
https://github.com/evennode/python-getting-started
Here is my main.py module's code:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello, World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000)
Also I'have created conf.py file with configuration for gunicorn:
workers = 4
bind = "0.0.0.0:8000"
Then I'm running the application with gunicorn --config=conf.py main:app and all works well on my local machine. To run it on evennode I populated requirements.txt and committed above files. Then run following commands:
git remote add evennode git#git.evennode.com:your_app_here
git push evennode master
The output looks next way and I don't know what to do with it:
ssh: connect to host git.evennode.com port 8000: No route to host
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
I have added my public ssh key to evennode app settings as well, so that's can't be an issue
Any help is appreciated
I am able to run a webserver using the following code
from flask import Flask
from waitress import serve
app = Flask(__name__, static_url_path='/static')
...
serve(app, port=8080)
The problem is that I can access it only from the machine where it is running, if I try to access it using the ipv4 ip, it doesn't work. Am I missing a step?
Simple example,try it!
I hope it will help you.
app1.py
from flask import Flask
app = Flask(__name__)
# app.run(host='0.0.0.0', port=8080,debug=True)
waitress_server.py
from waitress import serve
import app1
serve(app1.app, host='0.0.0.0', port=8080)
Then run below command
python waitress_server.py
Waitress now provides a simple command line Utility called waitress-serve for running the Flask Application. Please note that this answer is valid for Waitress 1.30. The command line arguments could change in future.
If your Flask application is called myapplication and the method which instantiates your application is called create_app, then you can run the command below. This will launch the server listening on port 8080 by default.
waitress-serve --call "myapplication:create_app"
If you wish to launch it on port 80 (http), then all you need to do is:
waitress-serve --port=80 --call "myapplication:create_app"
D:\flaskapps>waitress-serve --port 80 --call "dlrlsummarizer:create_app"
Serving on http://ADITHYA-PC:80
Waitress serve command line arguments.
Flask 1.0 production deployment tutorial.
Try using
serve(app, host='0.0.0.0', port=8080)
I ran into this question and looking something similar.
After looking at the documentation and combined with your original request, I tested
serve(app, port=8080, host="x.x.x.x")
Where x.x.x.x is my host ip address.
It works fine on my end.
Complete code
from flask import Flask
from waitress import serve
app = Flask(__name__)
...
serve(app, port=8080, host="x.x.x.x")
I realize this question was probably based in a miss-diagnosed firewall or NAT issue, but in case people come here actually wanting to serve a Flask app with waitress on windows properly (as a service), I want to point to my answer here, so that it can be of use and receive some feedback.
from flask import Flask
from waitress import serve
app = Flask(__name__)
#app.route("/")
def hello_world():
return "<p>Hello stay healthy.</p>"
if __name__ == "__main__":
serve(app, host="127.0.0.1", port=8080)
Problem may persist in host. You can use host="127.0.0.1" in your program.
Save your program in app.py file.
Run your program.
The server will be accessible at http://localhost:8080
I just realized that can be reached by computers in the same network, but not from computers outside of the network
You need to forward the port in your router and use your public IP address.
To be able to use your internal PC (behind the router) you need to forward in the router the externl port 8080 to internal port 8080 and IP address of your server.
In this conditions you can access your server from outside your network using your external IP. That is OK if you have a static IP address allocated by your provider. If not than you can use a free DNS provider (I use DnsExit) which will provide you with a name for your external IP address. This way you can access your server with a name even if the IP address from your service provider changes from time to time.
I work on a linux cluster that is behind a firewall. It does not have web access.
I had this idea I could try to run flask and direct it to a port I know is open (5901 for vnc), and then tunnel that port and view it in my browser.
It's not working so far. Is this possible at all?
Here is what I'm doing:
helloflask.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5901)
#app.run()
I run python helloflask.py then
ssh -L 5901:<inner server>:5901 <outer server>
Then I navigate to localhost:5901. Nothing. I also tried links localhost:5901 and links <server>:5901, but again nothing.
Is it possible there is some way to do this?
You can do this :
Run your flask app or notebook on the remote server on any port. Say for example port 5000.
On your local machine run below command to establish the ssh tunnelling :
ssh -D 8123 -f -C -q -N username#remotesrrver
The port 8123 is arbitrary here it can be any allowed port on your local machine. Then setup one of your browser (Fire fox may be) to use socks proxy on port 8123
Make sure that the traffic is proxied for localhost also. By default Firefox disable proxying for localhost. Once these are established you should be able to go to http://localhost:5000 on your browser to hit the app /notebook running on the remote machine
And your hellowflask.py should be like something below for it to work
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5901)
#app.run()
Might I suggest trying something like pyngrok to programmatically manage an ngrok tunnel for you? Full disclosure, I am the developer of it. Flask example here, but it's as easy as installing pyngrok:
pip install pyngrok
and using it:
from pyngrok import ngrok
# <NgrokTunnel: "http://<public_sub>.ngrok.io" -> "http://localhost:5000">
http_url = ngrok.connect(5000)
My use case:
We need to run a watir-webdriver script in headless mode and our dev machines run Windows.
The gist of our problem:
I can stand up the python server inside the container, but I can't connect to it at its expected location from the host: http://192.168.59.103:8084.
The architecture:
A ruby script that "does something useful and prints the output to the console" and a basic python server that imports os and then executes os.system('ruby ourrubyscript.rb') inside our index route. We also brought in flask for api routing and flask.cors to eliminate potential cross origin issues.
Local test (on Host):
running "python server.py" in our host workspace stands up a python server on port 5000. Routing to it from a browser executes our route and prints the expected output to the console.
server.py
from flask import Flask
from flask import request
from flask.ext.cors import CORS
import os
app = Flask(__name__)
CORS(app, resources={r'/': {"origins": "*"}}, headers='Content-Type')
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/')
def index():
return "<h1>Hello Stupid</h1>"
#app.route('/ruby/test', methods=['GET'])
def runRubyScript():
return os.system("ruby script.rb")
if __name__ == "__main__":
app.run()
When I nav to localhost:5000, "Hello Stupid" prints to my screen.
When I route to localhost:5000/ruby/test, our script runs and that script prints to my console.
Procedure to move this to docker
We pulled latest centos and installed wget, xvfb, git, ruby, python, pip, flask, flask-cors, and firefox; committed that to a local image named "webdev."
Then gem installed headless and installed phantomjs to $PATH
We then cloned our src repository to "/opt/testapp" in the container. This repository contains our "server.py" file and a "script.rb" file.
docker#boot2docker:~$ docker run -d -p 5000:5000 --name wd webdev python /opt/testapp/server.py
So, I left my boot2docker-vm bound to private ip 192.168.59.103, and I can confirm that this ip is valid by navigating to a different port that is running a different container; however, when I navigate to 5000, I get an ERR_CONNECTION_REFUSED. I had an almost "AHA!!" moment thinking that iptables had the port locked down by default and we needed to go open internal port 5000 in order to map it out to the vm but then I found that the centos image does not have iptables (or firewalld since this is CentOS7) installed by default. When that approach turned out to be incorrect, I decided to post to see if anyone might be able to assist here because I am out of ideas.
So I have figured out why this is not exposed to the host environment and this makes perfect sense.
In NAT mode, the virtual machine gets assigned a private static ip address: 192.168.59.103 (that is...the virtual machine gets assigned that IP)
Each container stands up with 2 adapters: a loopback and an externally facing virtual private bridge accessible to the vm.
When I stand up my server on port 5000, it binds directly to loopback inside the container and is inaccessible to the virtual machine.
Removing the localhost binding from the service and allowing it to
bind to the default gateway 0.0.0.0:5000
causes the service to listen on all adapters and allows communications
between the vm and the container's external adapter through the
virtual private bridge that gets created when the container stands.
For some reason, switching my virtual machine to run in Bridged mode against my NIC is causing the boot2docker-vm to crash on start....so I'm relegated to NAT for the time being until I can figure out how to switch it properly.
[Edit 1 (related to bridging)]
Bridge mode seems to currently be unsupported in boot2docker as of at least October 8, 2014. b2d expects a NAT adapter for ssh bootstrapping and the host adapter for container<->container socket access.
The current, unsupported, undocumented workaround to expose a container to hosts on a network is to add a third network interface to VirtualBox and bridge with it.
[Edit 2 (example server running against default gateway)]
Here is an example of a flask server that attaches to all interfaces:
Note that the only Δ between the server above and the server below is the final line of the configuration.
app.run()
needs to become
app.run(host='0.0.0.0')
from flask import Flask
from flask import request
from flask.ext.cors import CORS
import os
app = Flask(__name__)
CORS(app, resources={r'/': {"origins": "*"}}, headers='Content-Type')
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/')
def index():
return "<h1>Hello Stupid</h1>"
#app.route('/ruby/test', methods=['GET'])
def runRubyScript():
return os.system("ruby script.rb")
if __name__ == "__main__":
app.run(host='0.0.0.0')