3

I'm new to nginx and how it handles locatoins, and was hoping to get help for a problem I'm having:

On the same server I have an Apache web server and a websocket server. Apache works on port 8080 and the websocket server works on 9090. I would like to put an nginx proxy in front so that http/https traffic gets proxied to apache and the ws/wss traffic gets proxied to the websocket server.

I have the following configuration:

location /ws* {
    proxy_pass ws://127.0.0.1:9090;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://127.0.0.1:8080;
}

This works fine, but the problem I'm facing is that all ws* requests also get redirected to the apache server whilst I only want them to be redirected to the ws server. I've read that nginx takes only the first location that matches, but this seems to be wrong in my case.

So the question is how do I proxy http(s) traffic ONLY to apache and ws(s) traffic ONLY to the web socket server?

Dave M
  • 4,494
  • 21
  • 30
  • 30
Mita Ka
  • 133
  • 1
  • 4

1 Answers1

2

The location syntax you have doesn't seem like what you are trying to do.

If you are trying to do regex with the location URL, the proper syntax is:

location ~ /ws.* {

If you are trying to do everything under ws directory, you should have:

location /ws/ {

You may want to review the documentation for more information on location. http://nginx.org/en/docs/http/ngx_http_core_module.html#location

Grumpy
  • 2,939
  • 17
  • 23
  • Thanks for pointing that out, I will give it a try. Though, does it solve the original problem? If I put "ws" in some of the http(s) URIs, wouldn't the ws(s) location still match? My goal is to proxy http(s) traffic to one server and ws(s) to another irrespective of the URIs being used. I guess the question comes down to "Is there a way to capture the protocol being used and proxy requests based on that"? – Mita Ka Sep 23 '14 at 05:37
  • Try reading that documentation. Nginx only picks one location, in case of no regular expression, the longest match. –  Sep 23 '14 at 06:25
  • @Grumpy, the suggestion about "location ~ /ws.* {" moved me a little bit further, but I can't upvote your comment because I don't have enough reputation. I would love to mark it as a solution, but we have not addressed the main question: can we proxy requests based on the protocol they use (http/ws)? – Mita Ka Sep 23 '14 at 08:33
  • @Dimitar if you are ultimately trying to set up two different services under same port and host, ideal environment can't be achieved because you are trying to overload a single interface. There is a variable called `$server_protocol` and you can use if statements to separate it. However, if statement is not recommended. http://wiki.nginx.org/IfIsEvil | If you set a separate host or port, you can simply setup a separate server {} block to handle each of them. – Grumpy Sep 23 '14 at 17:18