0

I have been running apps with this server blocks structure for sometime and it has never given me any problems.

geo $authentication {
  default "Authentication required";
  `Some ip number` "off";
}

server {
  listen         80 default_server;
  listen    [::]:80 default_server;
  server_name my.domain.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  ssl_certificate /etc/letsencrypt/live/my.domain.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/my.domain.com/privkey.pem; # managed by Certbot

  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

  server_name my.domain.com;
  client_max_body_size 200M;
  
  root /var/www/;
  index index.php index.html index.htm;

  location / {
    add_header Access-Control-Allow-Origin *;
    auth_basic $authentication;
    auth_basic_user_file /var/www/.htpasswd;
    try_files $uri $uri/ =404;
  }

  # Here is for example the app where I am running socket.io from
  location /myapp {
    auth_basic $authentication;
    auth_basic_user_file /var/www/.htpasswd;
    try_files $uri $uri/ =404;
  }

  # If this app has some sort of api route for express I do a proxy pass
  location /api/upload/ {
    proxy_pass http://localhost:5003/api/upload;
  }

However I am trying to use socket.io and I am having problems understanding if the subfolder is a problem as I keep getting CORS if I try to connect from the client as in

import { io } from 'socket.io-client'
const socket = io('http://localhost:5003')

On the server I got this

import express from 'express'
import { createServer } from 'http'
import { Server } from 'socket.io'

const app = express()
const prod = process.env.NODE_ENV === 'production'
const port = process.env.PORT || prod ? 5003 : 4000
const httpServer = createServer(app)

const io = new Server(httpServer, {
  cors: {
    origin: '*',
    methods: ['GET', 'POST']
  }
})

const connections = []

io.on('connection', (socket) => {
  connections.push(socket)
  console.log(`Socket id ${socket.id} connected`)

  socket.on('disconnect', () => {
    connections.splice(connections.indexOf(socket), 1)
  })
})

httpServer.listen(port, () => console.log(`App listening on port ${port}.`))

I can see that whereas on development it all works fine and it establishes a web socket connection:

enter image description here

On the server after the CORS of course it does not:

enter image description here

No matter what I try, I always end up getting this: enter image description here

Álvaro
  • 117
  • 1
  • 2
  • 8

1 Answers1

1

In your second picture, the socket.io lib is using polling. This may come because you didn't set the nginx config properly.

location /socket.io/ {
    proxy_pass http://localhost:5003/socket.io/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
}

Here is a good example.After changing this you should be able to reach your backend just using the following:

import { io } from 'socket.io-client'
const socket = io()

Notice that if all your request go through the Nginx, you don't need the CORS directives as all your request will be going to the same address and port.

Álvaro
  • 117
  • 1
  • 2
  • 8
SePeF
  • 126
  • 3
  • Thanks but where is `http://wsbackend` coming from? I tried it with `http://localhost:5003/socket.io/` and I get 404 – Álvaro Feb 19 '21 at 17:55
  • Is the address of your backend express + socket.io server. If the Nginx and backend are running in the same host you can try with 127.0.0.1, if it is a docker container it is the name of the container/service. from your code `const port = process.env.PORT || prod ? 5003 : 4000` if you don't set is in an env var and you are in development, then the port is 4000 – SePeF Feb 19 '21 at 18:17
  • I am doing this without docker just with a nginx server on ubuntu on linode, when I run the server I can see with pm2 that the app is indeed listening on 5003. I mean I want to run on port 4000 when in dev and 5003 when in production and that part actually works – Álvaro Feb 19 '21 at 18:19
  • are you serving your frontend code also over the nginx, if not you will get the CORS problem. – SePeF Feb 19 '21 at 18:28
  • The react front end is just accessed when you go to`https://my.domain.com/myapp/index.html` is the front end who access the backend with the proxy_pass from nginx, when I need to request something from an express route. The nginx file you see is the one that I am using. – Álvaro Feb 19 '21 at 18:31
  • Did you change the frontend code (`const socket = io()`)? If you did you could try `const socket = io('wss://my.domain.com')` to force TLS as you don't have a redirect to port 443 when you connect to port 80. – SePeF Feb 19 '21 at 18:49
  • When I do that I don't get CORS but the ws tab on network is blank and socket.io do not work – Álvaro Feb 19 '21 at 18:57
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/119954/discussion-between-alvaro-and-sepef). – Álvaro Feb 19 '21 at 19:06