17

ok, this task should be simple but I just can't get it to work. I would like to have a subfolder after my domain name (actually after the IP of that domain name), which redirects to a specific port on the same server. Essentially, I want to get rid of having to use many ports.

Here is my nginx config for that

server {
    listen 80;

    index index.html index.htm index.nginx-debian.html index.php;

    server_name aaa.bbb.ccc.ddd;

    location ^~ /app2 {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://aaa.bbb.ccc.ddd:8001;
    }
}

So upon accessing aaa.bbb.ccc.ddd/app2 I would like this to resolve to http://aaa.bbb.ccc.ddd:8001.

This can note possibly be so complicated. What am I missing here?

Thank you Pat

1
  • Do you mean "redirects to a port" or "proxies to a port"? They're quite different. Your question is unclear, perhaps you could expand on your use case including client.
    – Tim
    Jul 27, 2016 at 19:08

2 Answers 2

24

Since you tagged this as a reverse proxy question, I assume you mean that you want to proxy the request so that user only sees http://aaa.bbb.ccc.ddd/app2 URL in her browser.

You can change your location block to this:

location ~/app2(.*)$ {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://aaa.bbb.ccc.ddd:8001$1;
}

Here we capture the URI part after /app2 to $1 variable, and use it in the proxy_pass directive.

6
  • Thank you. That kinda did the trick. aaa.bbb.ccc.ddd:8001 is only displayed partially. There are websockets on that page and plenty of java script. I guess that is because I proxy the port and do not forward it as Tim mentioned above. Is this actually possible to achieve just using nginx?
    – pAt84
    Jul 27, 2016 at 21:05
  • What do the URLs of resources look like at the aaa.bbb.ccc.ddd:8001 page? Most likely you need to fix the URLs to contain the /app2 part. Jul 27, 2016 at 21:09
  • It is really just a websocket there (showing some radar data, automotive...). There is no sign of "app2" in the source code.
    – pAt84
    Jul 27, 2016 at 21:23
  • Hm ok, yes. To call the websocket JS uses " var ws = new WebSocket('ws://' + location.host + '/ws');". location.host now misses the port number, which makes the whole thing not work anymore.
    – pAt84
    Jul 27, 2016 at 21:57
  • 1
    There are two options. Either a proxy_pass solution, where user sees http://aaa.bbb.ccc.ddd/app2 in the browser. In this case, the location.host contains aaa.bbb.ccc.ddd. You need to add app2 there to make it work. Another alternative is rewrite, where user sees http://aaa.bbb.ccc.ddd:8001 in the browser, and is what the browser will use. There is no middle-way. Jul 28, 2016 at 8:39
2

The answer of Tero Kilkanen is great. However, in some situations, the non-named regex group(ex: $1) cannot be found. We can use the named group(ex: $sub_dir) to prevent this error.

location ~/app2(?<sub_dir>.*)$ {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://aaa.bbb.ccc.ddd:8001$sub_dir;
}

The above example uses (?<sub_dir>.*) to set the named group, we can use $sub_dir to get this Regex group value.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .