vincentdnl

Deploy multiple Flask applications with Nginx reverse proxy and Gunicorn

May 23rd, 2016

    I often use the Python framework Flask for my projects because it is simple and I can focus on my domain logic. I usually also use Gunicorn to serve my applications with Nginx as a reverse proxy. My Gunicorn tasks are executed by an upstart script:

    description "mytask"
    
    start on runlevel [2345]
    stop on runlevel [!2345]
    
    respawn
    setuid user
    setgid user
    
    env PATH=/path/to/flask/venv/
    chdir /path/to/my/app
    exec gunicorn --workers 3 -b unix:mysock.sock wsgi:app
    

    My app is started by wsgi.py in my app folder:

    from app import app
    
    if __name__ == "__main__":
        app.run()
    

    The upstart tasks create mysock.sock UNIX domain socket files in my apps folders. They will be used by Nginx to serve my applications.

    In /etc/nginx/sites-available, I create my config file:

    server {
        listen 80 default_server;
        server_name example.com;
    
        location /my-first-app/ {
            prox_pass http://unix:/path/to/my/app1/mysock1.sock:/;
        }
    
        location /my-second-app/ {
            prox_pass http://unix:/path/to/my/app2/mysock2.sock:/;
        }
    
        #...
    }
    

    The ":/" part means that if you try to access http://example.com/my-first-app/my-route/, your app will receive the route "/my-route" and not "/my-first-app/my-route" that would not match the following route in your Flask app:

    @app.route('/my-route', methods=['GET'])
    def my_route():
        pass
    

    I hope this basic tutorial helped. Feedbacks in comments are welcome!