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?