Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx configuration for static sites in root directory, Flask apps in subdirectories

I'd like to have a static site in my root public_html directory, then Flask apps in their own subdirectories (e.g. public_html/foo). The static root directory functions as expected.

I have spent hours editing the nginx configuration to get the Flask apps working, but always end up back in the same place, namely that the following code always returns 'Bad Config' when I migrate to mysite/foo. I want it to return 'Hello World!'

If I alter the nginx configuration so that the server root is in public_html/foo, the Flask applications work as expected (i.e. mysite.com returns 'Hello World!'). In the following configuration, the Flask index still points to mysite.com when I believe it should point to mysite.com/foo

/etc/nginx/sites-enabled/mysite

upstream frontends {
# gunicorn
server 127.0.0.1:18000;
}

server {
listen 80;
server_name www.mysite.com;
rewrite ^/(.*) http://mysite.com$1 permanent;
}

server {
listen 80;
server_name mysite.com;
server_name_in_redirect off;
root /home/ubuntu/public_html/mysite;

access_log /home/ubuntu/logs/mysite/access.log;
error_log /home/ubuntu/logs/mysite/error.log;

location / {
    index index.html;
    }
location /foo {
    try_files $uri @foo;
    }
location @foo {
        proxy_pass http://frontends;
        break;
    }
}

/home/ubuntu/public_html/mysite/foo/foo.py

from flask import Flask
from flask import render_template
app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World!'

@app.route('/foo')
def test():
    return 'Bad config'

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

if __name__ == '__main__':
    app.run()

/home/ubuntu/public_html/mysite/foo/deploy.py

workers = 2
bind = '127.0.0.1:18000'
proc_name = 'foo_gunicorn'
pidfile = 'foo.pid'

Flask is launched with gunicorn -c deploy.py foo:app

Update

Adding rewrite /foo/(.*) /$1 break; to the nginx location /foo block makes mysite/foo return 'Hello World', however all its links (such as those to the stylesheet from a template) still point to the site root (e.g. mysite/static/style.css instead of mysite/foo/static/style.css)

like image 565
Jason Winget Avatar asked Sep 26 '11 16:09

Jason Winget


Video Answer


1 Answers

Got an answer from mitsuhiko (Flask lead dev): http://flask.pocoo.org/snippets/35/

You need to define a ReverseProxied class in your Flask app and add several proxy-set-header lines to the location /foo block in the nginx config.

like image 137
Jason Winget Avatar answered Oct 07 '22 00:10

Jason Winget