And I deployed a Java app called Phantombot which exposes two ports: one for the website on port 25000, and another for a websocket on port 25003… So I configured so the websocket port is 443 and left the website port at 25000, then I defined the following in another docker-compose.yml:
The website successfully works if I refresh multiple times, however ~90% of the time one of the assets of the website won’t load and it will return a 500 error because the protocol “ws” isn’t supported.
Is there any way to expose a service with two different ports? As a side note, the web UI is under /panel so I don’t know if there’s a way to proxy all requests to /panel via the 25000 port, and leave everything else on the websocket port since websocket is just an upgrade from the http request.
As a last question, if I change the protocol to https, how will traefik know which https request goes to what protocol? It seems to me some of the websocket requests may go to the ui.frontend segment while others will go to the websocket one… And yeah, making the ws an https request makes sense – it starts that way anyways then gets upgraded, right?
It's not possible to have 2 segments with the same rule expect if the segments use different entry point (i.e. different ports).
Then you need to change your rules or your entry points.
Unfortunately we’re getting 504 Gateway Timeouts now. Per your docs in Basic - Matchers we see the semicolon as the rule separator for AND and Headers:Connection,upgrade being the matcher, as well as the host that’s responding on, but now the service doesn’t even run. Before at least it will work but some routes may return a 500.
The connection is upgraded after the routing, then you cannot route on that.
Remember that your routing must be based on something related to the client's call, because WS uses HTTP, it's impossible to tell if a call is for the UI or WS.
Thanks for the answer! Adding to your comment though, we are using the Header matcher but we thought since Traefik is a Go application, it should somehow follow the same rules as the Go standard library, unless you guys wrote your own parser for it… In the Go std library, case sensitivity doesn’t really matter on header names. Or are you referring to the fact it could be (u|U)pgrade?
I’ll let mdfc.tech try using the matcher that supports regexps but judging by the speed of regexps in Go, maybe an OR matcher can somehow be used here, so it supports both Connection: Upgrade and Connection: upgrade.
$ curl -vvv 172.18.0.6:25000
* Rebuilt URL to: 172.18.0.6:25000/
* Trying 172.18.0.6...
* TCP_NODELAY set
* Connected to 172.18.0.6 (172.18.0.6) port 25000 (#0)
> GET / HTTP/1.1
> Host: 172.18.0.6:25000
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 02 Jul 2019 21:17:22 GMT
< Content-type: text/html; charset=UTF-8
< Content-length: 6689
<
<!--
# ommitted for brevity
Note the routing works properly, but for some reason traefik fails to connect to it. Yet if we connect via cURL to the dialed endpoint, it works. Do note, however, we have the traefik.docker.network=web label.
I think I found the issue because now it properly works. Since the network is external, reapplying docker-compose up -d doesn’t really let traefik find the appropriate ports and internal IP address, so it was pointing to the initial IP address / port from the first time the container was brought to life, rather than the new one when it was respawned. Doing docker-compose down --rmi=all && docker-compose up -d fixed the issue with the configuration @mdfc put above.
Additionally, I enabled the Web UI. It clearly showed what traefik was reading from the previous configuration, and it was showing the same backend with two different addresses (using our initial configuration from the first post) which was roundrobin’d randomly, that’s why we were seeing some of them hit one, and some of them hit the wrong backend port. In the second case it showed that the IP address detected by traefik didn’t match the new one given by docker (visible by doing docker ps).
Thanks for your help, @ldez. The docs weren’t exactly that clear regarding segments so I’m glad we got your help on that.
but keep getting a handshake error on when invoking wss://cluster06.gbetlds.mgt/autotest01/echo
time="2022-03-29T16:19:11Z" level=error msg="vulcand/oxy/forward/websocket: Error dialing "cluster06.gbetlds.mgt": websocket: bad handshake with resp: 404 404 Not Found"