I'm trying to make my web app (Django/wsgi-based) available from some subfolder of the main domain. I'm using docker for my app, and static files, so I have main nginx on my server as reverse proxy, another nginx in "nginx" container which routes the stuff for my app and uWSGI in the second container which serves actual Django data
And I want my app to be available externally as myserver.com/mytool
, in the same time I do not want to hardcode mytool
anywhere in my app. Usually SCRIPT_NAME
header is used for this type of stuff, so here is nginx configuration on the host:
server {
listen 80; # Just for sake of simplicity, of course in production it's 443 with SSL
location /mytool/ {
proxy_pass http://127.0.0.1:8000/;
include proxy_params;
proxy_set_header SCRIPT_NAME /mytool; # <--- Here I define my header which backend should use
}
}
Then in my docker-compose
I expose 8000:80 for nginx and here is internal nginx configuration:
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass web:3031;
}
}
With this configuration I would expect that my Django app receives SCRIPT_NAME header, but apparently it does not.
In the same time if I define custom headers like proxy_set_header X-something something;
then this gets forwarded correctly and I can see it from Django.
How should I pass SCRIPT_NAME
to avoid path hardcode in my code?
There are two problems here.
First is that nginx considers headers which contain underscores as invalid, so
SCRIPT_NAME
header is not being accepted by nginx in the container because it's invalid from nginx point of view. Luckily, nginx directive underscores_in_headers is here to help.Just add
underscores_in_headers on;
toserver
section of nginx inside Docker (not to the host one).When this is done here is yet another issue - nginx forwards header prepending
HTTP
in front of its name. So now from Django side you will seeHTTP_SCRIPT_NAME
instead ofSCRIPT_NAME
. But again, luckily for us, it can be easily fixed by usinguwsgi_param SCRIPT_NAME $http_script_name;
line in nginx inside Docker again.Thus, final nginx config inside Docker should look like: