gomennathan
gomennathan

Reputation: 133

Putting a Flask app with gunicorn behind Caddy reverse proxy

I have a Flask app which I am running with gunicorn. It works by itself. I can reach the app at localhost/ and go to other links from there. The app assumes its root path is / and generates all relative URLs accordingly.

Now I want to put this behind a reverse proxy, for which I use Caddy. But also I want it to be on a subpath. So users would see example.com/myapp/ as the root page, and pages like example.com/myapp/profile. However, the Flask app's code would continue to have things like <a href="/profile">. I assume Caddy can simply rewrite the URLs and make it all work, since other servers I've used have all been able to work this way, although they usually take some kind of "root URL" config parameter.

However, when I run my app with the reverse proxy, the URLs are broken. It tries to send users from example.com/myapp/ to example.com/profile instead of example.com/myapp/profile. My Caddyfile currently just says:

handle_path /myapp/* {
    reverse_proxy internal.app.url:8000
}

How can I get the links to work correctly? Is this a problem that should be solved in the Caddyfile, the gunicorn configuration, or my Flask app?

Gunicorn has an example nginx config where they set some proxy headers: https://docs.gunicorn.org/en/latest/deploy.html However, in my experience nginx has some silly defaults and configuration ends up being verbose because of it. How much of this stuff would I need to replicate in my Caddyfile, and how?

Flask apparently has a url_for method which can dynamically generate URLs. However, I could simply define a ROOT_URL parameter in my app, and prepend that to all my relative URLs. I'm pretty sure it would work, but it would make all the URLs look ugly, and I couldn't access my app's pages at localhost/profile anymore (for testing), I would have to use localhost/myapp/profile. Also the "recommended" url_for seems more work than just doing it myself, so I feel like I'm missing something here.

Upvotes: 1

Views: 1269

Answers (1)

Probel
Probel

Reputation: 195

For what it's worth, I believe the problem is in the Caddyfile. You should use handle instead of handle_path to not strip the prefix from the url.

From the Caddy documentation for handle_path:

Works the same as the handle directive, but implicitly uses uri strip_prefix to strip the matched path prefix.

Upvotes: 0

Related Questions