Flask app stops after a few hours in windows [duplicate] - flask

Setting up Flask with uWSGI and Nginx can be difficult. I tried following this DigitalOcean tutorial and still had trouble. Even with buildout scripts it takes time, and I need to write instructions to follow next time.
If I don't expect a lot of traffic, or the app is private, does it make sense to run it without uWSGI? Flask can listen to a port. Can Nginx just forward requests?
Does it make sense to not use Nginx either, just running bare Flask app on a port?

When you "run Flask" you are actually running Werkzeug's development WSGI server, and passing your Flask app as the WSGI callable.
The development server is not intended for use in production. It is not designed to be particularly efficient, stable, or secure. It does not support all the possible features of a HTTP server.
Replace the Werkzeug dev server with a production-ready WSGI server such as Gunicorn or uWSGI when moving to production, no matter where the app will be available.
The answer is similar for "should I use a web server". WSGI servers happen to have HTTP servers but they will not be as good as a dedicated production HTTP server (Nginx, Apache, etc.).
Flask documents how to deploy in various ways. Many hosting providers also have documentation about deploying Python or Flask.

First create the app:
import flask
app = flask.Flask(__name__)
Then set up the routes, and then when you want to start the app:
import gevent.pywsgi
app_server = gevent.pywsgi.WSGIServer((host, port), app)
app_server.serve_forever()
Call this script to run the application rather than having to tell gunicorn or uWSGI to run it.
I wanted the utility of Flask to build a web application, but had trouble composing it with other elements. I eventually found that gevent.pywsgi.WSGIServer was what I needed. After the call to app_server.serve_forever(), call app_server.stop() when to exit the application.
In my deployment, my application is listening on localhost:port using Flask and gevent, and then I have Nginx reverse-proxying HTTPS requests to it.

You definitely need something like a production WSGI server such as Gunicorn, because the development server of Flask is meant for ease of development without much configuration for fine-tuning and optimization.
Eg. Gunicorn has a variety of configurations depending on the use case you are trying to solve. But the development flask server does not have these capabilities. In addition, these development servers show their limitations as soon as you try to scale and handle more requests.
With respect to needing a reverse proxy server such as Nginx is concerned it depends on your use case.
If you are deploying your application behind the latest load balancer in AWS such as an application load balancer(NOT classic load balancer), that itself will suffice for most use cases. No need to take effort into setting up NGINX if you have that option.
The purpose of a reverse proxy is to handle slow clients, meaning clients which take time to send the request. These reverse load balancers buffer the requests till the entire request is got from the clients and send them async to Gunicorn. This improves the performance of your application considerably.

Related

Do I need to use Apache in my AWS EC2 instance for my flask App?

