'Websockets request fails with nginx-proxy for docker with ssl
I'm using nginx-proxy as a reverse proxy for my containers in a web server. I have a Laravel backend application with a Vue frontend and they communicate via Websockets using Laravel Websockets.
The communication works fine locally between the backend and frontend containers via HTTP but I'm having trouble using it in a web server via HTTPS.
I use acme-companion to generate and renew Let's encrypt certificates. The /etc/nginx/conf.d/default.conf
file is edited following these instructions from Laravel Websockets for usage with nginx reverse proxy.
In the front end, I'm calling the WebSocket server wss://api.domain.com
. As I understand, this would reach my location @ws
and be proxied to the api
container (copied the IP from the upstream) in port 6001 which is were my WebSocket server listens to. The problem is that no request are reaching the WebSocket server. I reloaded Nginx config after editing with nginx -s reload
Can someone help me? I can't seem to understand what I'm doing wrong or how to debug this properly as /var/log/nginx/access.log
and /var/log/nginx/error.log
inside the nginx-proxy
container are empty. Thank you.
docker-compose.yml
version: '2'
services:
nginx-proxy:
container_name: nginx-proxy
image: jwilder/nginx-proxy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- "/etc/nginx/vhost.d"
- "/usr/share/nginx/html"
- "/var/run/docker.sock:/tmp/docker.sock:ro"
- "/etc/nginx/certs"
letsencrypt-nginx-proxy-companion:
container_name: letsencrypt-nginx-proxy-companion
image: jrcs/letsencrypt-nginx-proxy-companion
restart: always
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
volumes_from:
- "nginx-proxy"
api:
container_name: api
image: guizo/docker-laravel:php8.0-apache-postgres
ports:
- 6001:6001
working_dir: /var/www/html
volumes:
- ./api:/var/www/html
volumes_from:
- "nginx-proxy"
environment:
VIRTUAL_HOST: api.domain.com
LETSENCRYPT_HOST: api.domain.com
app:
container_name: app
image: guizo/docker-nginx
working_dir: /usr/share/nginx/html
volumes:
- ./app/dist:/usr/share/nginx/html
environment:
VIRTUAL_HOST: app.domain.com
LETSENCRYPT_HOST: app.domain.com
/etc/nginx/conf.d/default.conf
map $http_upgrade $type {
default "web";
websocket "ws";
}
# api.domain.com
upstream api.domain.com-upstream {
## Can be connected with "dev_default" network
# api
server 172.18.0.4:80;
# Fallback entry
server 127.0.0.1 down;
}
server {
server_name api.domain.com;
listen 80 ;
access_log /var/log/nginx/access.log vhost;
# Do not HTTPS redirect Let'sEncrypt ACME challenge
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
auth_request off;
allow all;
root /usr/share/nginx/html;
try_files $uri =404;
break;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name api.domain.com;
listen 443 ssl http2 ;
access_log /var/log/nginx/access.log vhost;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_certificate /etc/nginx/certs/api.domain.com.crt;
ssl_certificate_key /etc/nginx/certs/api.domain.com.key;
ssl_dhparam /etc/nginx/certs/api.domain.com.dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/certs/api.domain.com.chain.pem;
add_header Strict-Transport-Security "max-age=31536000" always;
include /etc/nginx/vhost.d/default;
location / {
try_files /nonexistent @$type;
}
location @web {
proxy_pass http://api.domain.com-upstream;
}
location @ws {
proxy_pass http://172.18.0.4:6001;
proxy_set_header Host $host;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
# Allow the use of websockets
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;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|