0

I am running any Nginx file server. I have 2 main folders i.e. folder-a and folder-b. If a user tries to land on /folder-a/abc and it's a 404, I should auto-redirect to another folder like /folder-b/abc. How do I set up such a rule in Nginx? My top folder names will always be hard-coded names like folder-a and folder-b.

Hacker
  • 7,798
  • 19
  • 84
  • 154

1 Answers1

1

As being said by @RichardSmith, if you want to look for a file in one of two locations, you can use try_files directive:

location ~ ^/folder-a(?<suffix>/.*) {
    try_files $uri $uri/ /folder-b$suffix /folder-b$suffix/ =404;
}

If you want to generate an HTTP redirect, you can use error_page directive with the additional named location:

location ~ ^/folder-a(?<suffix>/.*) {
    error_page 404 @redirect;
}

location @redirect {
    return 301 /folder-b$suffix;
}

If you have some additional configuration directives in your root location (location / { ... }), you should either duplicate them inside the location ~ ^/folder-a(?<suffix>/.*) { ... } or move them to the server context if there are no other locations where those directives should not be applied.

Ivan Shatsky
  • 13,267
  • 2
  • 21
  • 37
  • I did use the redirect code as above, but looks like all clicks on folder-a is taking to folder-b – Hacker May 27 '21 at 05:15
  • `code` worker_processes 1; events { worker_connections 1024; } http { server { server_name localhost; listen 80; location / { root /usr/share/nginx/html/; include /etc/nginx/mime.types; autoindex on; autoindex_exact_size off; autoindex_localtime on; } location ~ ^/folder-a(?/.*) { error_page 404 @redirect; } location @redirect { return 301 /folder-b$suffix; } } } `code` – Hacker May 27 '21 at 05:15
  • Both my folders are inside /usr/share/nginx/html/ – Hacker May 27 '21 at 08:30
  • With your configuration directives `root`, `include mime.types` and all the `autoindex` ones are applied only to the `location / { ... }` and not the other one. Move them to the `server` context (and `include mime.types` is usually placed at the `http` context). Remove trailing slash from `root /usr/share/nginx/html/` directive. You can omit `location / { }` at all. – Ivan Shatsky May 27 '21 at 09:29
  • `code` worker_processes 1; events { worker_connections 1024; } http { include /etc/nginx/mime.types; server { server_name localhost; listen 80; root /usr/share/nginx/html; autoindex on; autoindex_exact_size off; autoindex_localtime on; location ~ ^/folder-a/(.+)$ { error_page 404 @redirect; } location @redirect { return 301 /folder-b/$1; } } } `code` – Hacker May 27 '21 at 09:50
  • Changed code to look like above, as per your suggestion. Any changes required. Was able to get it to work as needed. – Hacker May 27 '21 at 09:51
  • Your new config looks ok. You slightly changed regex part, but in practice it won't make any difference, both variants works equally. I have added a note about additional configuration directives to my answer. – Ivan Shatsky May 27 '21 at 10:03
  • I removed the root location only, so it should be fine. – Hacker May 27 '21 at 10:17
  • On similar lines I have another question, https://stackoverflow.com/questions/67721091/merge-directory-listing-for-2-different-folders-nginx any help would be much obliged. – Hacker May 27 '21 at 11:27
  • No, I don't think it's possible. Well, you can write your own backend with PHP to generate such a joined index file or even write your own advanced version of [`ngx_http_autoindex_module`](https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_autoindex_module.c) and add such a feature :)) – Ivan Shatsky May 27 '21 at 12:27
  • If my folders folder-a and folder-b are on 2 different NFS mounts. Maybe something of unionfs would work? and then new folder can be linked for ngingx file explorer? – Hacker May 29 '21 at 03:36
  • 1
    Maybe something like unionfs/overlayfs/aufs could work, but I never used them and this is outside the scope of the original question. – Ivan Shatsky May 30 '21 at 15:38