I'm so confused as to what benefits I will be getting from using Apache to serve my Flask App in my EC2 instance if it's already out there to the public, & whether I have to think about using something like Apache or Nginx from the first place?
Why not just configure a production server like gunicorn (as I heard it's better to be used for security purposes even though this answer kinda made me doubt this a bit) and get a private domain and that's it for my flask app?
This question boils down to "application server vs web server". In your case gunicorn is an app server, and nginx/apache is a web server.
What is the difference between application server and web server?
To give some brief advice, you need to consider the scale and actual functionality of your app. If you expect to serve any consistent number of users, use web server, they are better optimized to serve concurrent requests. If your app serves some static files - also use web server, they do it more efficiently. If it's an internal app which only you and couple of guys use occasionally, you can get by only running a gunicorn.

React with Django in production

I am planning to deploy an application which is built in react frontend, and calls a python backend. What I am planning is to deploy react on a linux box on a node.js server and python on django behind Apache.
Can someone would suggest if this would be right architecture from production grade perspective?
If application is expected to get 1000 requests per hour, then will this architecture work? or I should replace or add components or layers?
Generally, you run both servers on different ports, and then point apache to django server for /api/ calls (or whatever URLs need to go to django api), and then the rest of the regular requests you point at node.js serving your javascript frontend application.
1000 requests per hour seems like nothing - depending of course on the work of the backend server - but in general any webserver should handle that no problem.
Apache has following settings for this:
ProxyPass "/api" "http://127.0.0.1:8000/api"
ProxyPassReverse "/api" "http://127.0.0.1:8000/api"
You can read more in documentation here: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html

Running Flask web application in Google Kubernetes Engine

There are a vast majority of tutorials and documentation on the web where Flask is running in development state. The log looks like this in development mode:
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5555/ (Press CTRL+C to quit)
I want to know more about how to make it production ready. I've seen documentation on this as well using production ready WSGI servers and nginx as reverse proxy in front. But can somebody tell me why WSGI and reverse proxy is needed?
If my Flask application is dockerized and running in Google Kubernetes Engine is it even necessary then? Will GKE not take care of the purpose of WSGI and reverse proxy?
As Flask's documentation states:
Flaskā€™s built-in server is not suitable for production
Why WSGI? It's a standard way to deploy Python web apps, it gives you options when choosing a server (i.e. you can choose the best fit for your application/workflow without changing your application), and it allows offloading scaling concerns to the server.
Why a reverse proxy? It depends on the server. Here is Gunicorn's rationale:
... we strongly advise that you use Nginx. If you choose another proxy server you need to make sure that it buffers slow clients when you use default Gunicorn workers. Without this buffering Gunicorn will be easily susceptible to denial-of-service attacks.
Here is Waitress's rationale for the same:
Often people will set up "pure Python" web servers behind reverse proxies, especially if they need TLS support (Waitress does not natively support TLS). Even if you don't need TLS support, it's not uncommon to see Waitress and other pure-Python web servers set up to only handle requests behind a reverse proxy; these proxies often have lots of useful deployment knobs.
Other practical reasons for a reverse proxy may include needing a reverse proxy for multiple backends (some of which may not be Python web apps), caching responses, and serving static content (something which Nginx, for example, happens to be good at). Not all WSGI servers need a reverse proxy: uWSGI and CherryPy treat it as optional.
P.S. Google App Engine seems to be WSGI-compliant and doesn't require any additional configuration.

How can I run multiple apps which that accept requests in Heroku?

Is it possible to configure Heroku where one has two processes that accept HTTP requests?
I would like to run one traditional request/response process (perhaps a Django Gunicorn process), and also run a NodeJS service that provides web-sockets. It would be nice if I could configure Heroku to work to a routing pattern like this:
ws/ # NodeJS websocket process
* # Django Process
Where any request with a URL begining with ws/ gets routed to the NodeJS websocket process, and everything else gets routed to Django.
Heroku gives an example of something similar.
https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio
But I really do not like this approach and will only consider it as a last resort. The issue is that the NodeJS process and the Rails process, are in separate Heroku apps. This will cause hassle when it comes to billing versioning and staging.

Test a webservice on a different port locally without JSONP

I'm currently writing a webservice (with node.js) for an AngularJS frontend which is hosted with node.js
It will later be available through a proxy under domain.com/api and therefore I don't need JSONP.
For local testing purposes i have my AngularJS app running on localhost:80 and my node.js backend on localhost:3000. Naturally I'm not able to query json requests. The easies
What would be the best setup to test my homepage locally without screwing to much in my setup?
I'm currently working on windows. Linux is also an option if it is easier.
Would it be possible to write a simple proxy for express that hosts both apps in the same domain?
You can use the hosts file to set the domain.com/api to localhost. This is done in /etc/hosts in Linux, but its present somewhere in Windows too. Another thing that helps me a lot is ssh tunneling. You can, for example, tunnel remote ports (where your backend is running) to localhost with ssh -L localPort:your.server:remotePort
It's not exactly what you asked for, but the easiest might be to have the node.js app serve the AngularJS app, too. It's quite efficient, certainly efficient enough to use for development.
If it's an expressjs app, you can just add
app.use(express['static'](__dirname + "/public"));
before your other routes to have it look for static files in ./public/
If your app is served by a template or build system that you can't easily reproduce in node.js, then another option would be to run nginx, apache or haproxy on some port (80 or 5000 or ...) and have that proxy to the current backend server for the app and port 3000 (the node.js app) for the API/data requests.
You might even be able to have your server currently running on port 80 do this.
As a final idea you could also setup the node.js app to proxy to port 80 for the "app files".
Edit - I just realized that both of your apps are written in node.js. Would it be possible to set it up so you run them separately in production but together in development? Put all the real functionality in modules and then have three separate "loaders" that start the apps, one together and then a loader for each individually.