1

I built a web app that will listen on a port and handle HTTP requests. For example, if I run it locally at 127.0.0.1:3000. I can access it with http://127.0.0.1:3000/path/within/app on my browser. I would like to deploy it on one of my servers, which is configured with nginx to handle all incoming requests (and TLS) and forward them to different applications (listening at http://127.0.0.1:xxx). Normally, I would give each app a different subdomain (e.g., access app1 with app1.example.com and app2 with app2.example.com), but it would be more convenient if I can use subpath (e.g., access app1 with example.com/app1 and app2 with example.com/app2). But I am not sure how to configure it.

My current configuration file is like the following. Suppose my app is listening at 127.0.0.1:3000.

location ^~ /app1 {
    proxy_set_header    X-Real-IP  $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header    Host $http_host;
    proxy_redirect      off;
    proxy_pass          http://127.0.0.1:3000/;
}

I would like to achieve the following.

  1. When I access https://example.com/app1, it will be equivalent to accessing http://127.0.0.1:3000.
  2. When I access https://example.com/app1/path/within/app, it will be equivalent to access http://127.0.0.1:3000/path/within/app.

However, with the above mentioned configuration file, only the first part work. If I access https://example.com/app1/path, my app complaints that it was http://127.0.0.1:3000//path that actually get accessed, and it doesn't know how to handle //path.

I would prefer not to modify any part of my application so that it can run independently if I decided to give it a subdomain in the future, and expects a fix with only modifying the nginx configuration file if possible. In addition, I am aware of the problem that any clickable links generated by the app will also need to handle subpath, but this app is simple enough that that is not a problem.

Thanks.

3
  • Change your location to location ^~ /app1/ { ... } (note the trailing slash). If you want the /app1 URI to be workable too, add location = /app1 { return 301 /app1/; } to your configuration. Jan 29, 2022 at 17:49
  • Thanks, are there ways to make /app1 work without sending 301?
    – lewisxy
    Jan 30, 2022 at 6:45
  • You can try location = /app1 { rewrite ^ /app1/ last; }. However in some cases it can make your app unable to load its assets (see the explanations in this answer) and I don't recommend to do it. Jan 30, 2022 at 7:09

1 Answer 1

0

Try the following configuration

location /app1/ {
    proxy_set_header    X-Real-IP  $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header    Host $http_host;
    proxy_redirect      off;
    proxy_pass          http://127.0.0.1:3000/;
}

location /app1 {
    return 301 /app1/;
}
5
  • 1
    Thanks, it works. However, are there ways to configure it so that I don't need to send 301 when client accesses /app1? In other words, I would prefer redirect on server side rather than client side, if possible.
    – lewisxy
    Jan 30, 2022 at 6:40
  • Are you sure that is what you want? Then you will have duplicate content at http://example.com/app1 and http://example.com/app1/ URLs, which is a problem for SEO. Jan 30, 2022 at 8:38
  • The current app I am working on only provide JSON APIs, so no HTML page. However, I don't have enough experience on this topic. What is the convention if my app is an actual website? Do we generally prefer the one with trailing slashes or not? Also, how does this choice affect query parameters (those after ?), if at all?
    – lewisxy
    Jan 30, 2022 at 14:16
  • Query arguments are independent of the path component of a URL, so there it doesn't matter. In my own projects, I do 301 redirect from /app1 to /app1/, because the one with ending slash is easier to handle in different places. Jan 30, 2022 at 16:26
  • 301 with api request is bad idea, all who do this shall be sent back to modem epoch or to long ping areas, to feel that 300ms is much less than 600ms
    – zb'
    Sep 13, 2022 at 8:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.