MichaelMackus
MichaelMackus

Reputation: 235

Nginx reverse proxying websockets

Is there a way to compile nginx to handle reverse proxying websockets requests? I'm building a realtime app in Node.JS and need a web server on top of this. Everything I've read says Nginx cannot reverse proxy websockets requests, so I'm a little confused on how I should approach this problem.

I was thinking about just implementing all server logic in Node, but there are some problems with this approach

1) PHP - I need a way to serve PHP files 2) Static files - I really like that nginx is very fast for static files. There are some modules for this, though, so this problem isn't too big. 3) When I need to update my Node app, I would like to be able to restart that part separately from the main server. Also, if the Node app crashes for some reason, I don't want the whole web server to go down!

Upvotes: 1

Views: 2033

Answers (2)

madwyatt
madwyatt

Reputation: 362

I am doing something similar, here is the nginx server config( file: MY_DOMAIN.tk.conf on: /etc/nginx/config.d/) that work for me, with:

  • let's encrypt tls cert for ssl
  • php7.2 reverse proxy
  • nodejs reverse proxy for websockets server running on port 8000.

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    
    upstream appserver {
        server localhost:8000; # appserver_ip:ws_port
    }
    
    server {
    
        server_name MY_DOMAIN.tk;
    
        root /var/www/html;
        index index.php;
    
        location /ws {
            proxy_pass http://appserver;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        }
    
    
        client_max_body_size 128m;
        # add_header Strict-Transport-Security "max-age=15768000" always;
    
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/MY_DOMAIN.tk/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/MY_DOMAIN.tk/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    
    }
    
    server {
        if ($host = MY_DOMAIN.tk) {
            return 301 https://$host$request_uri;
        } # managed by Certbot
    
        server_name MY_DOMAIN.tk;
        listen 80;
        return 404; # managed by Certbot
    
    }
    

by doing this then you can conect to wss://MY_DOMAIN.tk/ws

Upvotes: 0

David Cornu
David Cornu

Reputation: 26

The simplest solution would be to setup virtual hosts in nginx for multiple subdomains and run each service on a separate one. That way you don't have to worry about distinguishing websockets requests from standard http requests on the same port.

Also, you can run php behind nginx using PHP-FPM but that's quite a challenge to get working, and for that reason Apache may be a better choice.

Upvotes: 1

Related Questions