Nginx proxy pass to supervisord

nginxproxypassreverse-proxysupervisord

I am trying to make the supervisord web interface available at http://example.com/supervisor

After trying for many hours I got it to work properly with a trailing slash (http://example.com/supervisor/).
I got it to show up without trailing slash too, but none of the images/css etc. works.

I'm new to nginx so I'm guessing something is wrong with my rewrite rules. The first rewrite is something I tried to add a trailing slash.

supervisord.conf

[unix_http_server]
  file = /tmp/supervisor.sock  ; (the path to the socket file)
  chmod=0700                   ; socket file mode (default 0700)

nginx.conf

location ~* ^/supervisor/? {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_x_host;
     proxy_set_header X-NginX-Proxy true;

     rewrite ^(.*[^/])$ $1/;
     rewrite /supervisor/(.*) /$1 break;
     proxy_pass http://unix:/tmp/supervisor.sock:;
     proxy_redirect off;
     proxy_buffering off;
}

I've been struggling with this for ages now and not sure where to go.
Could anyone point me in the right direction?

Thank you.

Edit:
Thanks Richard, that helped me get a bit further. I had to change the redirect to return 301 $scheme://$host$request_uri/; to get it to work here, but now it redirects to supervisor/

It looks ok now, but pressing refresh, restart etc. works for the command, but does not return to /supervisor/. I changed supervisord to inet_server to test and when going to example.com:9001 everything works fine. I tried to proxy to inet server, but it still does not work.
E.g. refresh button sends: /supervisor/index.html?action=refresh and returns with /?message=Page%20refreshed%20at%20Sat%20Jul%20%201%2014%3A10%3A27%202017
It looks like it does not return to /supervisor/ but to the root of the server (example.com/?message=…)? Any idea how I can fix this?

Edit2:
Ok after googling for hours I made this solution which works for me. Read that I should stay away from if in nginx, so it's probably not a great solution. At least it works here now. I added this to my conf:

if ($http_referer ~* example.com/supervisor ) {
    set $test supervisor;
}

if ($request_uri ~* message ) {
    set $test  "${test}+message";
}

if ($request_uri !~ supervisor ) {
    set $test  "${test}+addsup";
}

if ($test = "supervisor+message+addsup") {
  return $scheme://$host/supervisor$request_uri;
  break;
}

Best Answer

If the resource files are specified using path-relative URIs, the browser may need to see the trailing slash. In which case, you could redirect /supervisor to /supervisor/, which would also simplify your existing location block. For example:

location = /supervisor {
    return 301 /supervisor/;
}
location ^~ /supervisor/ {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_x_host;
    proxy_set_header X-NginX-Proxy true;

    proxy_pass http://unix:/tmp/supervisor.sock/;
    proxy_redirect off;
    proxy_buffering off;
}

Note that the second block is now a prefix location and the previous rewrite statement is now implemented by proxy_pass (using a trailing /). See this document for more.