Navigation Menu

Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

502 Bad Gateway. Proxy socket.io using Nginx #273

Closed
skeeith opened this issue Feb 27, 2018 · 12 comments
Closed

502 Bad Gateway. Proxy socket.io using Nginx #273

skeeith opened this issue Feb 27, 2018 · 12 comments

Comments

@skeeith
Copy link

skeeith commented Feb 27, 2018

Windows 10 Home Single Language
NodeJS v8.9.4

using Homestead as server (192.168.10.10)

SCENERIO
2 domains
domain-name.dev (Web App Domain)
socket.domain-name.dev (Socket Sub Domain)

SERVER BLOCK CONFIGURATION

server {
listen 80;
listen 443 ssl;
server_name domain-name.dev;

location /socket.io/ {
    proxy_pass http://localhost:6001;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header X-Real-IP $remote_addr;

    proxy_buffers 8 32k;
    proxy_buffer_size 64k;

    add_header 'Access-Control-Allow-Origin' 'https://socket.domain-name.dev' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,Authorization,X-CustomHeader,Keep-Alive,User-Agent,X-Requested$        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modi$    }

access_log off;
error_log  /var/log/nginx/socket.domain-name.dev-error.log error;

ssl_certificate     /etc/nginx/ssl/socket.domain-name.dev.dev.crt;
ssl_certificate_key /etc/nginx/ssl/socket.domain-name.dev.dev.key;

}

CONSOLE LOG OUTPUT
https://socket.domain-name.com/socket.io/?EIO=3&transport=polling&t=M7Ork96 502 (Bad Gateway)

Laravel-Echo-Server Config
{
"authHost": "https://domain-name.dev",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "abe8852957c867cf",
"key": "67c71c1f7b7cbb70fbbeda6f340c2891"
}
],
"database": "redis",
"databaseConfig": {
"redis": {
"port": "6379",
"host": "192.168.10.10",
"password": "960c3dac4fa81b4204779fd16ad7c954f95942876b9c4fb1a255667a9dbe389d"
},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": false,
"host": null,
"port": "6001",
"protocol": "https",
"socketio": {},
"sslCertPath": "/etc/nginx/ssl/domain-name.dev.dev.crt",
"sslKeyPath": "/etc/nginx/ssl/domain-name.dev.key",
"sslCertChainPath": "",
"sslPassphrase": "",
"apiOriginAllow": {
"allowCors": true,
"allowOrigin": ".",
"allowMethods": "GET, POST",
"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
}
}

@stierler
Copy link

On your proxy_pass config, try including /socket.io/ at the end, since it's most likely stripping that off.

My nginx config in a dev environment that proxies correctly looks something like:

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

@J5Dev
Copy link

J5Dev commented Jun 14, 2018

Hi @skeith69 did this solve your issue, or did you resolve it yourself somehow...?

I am having the same problem, and this didn't resolve it for me.

@skeeith
Copy link
Author

skeeith commented Jun 15, 2018

@J5Dev yes I resolved the issue myself.

change the SUB-DOMAIN and DOMAIN to what you have.

like for me

test.domain.com (my sub-domain)

and

socket.test.domain.com (my sub-domain for web socket for test.domain.com)

Here it my nginx web socket server block

/etc/nginx/sites-available/socket.test.domain.com server block file

upstream SUB-DOMAIN.websocket {
    server 127.0.0.1:6001;
}

server {
    listen 80;
    listen 443 ssl http2;
    server_name socket.SUB-DOMAIN.DOMAIN.com;

    location /socket.io {
        #add_header 'Access-Control-Allow-Origin' '*' always;
        #add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
        #add_header 'Access-Control-Allow-Credentials' 'true' always;
        #add_header 'Access-Control-Allow-Headers' 'DNT, Authorization, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, Content-Type, Content-Length';

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass https://SUB-DOMAIN.websocket;
    }

    location / {
        proxy_pass https://SUB-DOMAIN.websocket;
    }

    ssl_certificate /etc/letsencrypt/live/socket.SUB-DOMAIN.DOMAIN.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/socket.SUB-DOMAIN.DOMAIN.com/privkey.pem;
}

here is my laravel-echo-server.json file
**NOTE my Redis server has a password. and change the values here to what you have.

