Compulsory trailing slashes with Caddy and gunicorn + flask

(Graeme Merrall) #1

I’ve been experimenting with Caddy and gunicorn for running multiple python apps under subdirectories. The idea is to them running in subdirectories

|- /app1/ -> gunicorn -> flask
|- /app2/ -> gunicorn -> flask

To do this I just set up a proxy directive according to the following:

proxy /gunicorn/ unix:/var/www/python/gunicorn/hello.sock {
         header_upstream SCRIPT_NAME /gunicorn

This works pretty well but I’ve discovered that because of the rewriting of trailing slashes all routes must use a trailing slash e.g. /page2/ otherwise gunicorn errors out with parsing the request. This is not a huge deal but it would be nice to have the option or in some way be able to use /page2 instead.

I’ve tried a few other combinations of just /gunicorn as the proxy path and also using the ‘without’ parameter but the above seems to be the only combination that works.

For interested parties who’d like to recreate the issue, the actual test Flask app is as simple as it gets.

Omitting the trailing slash for ‘/page2/’ causes the issue to occur. Is there a way to achieve having routes omitting the trailing slash? e.g. just ‘/page2’

from flask import Flask, render_template, url_for

app = Flask(__name__)

def hello():
  return render_template('hello.html')

def page_two():
  return render_template('page2.html')

if __name__ == "__main__":

template is:
<p><a href="{{ url_for('page_two') }}">Link to page2</a></p>

and the gunicorn command is:
pipenv run gunicorn -w 2 -b unix:hello.sock hello:app --reload --access-logfile /var/log/python/gunicorn_access.log --error-logfile /var/log/python/gunicorn_error.log --log-level debug

(Michael Munson) #2

Can you try changing:
proxy /gunicorn/ unix:/var/www/python/gunicorn/hello.sock

to proxy /gunicorn unix:/var/www/python/gunicorn/hello.sock


(Michael Munson) #3

Here is what I use for gunicorn:

root /home/web/website/

header / -Server

rewrite {
    to /public/{path}

proxy /public unix:/home/web/gunicorn.sock {
    except /static
    without /public

log stdout

It’s the slightly awkward equivilent of try_files then proxy.

(Matthew Fay) #4

@SpiraMirabilis, a slightly more elegant try-then-proxy:

root /home/web/website/public/static

header / -Server

rewrite {
    to {path} {path}/ /proxy{uri}

proxy /proxy unix:/home/web/gunicorn.sock {
    without /proxy

log stdout