• If you are still using CentOS 7.9, it's time to convert to Alma 8 with the free centos2alma tool by Plesk or Plesk Migrator. Please let us know your experiences or concerns in this thread:
    CentOS2Alma discussion

Resolved Websocket Error 400, Docker & nginx

TarZug

New Pleskian
I have a docker app on latest Plesk Onyx running (mattermost) and it works perfectly when opened directly through server IP and Docker mapped port (192.168.0.5:33000) Everything works great.

The problem is when I try to make it work through NGINX proxy. If select a domain and set Docker Proxy Rules for the app, it works until a websocket connection is requred. In this moment I get the following error:

WebSocket connection to 'wss://chat.spntt.com/api/v3/users/websocket' failed: Error during WebSocket handshake: Unexpected response code: 400

And this repeats for every request. I tried adding additional nginx rules as below but is still does not work.

ocation /api/v3/ {
proxy_pass http://0.0.0.0:33000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}

I have disabled proxy mode even in the apache&nginx settings. What else can I do?
 
location /api/v3/ {
proxy_pass http://192.168.0.5:33000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}

I tried it all, docker ip, mapped ip... it just makes no difference
 
But have you tried to check that port is available for connection with telnet, at least?
 
I can telnet to 192.168.0.5:33000 and using

GET / HTTP/1.1
HOST: HOSTNAME

and I get the page in plain text on the console, if I use the page through 192.168.0.5:33000 I get the full functionality, eveything works. I am missing something in nginx setup, to get the websocket part of it working when used through the proxied domain.
 
This is supposed to work as from:
mattermost-nginx/mattermost at master · mstrpupt2/mattermost-nginx · GitHub


map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
server {
listen 80;
location / {
gzip off;
client_max_body_size 50M;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://app:APP_PORT;
}
}


How can I apply this in plesk?
 
I removed the docker proxy rules for the domain completely. As I can not add map in the additional nginx directives, I just removed the line:

proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;

So it reads out now as below (just to test):

location / {
gzip off;
client_max_body_size 50M;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://192.168.0.5:33000;
}

Now websockets work great, no errors anymore, I can almost use it now.

What I have now are following errors - which prevent it from working correctly:
GET http://chat.spntt.com/api/v3/teams/6zf7npa91fbz7cm7kbm53yhuge/channels/ 404 (Not Found)
 
OK, if I put only the following everything except for web sockets works.

location ~ ^/.* {
proxy_pass http://192.168.0.5:33000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


If I put only the following websocket works, but there are a lot of other errors:

location / {
gzip off;
client_max_body_size 50M;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://192.168.0.5:33000;
}


Now the obvious question is, that I need to combine the two, and everything will work, as each makes one part to work. Just putting both in the additional nginx directives does not fix it, I still get web socket errors.
 
Ok, I fxed it by using this in additinal nginx directives, after turning on he docker proxy rule:

location ^~ /api/v3/users/websocket {

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_pass http://192.168.0.5:33000;
}


THe problem was ^~ which I had to add at the location line
 
My Solution was primary to disabled/remove the Plesk Docker Proxy. If there is a rule enabled, Plesk will add a "location ~ ^/.*" rule to the nginx.conf, which does NOT handle SSL WebSocket-Connection! This location will take ALL requests before it will arrive to a custom vhost_nginx.conf (under domain > hosting > custom nginx-rules) rule to enable the SSL WebSocket.

So - just disable the Plesk Docker Proxy Rule(s) and add them manually in the additional hosting rules for nginx this way and add two lines to enable SSL WebSockets:

Code:
location ~ ^/.* {
    proxy_pass http://0.0.0.0:{PORT_TO_YOUR_DOCKER_CONTAINER_APP};
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;   // > add this is for websockets
    proxy_set_header Connection "upgrade";    // > add this is for websockets
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}
 
Thank you, @Matthias, I really didn't expect that it gonna work, but it worked very well. I really wonder why Plesk doesn't do this automatically.
 
Back
Top