Skip to content

Instantly share code, notes, and snippets.

@gmanau
Last active March 25, 2024 12:15
Show Gist options
  • Star 53 You must be signed in to star a gist
  • Fork 21 You must be signed in to fork a gist
  • Save gmanau/4f5bdb223d1e13417a3e to your computer and use it in GitHub Desktop.
Save gmanau/4f5bdb223d1e13417a3e to your computer and use it in GitHub Desktop.
How to setup nginx as nodejs/socket.io reverse proxy over SSL
upstream upstream-apache2 {
server 127.0.0.1:8080;
}
upstream upstream-nodejs {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name mydomain.com www.mydomain.com;
rewrite ^(.*) https://$host$1 permanent;
}
server {
listen 443 ssl;
ssl on;
server_name mydomain.com www.mydomain.com;
access_log /var/log/nginx/access-ssl.log;
error_log /var/log/nginx/error-ssl.log;
ssl_certificate /etc/nginx/ssl/wasmycertificate.crt;
ssl_certificate_key /etc/nginx/ssl/mycertificate.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
keepalive_timeout 60;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
large_client_header_buffers 8 32k;
location / {
proxy_pass http://upstream-apache2;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Front-End-Https on;
}
location /socket.io/ {
proxy_pass http://upstream-nodejs;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
@oaa97181
Copy link

@nikitalpopov @kylezinter (apologies I never got a notification for your comment) Config as below (domains changed).

upstream my-domain {
        server 127.0.0.1:4001;
}

server {
        listen          80;
        server_name     sub.example.com;
        rewrite         ^(.*)   https://$host$1 permanent;
}

server {
        listen 443 ssl; # managed by Certbot

        server_name sub.example.com;

        ssl_certificate /etc/letsencrypt/live/sub.example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/sub.example.com/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

        location / {
                proxy_pass              http://my-domain;
                proxy_next_upstream     error timeout invalid_header http_500 http_502 http_503 http_504;
                proxy_redirect          off;
                proxy_buffering         off;

                proxy_set_header        Host                    $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto       $scheme;
                add_header              Front-End-Https         on;
        }

        location /socket.io/ {
                proxy_pass              http://my-domain;
                proxy_redirect          off;

                proxy_http_version      1.1;

                proxy_set_header        Upgrade                 $http_upgrade;
                proxy_set_header        Connection              "upgrade";
                proxy_set_header        Host                    $host;
                proxy_set_header        X-Real-IP               $remote_addr;
                proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
        }
}

thank you so fucking much i love you!!!!!! :DDDD

@rushdynamic
Copy link

Hi @CWFranklin, do you mind sharing a snippet of your server creation and client connection blocks? I'm having the same WebSocket is closed before the connection is established error, and my nginx config seems almost identical to yours. Thank you.

@CWFranklin
Copy link

@rushdynamic Hi, hopefully this is of some help for you. I've made a public Gist here of what I think is relevant for a full setup. I've anonymised as much as I can as it's used in a live project, but it should be coherent enough to follow: https://gist.github.com/CWFranklin/e74471360ee420c102be75e1214f018c

If there's anything else specifically you want added then let me know and I can try and sort it.

@rushdynamic
Copy link

Hi @CWFranklin, unfortunately I still haven't been able to figure out exactly what's wrong with my config yet even after going through yours, but it does feel like I'm very close. Thank you so much for taking the time to share your config though, I really appreciate it.

@codenaij
Copy link

Hi @CWFranklin

Here's mine. It doesn't seem to work tho:

server {
    listen 80;
    server_name mydomain.com;
    rewrite ^/(.*) https://mydomain.com/$1 permanent;
}


server {
     
        listen 443 ssl;
        listen [::]:443 ssl;

       

        root /var/www/html;


        #server_name _;
        server_name mydomqin.com;
        ssl_certificate /home/admin/mydomain.com.chained.crt;
        ssl_certificate_key /home/admin/mydomain.com.key;


location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }


location /api {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }


 location /socket.io/  {
      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_set_header X-NginX-Proxy false;

      proxy_pass http://localhost:8000;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }


~         

For my server.js, I had prepared it this way:

require('dotenv').config('.env')
const app = require('./app')
require('./config/db')

const port = process.env.PORT || 8000
const cors = require('cors')

const {
  loadMessages,
  sendMsg,
  setMsgToUnread,
  deleteMsg,
} = require('./utils/messageActions')

const server = app.listen(port, () =>
  console.log(`Server running on port ${port}`)
)
const io = require('socket.io')(server, {
  cors: {
    origin: '*',
  },
})

I get the error WebSocket connection to 'wss://mydomain.com:3000/ws' failed:

@asadmubashr
Copy link

same not working for me have you found any solutions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment