'How to proxy WebSockets in Traefik?

I'm trying to set up Upsource to work behind Traefik: https://www.jetbrains.com/help/upsource/proxy-configuration.html

traefik is listening to port 8008 and 8443 (since 80/443 will be used for another):

--entryPoints='Name:http Address::8008 Redirect.EntryPoint:https' --entryPoints='Name:https Address::8443 TLS'

docker labels:

labels:
  traefik.backend: upsource
  traefik.enable: "true"
  traefik.port: "8080"
  traefik.frontend.rule: "Host:review.domain.com"

In conf/internal/bundle.properties, base-url is configured as follow:

base-url=https\://review.domain.com\:8443/

problem:

time="2017-09-20T03:23:59Z" level=error msg="Error getting ACME certificates [review.domain.com] : Cannot obtain certificates map[review.domain.com:acme: Error 400 - urn:acme:error:connection - Connection refused
Error Detail:
        Validation for review.domain.com:443

Why it validate for port 443 instead of 8443?

Moreover, to proxy WebSockets in Nginx:

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://upsourcemachine.domain.local:1111;
        proxy_pass_header Sec-Websocket-Extensions;

Can you confirm that Traefik support WebSockets? And if so, how to configure?



Solution 1:[1]

Traefik handle websocket, and you don't need any specific configuration for this.

Your problem seems to be more about the challenge in Let's Encrypt. Let's Encrypt doesn't handle TLS Challenge on other port than the default one and the default challenging in Traefik is TLS :(

So you need to configure Traefik to use DNS Challenge https://docs.traefik.io/configuration/acme/

Solution 2:[2]

Worked example for confluence

version: '3.3'

networks:
  traefik:
    external: true

volumes:
  portainer_data:
  confluence:

services:
  traefik:
    image: traefik:1.7.9-alpine
    command: >
      --docker
      --docker.swarmmode
      --docker.watch
      --docker.exposedbydefault=true
      --docker.domain=example.com
      --defaultentrypoints=http,https,ws,wss
      --entrypoints='Name:http Address::80'
      --entrypoints='Name:https Address::443 TLS'
      --acme
      --acme.email='[email protected]'
      --acme.storage='/certs/acme.json'
      --acme.entryPoint=https
      --acme.httpChallenge.entryPoint=http
      --acme.onhostrule=true
      --acme.acmelogging=true
      --logLevel=INFO
      --accessLog
      --api
    ports:
      - 80:80
      - 443:443
    networks:
      - manager
      - traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /certs:/certs
    deploy:
      mode: global
      labels:
        - traefik.enable=true
        - traefik.port=8080
        - traefik.frontend.rule=Host:traefik.example.com
        - traefik.docker.network=traefik
        #- traefik.redirectorservice.frontend.entryPoints=http
        #- traefik.redirectorservice.frontend.redirect.entryPoint=https
        - traefik.webservice.frontend.entryPoints=http,https
  portainer:
    image: portainer/portainer:1.20.1
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    networks:
      - manager
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    deploy:
      placement:
        constraints: [node.role == manager]
      labels:
        - traefik.enable=true
        - traefik.port=9000
        - traefik.frontend.rule=Host:portainer.example.com
        - traefik.docker.network=traefik
        #- traefik.redirectorservice.frontend.entryPoints=http
        #- traefik.redirectorservice.frontend.redirect.entryPoint=https
        - traefik.webservice.frontend.entryPoints=http,https
  agent:
    image: portainer/agent:1.2.1
    environment:
      AGENT_CLUSTER_ADDR: tasks.agent
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - manager
    deploy:
      mode: global
  confluence:
    image: cptactionhank/atlassian-confluence:6.3.4
    networks:
      - traefik
    volumes:
      - confluence:/var/atlassian/confluence
    deploy:
      replicas: 1
      labels:
        - traefik.enable=true
        - traefik.port=8090
        - traefik.frontend.rule=Host:confluence.example.com
        - traefik.docker.network=traefik
        # - traefik.redirectorservice.frontend.entryPoints=http
        # - traefik.redirectorservice.frontend.redirect.entryPoint=https
        - traefik.webservice.frontend.entryPoints=http,https,ws,wss

Solution 3:[3]

An example for Kubernetes:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: server-route
spec:
  entryPoints:
    # Defined in the traefik configuration, e.g.
    # --entrypoints.websecure.address=:8888
    - websecure
  routes:
    - match: PathPrefix(`/`)
      middlewares:
        - name: server-headers
      kind: Rule
      services:
        - name: server
          port: portname
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: server-headers
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Proto: "https"

You must use Traefik's custom IngressRoute object instead of a normal Ingress.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Julien SALLEYRON
Solution 2 vitams
Solution 3 Hugo O. Rivera