Configure NGINX reverse proxy with browser WebSocket and docker-compose

大兔子大兔子 提交于 2021-02-08 08:20:34

问题


I am trying to get nginx to proxy a websocket connection to a backend server. All services linked via docker-compose.

When i create the WebSocket object in my frontend react app:

let socket = new WebSocket(`ws://engine/socket`)

I get the following error:

WebSocket connection to 'ws://engine/socket' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED

I believe the problem comes from converting ws:// to http:// and that my nginx configuration does not seem to be pick up the match location correctly.

Here is my nginx configuration:

server {
    # listen on port 80
    listen 80;

    root   /usr/share/nginx/html;
    index  index.html index.htm;

    location ^~ /engine {
      proxy_pass http://matching-engine:8081/;
      proxy_http_version 1.1;
      proxy_redirect     off;
      proxy_set_header Host $host;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }

    # Media: images, icons, video, audio, HTC
    location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
      expires 1M;
      access_log off;
      add_header Cache-Control "public";
    }

    # Javascript and CSS files
    location ~* \.(?:css|js)$ {
        try_files $uri =404;
        expires 1y;
        access_log off;
        add_header Cache-Control "public";
    }

    # Any route containing a file extension (e.g. /devicesfile.js)
    location ~ ^.+\..+$ {
        try_files $uri =404;
    }
}

Here is part of my docker-compose configuration:

  matching-engine:
    image: amp-engine
    ports:
      - "8081:8081"
    depends_on:
      - mongodb
      - rabbitmq
      - redis
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
        window: 120s

  client:
    image: amp-client:latest
    container_name: "client"
    ports:
      - "80:80"
    depends_on:
      - matching-engine
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
        window: 120s

docker-compose resolves the 'matching-engine' automatically (i can make normal http get/post requests that nginx resolves correctly, and nslookup finds the matching-engine correctly, so i believe the basic networking is working correctly for HTTP requests which leads me to think that the problem comes from the match location in the nginx configuration.

How can one pick up a request that originates from `new WebSocket('ws://engine/socket') in a location directive. I have tried the following ones:

  • location ^~ engine
  • location /engine
  • location /engine/socket
  • location ws://engine

without any success.

I have also tried changing new Websocket('ws://engine/socket') to new Websocket('/engine/socket') but this fails (only ws:// or wss:// prefixes are accepted)

What's the way to make this configuration work ?


回答1:


As you are already exposing port 80 of your client container to your host via docker-compose, you could just connect to your websocket-proxy via localhost:

new Websocket('ws://localhost:80/engine')


来源:https://stackoverflow.com/questions/52757997/configure-nginx-reverse-proxy-with-browser-websocket-and-docker-compose

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!