{
	"authHost": "https://DOMAIN.com",
	"authEndpoint": "/broadcasting/auth",
	"clients": [
		{
			"appId": "abe8852957c867cf",
			"key": "67c71c1f7b7cbb70fbbeda6f340c2891"
		}
	],
	"database": "redis",
	"databaseConfig": {
		"redis": {
			"port": "6379",
			"host": "127.0.0.1",
			"password": "960c3dac4fa81b4204779fd16ad7c954f95942876b9c4fb1a255667a9dbe389d"
		}
	},
	"devMode": false,
	"host": null,
	"port": "6001",
	"protocol": "https",
	"socketio": {},
	"sslCertPath": "/etc/nginx/ssl/DOMAIN.com.crt",
	"sslKeyPath": "/etc/nginx/ssl/DOMAIN.com.key",
	"sslCertChainPath": "",
	"sslPassphrase": "",
	"apiOriginAllow": {
		"allowCors": true,
		"allowOrigin": "*.*",
		"allowMethods": "GET, POST",
		"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
	}
}

resources/assets/js/bootstrap.js file

import Echo from "laravel-echo";

window.io = require('socket.io-client');

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: 'https://socket.SUB-DOMAIN.DOMAIN.com'
});

then run the laravel-echo-server start in your server or put it in your supervisor for auto start up.

@jonathanpmartins
Copy link

this help me alot! tnks @skeeith

"allowCors": true,
"allowOrigin": "*.*",
"allowMethods": "GET, POST",
"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"

thing you could close the issue

@stierler
Copy link

@jonathanpmartins @skeeith for allowOrigin, it should either be one single URL, or just * (not with extra period and asterisk like you have) according to actual spec for Access-Control-Allow-Origin
See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

I've ran into issues with other applications/services where if providing a incorrect value or multiple values, it would cause it to fail as well.

I'm assuming it hasn't caused any issue for you since it sounds like it's working - but just pointing out since it sent me in a weird loop a while back..

@tlaverdure
Copy link
Owner

Hey there, this issue was opened a while ago. I'm going to close this issue, if this issue still exists, please open a new issue or open a Pull Request.

@bastones
Copy link

bastones commented Dec 15, 2018

Just to provide some clarification as the solution provided isn't very clear, an upstream allows you to define one or more servers to proxy requests through proxy_pass.

As far as I can see, anyone that wants to host the Laravel Echo Server on the same box as Nginx will come across this issue. The solution is to define an upstream that will proxy all requests to /socket.io to the Laravel Echo Server on port 6001.

I wrote an article on my blog about the migration to the Laravel Echo Server (from Pusher) if anyone else is going through the same transition or is interested in reading over it.

TL;DR: Add an upstream server and proxy the requests through it:

upstream websocket {
    server 127.0.0.1:6001;
}

And within the server{} block:

location /socket.io {
    proxy_pass https://websocket;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
}

Your nginx configuration files should be located at /etc/nginx/sites-available/

If you're using Laravel Forge, you can modify the nginx configuration for the affected site(s) within the Forge front-end directly.

@ghost
Copy link

ghost commented Jan 30, 2019

@bastones

Read your article and have tried everything and I can't get this to work in any form.

I always get a 502 Bad Gateway on my Homestead server.

I have it set up exactly as in your blog post.

Need some help.

@ghost
Copy link

ghost commented Jan 30, 2019

I resolved this by specifying the host in the upstream block

upstream websocket {
    server domain.tld:6001;
}

Thanks for the great solution.

@ahusnullin
Copy link

I have the same problem, but everything I've tried doesn't help.
I created a question: https://stackoverflow.com/questions/64428863/websocket-with-laravel-echo-server-502-bad-gateway
Can you help please?

@skeeith
Copy link
Author

skeeith commented Oct 22, 2020

@ahusnullin I replied to your stackoverflow question.

@ahusnullin
Copy link

I don't know what the problem is, but I found a solution.
I've updated a lot: updated Nginx to 1.19.1, possibly installed some additional modules. Installed npm not globally, but locally.
And it worked ...

Attention: this only works if you write location /socket.io.
That was not the point for sure: "authHost": "http://localhost"

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants