You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:同一Docker容器通过Traefik配置HTTPS与WSS同域名访问

解决方案

核心问题分析

  1. Traefik未暴露WSS入口端口:你在traefik.toml里定义了:8000的WSS入口点,但Traefik容器的ports配置里没有映射这个端口到宿主机,外部无法访问。
  2. 路由与服务类型不匹配:WSS属于HTTP协议的升级,应该使用http类型的路由和服务,而非tcp类型(除非处理纯TCP的WebSocket,但WSS是带TLS的WebSocket,基于HTTP协议)。
  3. ACME服务器版本过时:你使用的acme-v01.api.letsencrypt.org已被废弃,需切换到v02版本。
  4. WSS路由未关联TLS与入口点:注释掉的TLS配置未启用,导致WSS连接无法通过加密通道建立。

修正后的完整配置

1. Traefik Docker-Compose配置

version: '3'

services:
  reverse-proxy:
    image: traefik:v2.7.1
    container_name: traefik
    ports:
      - "80:80"
      - "443:443"
      # 如果坚持用独立的8000端口做WSS,需添加以下映射,否则可省略,用443统一处理
      # - "8000:8000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - $PWD/traefik.toml:/etc/traefik/traefik.toml
      - $PWD/acme.json:/acme.json
    restart: always
    networks:
      - web
networks:
  web:
    external: true

2. Traefik.toml配置

[accessLog]
[api]
  dashboard = true
  insecure = true
[log]
  level = 'ERROR'
[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http]
      [entryPoints.web.http.redirections]
        [entryPoints.web.http.redirections.entryPoint]
          to = "websecure"
          scheme = "https"
          permanent = true

  [entryPoints.websecure]
    address = ":443"
    [entryPoints.websecure.http.tls]
      certResolver = "default"
  # 若不需要独立端口,可删除以下WSS入口点配置,用websecure统一处理
  # [entryPoints.wss]
  #   address = ":8000"
  #   [entryPoints.wss.http.tls]
  #     certResolver = "default"

[providers]
  [providers.docker]
    watch = true
    exposedByDefault = false
    network = "web"

[certificatesResolvers]
  [certificatesResolvers.default]
    [certificatesResolvers.default.acme]
      email = "contact@queel.io"
      storage = "acme.json"
      # 切换到v02版本的ACME服务器
      caServer = "https://acme-v02.api.letsencrypt.org/directory"
    [certificatesResolvers.default.acme.tlsChallenge]

3. Node容器Docker-Compose配置

node:
  build: ./docker/node_api
  volumes:
    - ./node:/src
  tty: true
  networks:
    - web
  # 容器内部端口无需映射到宿主机,由Traefik负责转发
  # ports:
  #   - ":8000"
  #   - ":8081"
  labels:
    - "traefik.docker.network=web"
    - "traefik.enable=true"

    # HTTPS API路由配置
    - "traefik.http.routers.node.rule=Host(`api.${HOST}`)"
    - "traefik.http.routers.node.entrypoints=websecure"
    - "traefik.http.routers.node.tls=true"
    - "traefik.http.routers.node.tls.certResolver=default"
    - "traefik.http.services.node.loadbalancer.server.port=8000"

    # WSS路由配置(使用同一websecure入口点,通过Host区分)
    - "traefik.http.routers.wss.rule=Host(`ws.${HOST}`)"
    - "traefik.http.routers.wss.entrypoints=websecure"
    - "traefik.http.routers.wss.tls=true"
    - "traefik.http.routers.wss.tls.certResolver=default"
    # Traefik会自动处理WebSocket升级,无需额外中间件
    - "traefik.http.services.wss.loadbalancer.server.port=8081"

    # 若坚持用独立的8000入口点,替换上方WSS的entrypoints为wss即可
    # - "traefik.http.routers.wss.entrypoints=wss"

    - "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
  depends_on:
    - elastic
    - neo
  working_dir: /src

关键配置说明

  1. 端口简化:无需给Node容器映射宿主机端口,Traefik通过Docker内部网络直接转发请求,更安全且避免端口冲突。
  2. WSS路由优化:直接复用websecure(443端口)入口点,通过Host(ws.${HOST})区分WSS请求,Traefik会自动处理WebSocket协议升级。
  3. ACME服务器更新:切换到v02版本确保证书正常签发。
  4. TLS强制启用:给WSS路由明确开启tls=true,保证连接加密(WSS本质就是WebSocket over TLS)。

内容的提问来源于stack exchange,提问作者user2626210

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 20:55:22