Nginx socket proxy between Node.js and React both running in separate Docker containers

Viewed 394


I wrote some chat app which is using Nodejs and socket.io for backend and React with socket.io-client for frontend. In development process, which means without Docker and Nginx the communication between those two worked like a charm. But now I want to deploy the app to the web (AWS BeansTalk) and I Docker'ised them and introduced them with Nginx for proxy between containers. But I can't get the websockets to working.

So the error look like this:

  • Firefox:
    Firefox can’t establish a connection to the server at ws://localhost:5000/socket.io/?EIO=3&transport=websocket.

  • Opera
    WebSocket connection to 'ws://localhost:5000/socket.io/?EIO=3&transport=websocket' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

The code I have:

  • Server side:
const express = require('express');
const http = require('http');
const socketio = require('socket.io');
const cors = require('cors');

const app = express();
const server = http.createServer(app);
const io = socketio(server);

io.set('origins', '*:*');

app.use(cors());
  • Client side
import io from 'socket.io-client';

const ENDPOINT = 'localhost:5000';
const socket = io(ENDPOINT);
  • Nginx conf
upstream client {
    server client:3000;
}

upstream api {
    server api:5000;
}

server {
    listen 80;

    location / {
        proxy_pass http://client;
    }

    location /api {
        proxy_pass http://api;
    }

    location /socket.io {
        proxy_pass http://api;
        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;
    }
}
  • docker-compose.yaml
version: '3'
services:
  nginx:
    restart: always
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - '3050:80'
  api:
    build: 
      dockerfile: Dockerfile.dev
      context: ./backend-prod
    volumes:
      - /app/node_modules
      - ./backend-prod:/app
  client:
    stdin_open: true
    build: 
      dockerfile: Dockerfile.dev
      context: ./frontend-prod
    volumes: 
      - /app/node_modules
      - ./frontend-prod:/app

Things I have tried:
Using different connection config options for Client side:

  const socket = io(endpoint, {
    rememberUpgrade: true,
    transports: ['websocket'],
    secure: true,
    rejectUnauthorized: false,
  });

Adding some config for Nginx

map $http_upgrade $connection_upgrade {
   default upgrade;
   '' close;
}

but none of these worked.

What is interesting, there is another error with sockets for Client side this time:

Firefox can’t establish a connection to the server at ws://localhost:3050/sockjs-node.

Which I FIXED and it is working correctly by only specifying the same policy for proxy in Nginx file:

location /sockjs-node {
    proxy_pass http://client;
    proxy_http_version 1.
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
}

But as you see, this solution does not work with socket.io.

Could you help me, please?

0 Answers
Related