I created a simple flask application that needs authentication to have access to the data.
When I run this application locally it works fine (accepts more than one client), however when I host the app on railway or heroku it can't handle more than one client.
Ex: when I access the URL on a computer and log in, if I access the URL on my cellphone (different netowrk) I get to have access to that account logged in.
I'm using the latest version of flask and using flask_login to manage authentication.
Does anyone have any idea why it's happening?
I've tried everything I found out on Internet, such as using
app.run(threaded=True)
I've also set the numbers of workers on gunicorn command for exemple
Does anyone have any idea why it's happening?
As official Flask's documentation says, never run your application in production in dev mode (what app.run() actually is).
Please refer to this section if you are going to deploy in self-hosted machine: https://flask.palletsprojects.com/en/2.2.x/deploying/
And if you are going to deploy to Heroku, you need to prepare for correct Procfile, like this:
web: gunicorn run:app
I've just solved it.
My gunicorn was in sync way and would handle only one request at a time.
So I had insert threads number on Procifle in order to it change worker_class from sync to Gthread
My Procfile afterall:
web: gunicorn --threads 4 :$PORT index:app
https://docs.gunicorn.org/en/stable/design.html#choosing-a-worker-type
Related
I have a very simple API (2 routes) which just has GET requests, and doesnt need any authentication or anything for now.
I want to know what is the best and appropariate way to deploy my API for production. I am unable to use docker, and would like to do it the server way.
So i have a few questions:
On the fastapi documentation it says you can do uvicorn main:app --host 0.0.0.0 --port 80 but i was thinking if that is the correct way for production? Do i just enter that command, and will the API automatically start listening on the servers IP address? Also is this method efficient and will it be able to handle all the requests? Or what would i change for it to be faster?
When should i use a process manager?
When should i use multiple workers? And what benefits do they provide?
When should i use Gunicorn as mentioned here? https://www.uvicorn.org/deployment/#gunicorn
I am just a little confused on how to deploy this because one article says do this, another says do this.
If for whatever reasons you don't like to use Docker-Ce, the best way is to create a systemd-service unit for your application so every time it goes down, systemd will try to restart it, then run it with servers like wgsi or gunicorn.
This link can help about systemd-services too:
https://blog.miguelgrinberg.com/post/running-a-flask-application-as-a-service-with-systemd
P.S note that the way you serve gunicorn isn't really related to docker or systemd-service, for both approaches you need to config gunicorn.
To answer your Question:
How can I deploy FastAPI manually on a Ubuntu Server?
You can check out this video tutorial on how to
Deploy FastAPI on Ubuntu
The deployment has the following architecture within a single Ubuntu VM.
As you take a look at the Architectural diagram above for FastAPI Deployment, it shows a single VM deployment.
Within the Ubuntu VM, there are two systemd services namely caddy.service and gunicorn.service up and running. The gunicorn.service runs the FastAPI application and the caddy.service exposes the FastAPI application running on Gunicorn as a reverse proxy with the help of uvicorn.workers.UvicornWorker worker class. In addition to this, our FastAPI communicates to PostgreSQL database server in an asynchronous fashion with the help of databases package that provides simple asyncio support for PostgreSQL database.
I have a Flask app (Plotly Dash) that fetches data from a DB which gets updated every day. Deployed on AWS, I run the app with gunicorn/nginx. Problem is, the data used in the app are from the latest gunicorn run, not the latest in the DB.
A solution I thought is adding an attribute to gunicorn command (eg. --reload) with a timer, to auto-restart gunicorn daily. Is this possible, or even, are there any other workarounds?
SOLUTION : https://community.plot.ly/t/how-to-refresh-data-on-fly/13069
You can signal gunicorn to reload with the SIGHUP signal. To try it out manually you can do that e.g. with killall -s 1 gunicorn, to reload everyday you probably want to use something like cron or some AWS specific service. It seems like AWS has some documentation on that.
Using killall is suboptimal, as it operates on the name of the process. It can break if the name changes (e.g. gunicorn renames itself to be identified with the application name) or if there are more than one gunicorn running. But as long as this is the only usecase for the server, it should be fine.
I'm trying to understand the behaviour of Pyramid regarding the [main:server] configuration and gunicorn.
If I use pserve, it'll use the configuration of [main:server], for both waitress and gunicorn. For example:
# development.ini
[server:main]
use = egg:waitress#main
listen = *:6543
So now, $ pserve development.ini will launch the project with waitress, which is expected. But if I use the command $ gunicorn (with gunicorn or waitress in the ini file) it'll work as well, which is not expected by me.
My questions are:
why does this configuration work if I run the command $ gunicorn --paste development.ini?
what happens under the hook? is waitress working? (I would say it's not according to the processes in my computer)
There are two independent pieces of configuration required to start serving requests for any WSGI app.
1) Which WSGI app to use.
2) Which WSGI server to use.
These pieces are handled separately and can be done in different ways depending on how you set it up. The ini file format is defined by the PasteDeploy library and provides a way for a consumer of the format to determine both the app config and the server config. However, when using gunicorn --paste foo.ini you're already telling gunicorn you want to use the gunicorn server (not waitress) so it ignores the server section and focuses only on loading the app. Gunicorn actually has other ways to load the app as well, but I'll ignore that complexity for now since that part is working for you. Any server config for gunicorn needs to be done separately... it is not reading the [server:main] section when you run gunicorn from the cli. Alternatively you can start your app using pserve which does use the server section to determine what server to use - but in your current setup that would run waitress instead of gunicorn.
So, after lots of reading and test, I have to conclude that:
using [main:server] is mandatory for a pyramid application
if you are running the application with gunicorn, you have to define this [main:server] nevertheless
gunicorn will ignore the use attribute, but pyramid will check the egg exists
gunicorn will use the rest of the settings (if any) but they will have less priority than the command line arguments or the config.py file
The reason behind this behaviour is still confusing to me, but at least I can work with it. Any other hints will be very appreciated.
I use Rchilli resume parser for parsing resume. It works fine while running on python manage.py runserver . I am getting an xml data as api response. But while running on gunicorn I'm getting an html response saying that "The service is temporarily unavailable". Is there something need to be changed on the configuration of gunicorn to get this fixed? As the project is still under development, I'm using only gunicorn for deploying the application. I am using this Method:Lessons Learned From The Dash: Easy Django Deployment for deploying the application without nginx.
I've recently started to experiment with Python and Tornado web server/framework for web development. Previously, I have used PHP with my own framework on a LAMP stack. With PHP, deploying updated code/new code is as easy as uploading it to the server because of the way mod_php and Apache interact.
When I add new code or update code in Python/Tornado, do I need to restart the Tornado server? I could see this being problematic if you have a number of active users.
(a) Do I have to restart the server, or is there another/better way?
(b) If so, how can I avoid users being disconnected/getting errors/etc. while it's restarting (which could take a few seconds)?
[One possible thought is to use the page flipping paradigm with Nginx pointing to a server, launch the new server instance with updated code, redirect Nginx there and take down the original server...?]
It appears the best method is to use Nginx with multiple Tornado instances as I alluded to in my original question and as Cole mentions. Nginx can reload its configuration file on the fly . So the process looks like this:
Update Python/Tornado web application code
Start a new instance of the application on a different port
Update the configuration file of Nginx to point to the new instance (testing the syntax of the configuration file first)
Reload the Nginx configuration file with a kill -HUP command
Stop the old instance of Python/Tornado web server
A couple useful resources on Nginx regarding hot-swapping the configuration file:
https://calomel.org/nginx.html (in "Explaining the directives in nginx.conf" section)
http://wiki.nginx.org/CommandLine (in "Loading a New Configuration Using Signals" section)
Use HAProxy or Nginx and proxy to multiple Tornado processes, which you can then restart one by one. The Tornado docs cover Nginx, but it doesn't support websockets, so if you're using them you'll need HAProxy.
You could use a debug=True switch with the tornado web instance.
T_APP = tornado.web.Application(<URL_MAP>, debug=True)
This reflects the handler changes as and when they happen.
Is this what you are searching for?
A module to automatically restart the server when a module is modified.
http://www.tornadoweb.org/en/branch2.4/autoreload.html
If you just want to deploy new code with tornado/python during development without restarting the server, you can use the realtimefunc decorator in this GitHub repository.