Usually userdir's in webservers prefix a ~ to the username, e.g. https://example.com/~me/ to access /home/me/public_html/.
Now, for $reasons, I need to setup an nginx server that serves directories in /home/${user}/public_html/ without this ~ prefix: https://example.com/me/.
At the same time, the webserver should also serve content from the webroot (/var/www/html/).
I don't really care for the case where content is available in both locations (e.g. https://example.com/foo/index.html could be served by both /var/www/html/foo/index.html and /home/foo/public_html/index.html).
Answers here on Server Fault have lead me to this config:
location ~ (?<user>[^/]+)(?<path>.*)?$ {
alias /home/$1/public_html$2;
index index.html index.htm;
autoindex on;
}
This works OK, but unfortunately, it also shadows the webroot (so I can no longer access /var/www/html/index.html via https://example.com/index.html).
So my 2nd try is this:
location ~ (?<user>[^/]+)(?<path>.*)?$ {
root /home/$user/public_html;
try_files $path $path/ @fallback;
index index.html index.htm;
autoindex on;
}
location @fallback {
root /var/www/html/;
index index.html index.htm;
}
This allows me to access both /home/me/public_html/index.html via https://example.com/me/index.html and /var/www/html/index.html via https://example.com/index.html
It also allows me to /home/me/public_html/bla/index.html via https://example.com/me/bla/
Unfortunately, things break with https://example.com/me/bla (note the missing trailing slash): nginx will issue a permanent redirect (301) to https://example.com/bla/ (stripping away my username! where it really should only do a redirect to https://example.com/me/bla/).
This gives plenty of 404 errors (when /var/www/html/bla/ does not exist), or the wrong content (when it does exist).
I'm sure people will forget to add their trailing slashes, and then end up in the wrong (or non-existant) directories.
My gut feeling is, that this wrong redirection comes from my use of root in the location block.
There's no such problem with alias, but how can I use try_files with a fallback location in that case?
So: how can I teach nginx to serve userdirs without a ~, while still serving content from my webroot and allowing the user to forget to type the trailing / when they want to access directories on the webserver?