Flask Webserver on Amazon Linux 2 - This site can’t be reached on browser [duplicate] - flask

This question already has answers here:
Are a WSGI server and HTTP server required to serve a Flask app?
(3 answers)
Closed 17 days ago.
I have started a Flask Webserver on an Amazon Linux 2 EC2 instances
(venv) [ec2-user#ip-10-0-1-63 microblog]$ flask run
* Serving Flask app 'microblog.py'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
When i try to access the Web either via the below Public V4 DNS or Public V4 IP i get "Site cannot be reached"
http://34.228.161.61:5000
http://34.228.161.61:5000/index
https://ec2-34-228-161-61.compute-1.amazonaws.com:5000
https://ec2-34-228-161-61.compute-1.amazonaws.com:5000/index
I have successfully launched an Apache Web Server into the same EC2 & VPC instances and have no issues.
Also running curl from the same server i launched flask returns the contents
[ec2-user#ip-10-0-1-63 ~]$ curl http://localhost:7999
Hello, World![ec2-user#ip-10-0-1-63 ~]$
(tried a range of other ports also)
Any clues on what to do to get it working from my Chrome/Safari browser?
Tried so far
Ensured EC2 was talking to the web
Ensured VPC had route to the public internet
Ensured other webservers could be launched successfully from the same EC2 instance

Might be your application is not allowed for the outside world (0.0.0.0). Please check the running port in your system. You can use the below command to check:
sudo netstat -tulpn | grep LISTEN
check if 0.0.0.0: in your case, 0.0.0.0:5000 is showing in output or not.
Then try to run with below command:
flask run --host=0.0.0.0
Let me know, if that works. #Cloudkaramchari

Related

Error 99 connecting to localhost:6379. Cannot assign requested address

Setup:
I have a virtual machine and in the virtual machine running three containers (an nginx proxy, a very minimalistic flask app and redis). Flask should be serving on port 5000 while redis on 6379.
Each of these containers are up and running just fine as stand a lone services, but also available via docker compose as a service.
In the flask app, my aim is to connect to redis and query for some keys.
The nginx container exposes port 80, flask port 5000 and redis port 6379.
In the flask app I have a function that tries to create a redis client
db = redis.Redis(host='localhost', port=6379, decode_responses=True)
Running the flask app I am getting an error that the port cannot be used
redis.exceptions.ConnectionError: Error 99 connecting to localhost:6379. Cannot assign requested address.
I am lost of clarity what could be causing this problem and any ideas would be appreciated.
In the flask app I have a function that tries to create a redis client
db = redis.Redis(host='localhost', port=6379, decode_responses=True)
When your flask process runs in a container, localhost refers to the network interface of the container itself. It does not resolve to the network interface of your docker host.
So you need to replace localhost with the IP address of the container running redis.
In the context of a docker-compose.yml file, this is easy as docker-compose will make service names resolve to the correct container IP address:
version: "3"
services:
my_flask_service:
image: ...
my_redis_service:
image: ...
then in your flask app, use:
db = redis.Redis(host='my_redis_service', port=6379, decode_responses=True)
I had this same problem, except the service I wanted my container to access was remote and mapped via ssh tunnel to my Docker host. In other words, there was no docker-compose service for my code to find. I solved the problem by explicitly telling redis to look for my local host as a string:
pyredis.Redis(host='docker.for.mac.localhost', port=6379)
Anyone using only docker to run a container,
you can add --network=host in the command like docker run --network=host to make docker use the network of the host while running the container.
You can also use a host network for a swarm service, by passing --network host to the docker service create command.
Make sure you don't publish any port while doing this. like -p 80:8000
I am not sure if Docker compose supports this.
N.b. this is only supported in linux.

Strange behavior in a Flask app with Docker on AWS doing a POST

I have a Flask app running with docker and uwsgi on AWS. I have some endpoints and when I do a POST to one of them, using Postman or Curl, I see on the logs the response status code 412, but on Postman or Curl it shows 502.
I tried to run the Flask app locally without docker but using uwsgi, and it runs as expected.
I need to have a 412 response to know how to handle this status code.
If the flask app works as expected on your local machine, it might have something to do with how the port routing is setup for your container.
In addition to the port your flask application is receiving requests on, there is a Docker container that it lives inside that also has its own ports. The first is an external set of ports that need to be exposed to receive requests, and there's another set of internal ports that can be linked to external ports and used by your application.
The long explanation is available in this answer here, but the TLDR is:
Running your container with docker run -it --expose 8008 -p 8008:8008 myContainer
will allow for an externally exposed port with --expose EXTERNALPORT and will bind the internal container port to the external container port with -p INTERNALPORT:EXTERNALPORT.
Lastly, when running your flask service, you'll need to make sure that its port lines up with the internally exposed container port. An example using the same port we listed before would be:
flask run --host=0.0.0.0 --port=8008

Opening port 5000 for the internet is not working for google cloud compute engine instance

I have a google cloud compute engine instance with Ubuntu 16.04 on it. I have a flask app running on port 5000.
I've set up firewall rules to allow ingress traffic for any host (using 0.0.0.0/0 filter) for tcp:5000. I ran the
sudo ufw allow 5000
command on the console.
At this point I was expecting to see the flask app by entering http://external_ip:5000 on my browser. But that is not the case. I get "external_ip refused to connect." error on the browser. What am I doing wrong?
Its working if I run the flask app on port 80 though.
As the allow-internal rule is active in the firewall rules. I thought maybe try accessing from a node under the same project (thus same default network). But no luck.
I had the same problem. The way to fix is, to add host parameter to Flask app as shown below. By default Flask App is designed to work on localhost only. This has fixed the problem for me
if __name__ == '__main__':
app.run(debug=False, port=8081, host='0.0.0.0')

SSH tunnelling to a remote server with django

I'm trying to set up an SSH tunnel to access my server (currently an ubuntu 16.04 VM on Azure) to set up safe access to my django applications running on it.
I was able to imitate the production environment with Apache WSGI and it works pretty good but since I'm trying to develop the application I don't want to make it available to broader public right now - but to make it visible only for a bunch of people.
To the point: when I set up the ssh tunnel using putty on Windows 10 (8000 to localhost:8000) and I run http://localhost:8000/ I get the folowing error:
"Not Found HTTP Error 404. The requested resource is not found.".
How can I make it work? I run the server using manage.py runserver 0:8000.
I found somewhere that the error may be due to the fact that the application does not have access to ssh files, but I don't know whether that's the point here (or how to change it).
Regards,
Dominik
After hours of trying I was able to solve the problem.
First of all, I made sure putty connects to the server and creates the desired tunnel. To do that I right-clicked on the putty window (title bar) and clicked event log. I checked the log and found the following error:
Local port 8000 forwarding to localhost:8000 failed: Network error:
Permission denied
I was able to solve it by choosing other local port (9000 instead of 8000 in my instance).
Second of all, I edited the sshd_config file: sudo vi etc/ssh/sshd_config
and added these three lines:
AllowAgentForwarding yes
AllowTcpForwarding yes
GatewayPorts yes
I saved the file and restarted the ssh service:
sudo service ssh stop
sudo service ssh start
Now when I visit localhost:9000 everything works just fine.

Connecting to EC2 Django development Server

I am new to EC2 and web development. Currently I have a Linux EC2 instance running, and have installed Django. I am creating a test project before I start on my real project and tried running a Django test server.
This is my output in the shell:
python manage.py runserver ec2-###-##-##-##.compute-1.amazonaws.com:8000
Validating models...
0 errors found
Django version 1.3, using settings 'testsite.settings'
Development server is running at http://ec2-###-##-##-##.compute-1.amazonaws.com:8000/
Quit the server with CONTROL-C.
To test that it is wroking I have tried visiting: ec2-###-##-##-##.compute-1.amazonaws.com:8000 but I always get a "Cannot connect" message from my browser.
Whenever I do this lcoally on my computer however I do successfully get to the DJango development home page at 127.0.0.1:8000. Could someone help me figure out what I am doing wrong / might be missing when I am doing this on my EC2 instance as opposed to my own laptop?
Using an ec-2 instance with Ubuntu, I found that specifying 0.0.0.0:8000 worked:
$python manage.py runserver 0.0.0.0:8000
Of course 8000 does need to be opened for TCP in your security group settings.
You probably don't have port 8000 open on the firewall. Check which security group your instance is running (probably "default") and check the rules it is running. You will probably find that port 8000 is not listed.
1) You need to make sure port 8000 is added as a Custom TCP Rule into your Security Group list of inbound ports
2) Odds are that the IP that you see listed on your AWS Console, which is associated to your instance is a PUBLIC IP OR a PUBLIC Domain Name(i.e. ec2-###-##-##-##.compute-1.amazonaws.com or 174.101.122.132) that Amazon assigns.
2.1) If it is a public IP, then your instance has no way of knowing what the Public IP assigned to it is, rather it will only know the its assigned Local IP.
2.2) To get your Local IP on a Linux System, type:
$ ifconfig
Then look at the eth0 Data and you'll see an IP next to "inet addr" of the format xxx.xxx.xxx.xxx (e.g. 10.10.12.135) This is your Local IP
3) To successfully runserver you can do one of the following two:
$ python manage.py runserver <LOCAL IP>:8000
or
$ python manage.py runserver 0.0.0.0:8000
** Option Two also works great as Ernest Ezis mentioned in his answer.
EDIT : From The Django Book : "The IP address 0.0.0.0 tells the server to listen on any network interface"
** My theory of Public IP could be wrong, since I'm not sure how Amazon assigns IPs. I'd appreciate being corrected.
I was having the same problem. But I was running RHEL on EC2. Besides from adding a rule to security group, I had to manually add a port to firewalld.
firewall-cmd --permanent --add-port=8000/tcp
firewall-cmd --reload
That worked for me! (Although no idea why I had to do that)
Yes, if you use quick launch EC2 option, you should add new HTTP rule (just as it appears on the list) to run a development server.
Adding a security group with the inbound rules as follows usually does the trick unless you have something else misconfigured. The port range specifies which port you want to allow incoming traffic on.
HTTP access would need 80
HTTP access over port 8000 would need 8000
SSH to server would need 22
HTTPS would need 443