通过 nginx 或 traefik 通过 html 网页访问 docker 容器 websocket?

Posted

技术标签:

【中文标题】通过 nginx 或 traefik 通过 html 网页访问 docker 容器 websocket?【英文标题】:Accessing docker container websocket through nginx or traefik via html web page? 【发布时间】:2020-02-12 07:19:10 【问题描述】:

我有两个 docker 容器正在运行——一个有一个 websocket,另一个是一个 nginx 容器。使用docker-compose.yml 设置如下:

version: "3.5"

  websocket: 
    build:
      context: .
      dockerfile: Dockerfile
    ports: 
      - "6000:7000"

  nginx:
    image: nginx:alpine
    restart: always
    ports:
      - "120:80"

在我的 nginx 容器中的 index.html 中,我目前必须设置 socketUrl: "http://192.168.X.X:6000",i.e. websocket 容器的本地 IP 地址。

有没有办法设置 nginx 以便socketUrl: "http://websocket:7000"?使用nginx还是traefik?

如果我在不同的机器上运行,我必须为新机器手动编辑socketUrl。我希望设置是跨机器的标准设置,以便我可以通过http://192.168.X.X:120的html访问websocket@

【问题讨论】:

【参考方案1】:

使用链接通过主机名访问另一个容器:

version: "3.5"

services:
  websocket: 
    build:
      context: .
      dockerfile: Dockerfile
    container_name: websocket
    ports: 
      - "6000:7000"

  nginx:
    image: dperson/nginx
    container_name: nginx
    ports:
      - "120:80"
    environment:
      - STREAM=0.0.0.0:80;websocket:7000
    links:
      - websocket

如果这不起作用,强制他们在同一个网络上:

version: "3.5"

services:
  websocket: 
    build:
      context: .
      dockerfile: Dockerfile
    container_name: websocket
    ports: 
      - "6000:7000"
    networks:
      - default

  nginx:
    image: dperson/nginx
    container_name: nginx
    ports:
      - "120:80"
    environment:
      - STREAM=0.0.0.0:80;websocket:7000
    links:
      - websocket
    networks:
      - default

networks:
  default:

【讨论】:

刚刚尝试了这些选项,但都不起作用。当我打开浏览器时,没有连接到 websocket。我在index.html 中输入了http://websocket:7000,对吗? 哦,不是这样的。只有 nginx 容器知道 websocket 主机名,而不是请求 index.html 的远程客户端。这就是为什么您必须通过反向 nginx/traefik http 代理(或像我的示例中的流)在内部路由远程请求的原因,您能更具体地了解您想要实现的目标吗? 我怀疑这不是正确的方法。我正在尝试通过 index.html 向/从 websocket 服务器(托管在容器中)发送消息。系统通过添加 "localhost:6000" 与主机上的浏览器一起工作。当涉及到代理时,我被卡住了。 websocket 端口必须可以从请求 index.html 的远程客户端访问(公共端口 6000)。因此,只需公开端口并使用 javascript 的 location.hostname 伪造 url,因为远程 websocket 主机名(托管这些容器的机器)将与 nginx 容器中的相同。如果你想保持 websocket 私有,你必须通过后端来路由它,比如 php

以上是关于通过 nginx 或 traefik 通过 html 网页访问 docker 容器 websocket?的主要内容,如果未能解决你的问题,请参考以下文章

利用Traefik+Docker构建可弹性扩展的微服务或服务集群

Traefik无法通过docker-compose连接到服务器。

是否可以使用 Traefik 通过 SSL 代理 PostgreSQL?

使用 Traefik 时如何使用 Nginx 和 Django Gunicorn 提供静态内容

确实,k8s的时代,ingress负载用traefik比nginx方便啊

Traefik:无法使用摘要身份验证登录服务