Gunicorn through mod_proxy redirects outside the scope of the project, despite ProxyPassReverse

I have a WSGI application (Django project) running under gunicorn on 127.0.0.1:18731 and I use Apache with mod_proxy to redirect requests from http://example.com/my-project/* to http://127.0.0.1:18731/* . Static files are stored outside of /my-project/ . If there is no need to redirect something in the Django application, this works fine, but if it tries to redirect the request (for example, add a trailing slash to http://example.com/my-project/foo ), it will remove /my-project/ from url leaving me with an invalid url http://example.com/foo/ .

My mod_proxy configuration is as follows:

 <Proxy *> Order deny,allow Allow from all </Proxy> ProxyRequests On ProxyPass /my-project/ http://127.0.0.1:18731/ retry=0 ProxyPassReverse /my-project/ http://127.0.0.1:18731/ retry=0 ProxyPreserveHost On ProxyErrorOverride Off 

I do not want to force Django to prefix /my-project/ with all its URLs, in the interest of portability. Obviously, Apache must handle the prefix itself using the ProxyPassReverse line. What am I doing wrong?

+7
source share
4 answers

I decided to switch to nginx, not being able to find a solution to the Apache ProxyPassReverse problem within a few days after requesting several help sites. Not to mention the various other issues that I have had with Apache over the past year. The problem can also be solved by creating a separate virtual host only for the proxy server, but I personally am not satisfied with this solution.

However, I recommend trying Chris first. I have not personally tested it, but its reasoning sounds (although a few months is too late for me).

0
source

I had this problem.

 ProxyPreserveHost On <Location "/my-project/"> ProxyPass http://127.0.0.1:18173/my-project/ ProxyPassReverse http://127.0.0.1:18173/my-project/ RequestHeader set SCRIPT_NAME /my-project RequestHeader set X-FORWARDED-PROTOCOL ssl RequestHeader set X-FORWARDED-SSL on </Location> 

To enable the WSGI application to create an absolute URL, we need:

  • ProxyPreserveHost On , so the Host: header is passed, and the application knows the host name with which the client sees us.
  • Add the SCRIPT_NAME header to let the application know where its root is.
  • Set the X-FORWARDED- headers as X-FORWARDED- . I use ssl too, so I have to say that the application should use the https scheme.

I use the <Location> directives because I do a lot more things on this vhost. But you can easily rewrite this by passing the path arguments ProxyPass and ProxyPassReverse .

NB: ProxyRequests should be Off if you do not want a proxy server forward. If you are reading this, you probably only need a reverse proxy.

Django's special note: settings.LOGIN_URL used as is, so you need to add SCRIPT_NAME to it in advance.

+6
source

Have you tried this? I added my project to a URL that you are also connecting to.

 <Proxy *> Order deny,allow Allow from all </Proxy> ProxyRequests On ProxyPass /my-project/ http://127.0.0.1:18731/my-project/ retry=0 ProxyPassReverse /my-project/ http://127.0.0.1:18731/my-project/ retry=0 ProxyPreserveHost On ProxyErrorOverride Off 

I usually use nginx for this kind of thing, so I'm not sure if this will work or not.

Update : the above does not work, so try something else.

Try something similar and see if that helps. This is a little different. It proxies everything except the media, which is served through an alias. This eliminates the need to have / my-project / in general.

 <VirtualHost *:80> ServerName example.com UseCanonicalName On ServerAdmin webmaster@localhost LogLevel warn CustomLog /var/log/apache2/example.com/access.log combined ErrorLog /var/log/apache2/example.com/error.log ServerSignature On Alias /media/ /home/example/example.com/pysrc/project/media/ ProxyPass /media/ ! ProxyPass / http://127.0.0.1:18731/ ProxyPassReverse / http://127.0.0.1:18731/ ProxyPreserveHost On ProxyErrorOverride Off </VirtualHost> 
+2
source

I solved the original problem by setting the ProxyPassReverse configuration to the actual domain name:

 ProxyPass /my-project/ http://127.0.0.1:18731/ ProxyPassReverse /my-project/ http://mydomain.com/ 

Hint: Apache ProxyPassReverse values

0
source

All Articles