If I have a node express server running on port 5003

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) => {
  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}.`))

And a client connecting the socket.io to the server

const socket = io(`http://localhost:5003`)

What would the nginx server block configuration be?

The url where this app is at is like this:


And my server blocks are:

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

server {
  listen         80 default_server;
  listen    [::]:80 default_server;
  server_name my.domain.com;
  return 404; # managed by Certbot

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;

Here is an example NGINX configuration block for webscokets. Notice how the connection is upgraded if a valid websocket connection is made to the end point

More at NGINX as a WebSocket Proxy

location /wsapp {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
    proxy_hide_header 'Access-Control-Allow-Origin';
  • This example is for a subfolder commonly referred to as an endpoint. That way NGINX doesn't try_files a path that is meant only for websockets to connect. No html or PHP is ever rendered at this end point. It accepts webscoket connections or nothing at all. – suchislife Feb 19 at 18:49
  • When I do this I get a CORS message, I am making the connection for socket io to and added the location endpoint – Álvaro Feb 19 at 18:53
  • I've updated the answer to use NGINX's proxy_hide_header directive. It could be that the server behind your proxy_pass is setting the Access-Control-Allow-Origin header. – suchislife Feb 19 at 19:07
  • So are you saying that the socket.io should connect like this const socket = io('') obviously I also changed the nginx proxy to 5003? I still get CORS thou – Álvaro Feb 19 at 19:09
  • More like const socket = io('wss://') WSS for SSL and WS for NON-SSL. I see your URL is not HTTPS but your nginx.conf example is. – suchislife Feb 19 at 19:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.