Starting flask server in background

50,268

Solution 1

My favorite way of doing it in production is to combine flask with uwsgi and nginx to keep persistence. Here are nice setup instructions to get you started: http://www.markjberger.com/flask-with-virtualenv-uwsgi-nginx/

Jist:

First make sure that your vps has the latest updates:

sudo apt-get update
sudo apt-get upgrade

Now install python and virtualenv:

sudo apt-get install build-essential python-dev python-pip
sudo pip install virtualenv

Make a folder for your website:

sudo mkdir -p /var/www/mysite
sudo chown -R <your user id> /var/www/mysite
cd /var/www/mysite

Setup virtualenv and install flask:

virtualenv .env --no-site-packages
source .env/bin/activate
pip install flask

Place your flask app in this folder. Make sure that your host is set to 0.0.0.0 and that your app is under if __name__ == '__main__':. If your app is in a function, uwsgi will not be able to call it.

Now is a good time to test your app with the flask development server to see if everything is working so far. If everything runs smoothly, install nginx and uwsgi:

deactivate
sudo apt-get install nginx uwsgi uwsgi-plugin-python

Next we must create a socket file for nginx to communicate with uwsgi:

cd /tmp/
touch mysite.sock
sudo chown www-data mysite.sock

By changing the owner of mysite.sock to www-data, nginx will be able to write to the socket. Now all we have to do is add our configuration files for nginx and uwsgi. First delete the default configuration for nginx:

cd /etc/nginx/sites-available
sudo rm default

Create a new configuration file mysite and add the following:

server {
    listen 80;
    server_tokens off;
    server_name www.mysite.com mysite.com;

     location / {
         include uwsgi_params;
         uwsgi_pass unix:/tmp/mysite.sock;
     }

     location /static {
         alias /var/www/mysite/static;
     }

     ## Only requests to our Host are allowed
     if ($host !~ ^(mysite.com|www.mysite.com)$ ) {
        return 444;
     }
}

In order to enable the site, we must link our configuration file to /etc/nginx/sites-enabled/:

sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite

The process is similar for uwsgi. Create the file /etc/uwsgi/apps-available/mysite.ini and add the following:

[uwsgi]
vhost = true
socket = /tmp/mysite.sock
venv = /var/www/mysite/.env
chdir = /var/www/mysite
module = app
callable = app

Module is the name of your python script and callable is the name of your flask instance. So if your flask site was in a file called mysite.py that looked like this:

from flask import Flask
my_app = Flask(__name__)

@my_app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    my_app.run(host='0.0.0.0')

Your mysite.ini file would be:

module = mysite
callable = my_app

Link the configuration file to the enabled-apps folder:

sudo ln -s /etc/uwsgi/apps-available/mysite.ini /etc/uwsgi/apps-enabled/mysite.ini

Finally, restart nginx and uwsgi:

sudo service nginx restart
sudo service uwsgi restart

Solution 2

$ python phantom.py &

Is probably the easiest way to make it run in the background. That said you should not be using the app.run() server to serve your flask app if you are moving it into production as @LukasGraf mentions (as well as I believe their documentation)

Solution 3

Probably the best way to do this is behind nginx like @RaphDG answered, But if you want to run it in the background for personal use I found that the logging system would not let you to use only with "&" at the end of the command line, in addition i found that the logger is internal logger of Werkzeug library.

To get around this you can do the next steps(code below):

  1. import werkzeug._internal
  2. create demi logger class
  3. Assign the new class to werkzeug._internal._log (log class)

It will evade notifications and loggers and let you run this process in the background (with "&")

code:

import werkzeug._internal

def demi_logger(type, message,*args,**kwargs):
    pass

the first line in the __main__:

werkzeug._internal._log = demi_logger
Share:
50,268
Uday
Author by

Uday

Updated on October 25, 2020

Comments

  • Uday
    Uday over 3 years

    I have a flask application which I am currently starting up in the following way:

    #phantom.py
    __author__ = 'uruddarraju'
    from phantom.api.v1 import app
    app.run(host='0.0.0.0', port=8080, debug=True)
    

    and when I run this script, it executes successfully by printing:

    loading config from /home/uruddarraju/virtualenvs/PHANTOMNEW/Phantom/etc/phantom/phantom.ini
    * Running on http://0.0.0.0:8080/
    

    But it never returns and if I do a CTRL-C the server stops. I am trying to deploy this to production and want to run this startup on the background, where the process stays up as long as the server is up.

    What is the best way to do this?