Traefik 2.2 + Docker + Websocket (ws) not working - docker

I'ved managed to get it Traefik working for http containers but when I switched to websocket, had no luck. Traefik is pretty easy. Let me share it's docker-compose file:
version: "3.3"
services:
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
# - "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entryPoints.ws.address=:81" #I ADDED THIS
- "--accesslog"
ports:
- "80:80"
- "81:81" #I ADDED THIS
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
To make it easier, I added and comment like #I ADDED THIS so you can see the changes I've made to make WS work.
Now on the actual project docker-compose I've added this labels:
version: '2.1'
services:
test:
restart: unless-stopped
hostname: test
build:
context: .
dockerfile: ./Dockerfile
expose:
- 81
labels:
- "traefik.enable=true"
- "traefik.http.routers.test.rule=Host(`test.com`)"
- "traefik.http.routers.test.entrypoints=ws"
- "traefik.http.services.test.loadBalancer.sticky.cookie=true"
And I'm trying to connect using Nodejs:
var ws = new WebSocket('ws://test.com:81')
Dont know what else to try.
Thank you in advanced.
EDIT Saw in traefik log:
time="2020-08-23T16:07:28Z" level=debug msg="vulcand/oxy/roundrobin/rr: completed ServeHttp on request" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"\",\"Fragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Connection\":[\"Upgrade\"],\"Sec-Websocket-Extensions\":[\"permessage-deflate; client_max_window_bits\"],\"Sec-Websocket-Key\":[\"jaXhUWe2lvrgxF0tOn3nWA==\"],\"Sec-Websocket-Version\":[\"13\"],\"Upgrade\":[\"websocket\"],\"X-Forwarded-Host\":[\"test.com:81\"],\"X-Forwarded-Port\":[\"81\"],\"X-Forwarded-Proto\":[\"ws\"],\"X-Forwarded-Server\":[\"58077bdceffd\"],\"X-Real-Ip\":[\"192.168.99.1\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"test.com:81\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.99.1:56705\",\"RequestURI\":\"/\",\"TLS\":null}"
192.168.99.1 - - [23/Aug/2020:16:07:07 +0000] "GET / HTTP/1.1" 499 21 "-" "-" 56 "test#docker" "http://172.19.0.2:81" 21082ms
Looks right, but still no communication between client/server.

I think you need to add service port to your test container:
- "traefik.http.services.test.loadbalancer.server.port=81"
edit:
for traefik to be able to discover your service, it needs to be on same network. so best solution seems to define external network for both services or use the one defined with your websocket service

Related

traefik docker basic exemple return 404

I'm starting to use treafix but I facing a wall. I'm trying to start with the basic docker example provided here : https://doc.traefik.io/traefik/user-guides/docker-compose/basic-example/
version: "3.8"
services:
traefik:
image: "traefik:v2.3"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--accessLog"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.rule=Host('server.local')"
As I'm local, I've set up "server.local" in my hostfile to point to 127.0.0.1
However, when I run it with compose and try to access my server.local I only got a 404, not the whoami expected response. I don't see anything that jump to me as wrong within the logs but again, I'm starting in, the traefik area.
I'm using docker desktop on windows wityh WSL2 and running the compose inside an ubuntu WSL2 vm
I found my issue :
In the traefik rule, you should only use backtick (`) and not a single quote (') to define string litteral
so my :
- "traefik.http.routers.whoami.rule=Host('server.local')"
should be
- "traefik.http.routers.whoami.rule=Host(`server.local`)"
I wished the traefik documentation made this much more clear, especially in the default exemples ...

Traefik 2.0 and docker simple configuration doesnt work

I'm following some tutorial link_to_tutorial about traefik 2.0 and docker, and I have docker-compose file which starts up two containers: traefik and my-app. The problem is when containers up and running, I am not able to browse to localhost:8082, as suggested by configuration, I always get "unable to connect" in browser.
docker-compose.yml :
version: "3.3"
services:
traefik:
image: "traefik:v2.0.1"
command:
- --entrypoints.web.address=:80
- --providers.docker
- --api.insecure
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
my-app:
image: containous/whoami:v1.3.0
command:
# It tells whoami to start listening on 8082 instead of 80
- --port=8082
labels:
- "traefik.http.routers.my-app.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.services.my-app.loadbalancer.server.port=8082"
However I am able to get localhost:8080 and traefik UI works well. As I understand all requests to "traefik" container normally should be redirected to "my-app":8082 container but it somehow fails. Help heeded.Thanks.
"traefik.http.routers.my-app.rule=Host(localhost,127.0.0.1)"

How to map specific port inside docker container when using traefik?

Here's my docker-compose.yml:
version: '3'
services:
website:
build: ./website
expose: [3000]
labels:
- "traefik.frontend.rule=Host:localhost"
blog:
build: ./blog
expose: [4000]
labels:
- "traefik.frontend.rule=Host:localhost;PathPrefix:/blog"
docs:
build: ./docs
expose: [3000]
labels:
- "traefik.frontend.rule=Host:localhost;PathPrefix:/docs"
proxy:
image: traefik
command: --api.insecure=true --providers.docker
networks:
- webgateway
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
webgateway:
driver: bridge
What I want is access three different node.js websites via different routes. But these three node.js websites actually expose different ports. Now my treafik is running. I can config via localhost:8080 But localhost localhost/blog and localhost/docs are all 404 page not found
P.S: I'm not sure whether port is the issue I should investigate, because changing one node.js service to port 80 doesn't solve the puzzle. And I saw on traefik dashboard the rule is Host(blog-dev)
PathPrefix:/blog
When you have this as a routing rule, traefix won't automatically remove the prefix when sending to the container.
So unless you have a route /blog inside your container you will get a 404.
So what you normally do is also add a middleware to strip this ->
https://docs.traefik.io/middlewares/stripprefix/
Also you appear not to be setting your rules based on your service.
So as an example for your first service blog,
try->
labels:
- "traefik.http.routers.blog.rule=Host(`localhost`) && PathPrefix(`/blog`)"
- "traefik.http.routers.blog.middlewares=strip-blog"
- "traefik.http.middlewares.strip-blog.stripprefix.prefixes=/blog"
And then do the same for your other routes, don't forget to replace routers.blog with routers.docs etc..
labels:
- traefik.http.services.<YOUR-SERVICE-NAME>.loadbalancer.server.port=9763
EG:
services:
wso:
image: "my-custom-wso-image"
volumes:
- .....
labels:
- "traefik.enable=true"
- "traefik.http.routers.wso.tls=true"
- "traefik.http.routers.wso.rule=Host(`my.nice.url`)"
- "traefik.http.services.wso.loadbalancer.server.port=9763" #<-----
Thanks to #Keith I found the solution
version: '3'
services:
website:
build: ./website
expose: [3000]
networks: # It's essential to specify the same network in every service
- webgateway
labels:
- "traefik.http.routers.website.rule=Host(`localhost`)" # Use the right format
- "traefik.port=3000" # Let traefik find the right port
blog:
build: ./blog
expose: [4000]
networks:
- webgateway
labels:
- "traefik.http.routers.blog.rule=Host(`localhost`) && PathPrefix(`/blog`)" # blog has a root as `/blog` so no need to strip otherwise too many redirects
- "traefik.port=4000"
docs:
build: ./docs
expose: [3000]
networks:
- webgateway
labels:
- "traefik.http.routers.docs.rule=Host(`localhost`) && PathPrefix(`/docs`)"
- "traefik.http.routers.docs.middlewares=strip-docs" # Necessary as Keith mentioned
- "traefik.http.middlewares.strip-docs.stripprefix.prefixes=/docs"
- "traefik.port=3000"
proxy:
image: traefik
command: --api.insecure=true --providers.docker
networks:
- webgateway
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
webgateway:
driver: bridge

Traefik configuration inside docker-compose with subdomains

I try to setup subdomains configuration using traefik but is doesn't work. This is my docker-compose config :
traefik:
image: "traefik:v2.0.0-rc3"
container_name: "traefik"
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8282:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "containous/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
#- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.frontend.port=80"
- "traefik.frontend.rule=Host:whoami.mydomain.com"
When I replace the host by mydomain.com/whoami it does works correctly. I also tried to add the subdomain to /etc/hosts file but nothing changes when I go to whoami.mydomain.com nothing appears.
Do you have suggestions ?
Thanks.
I'm not an expert with Docker or Traefik, but I have been doing some work in that regard. The only thing I see that looks a bit weird to be is that you may want to throw a common network option on both to ensure they are sharing, such as:
networks:
- web
The only other guess would be if you are missing the DNS entry for whoami.yourdomain.com
For the record,
If append the following content to my /etc/hosts:
127.0.0.1 whoami.mydomain.com
the following snippet works on my machine:
version: '3'
services:
traefik:
image: "traefik:v2.5"
container_name: "traefik"
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8282:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "containous/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
An yours with traefik:2.5 answers with a 404 not found on my machine.
Note: the port 8282 on my machine gives nothing (which is normal as nothing is listening in port 8080 in the container).

Traefik and Docker Compose returns a Bad Gateway for application route

I am trying to setup Traefik with a test app on a non-standard port.
IIS is currently using port 80 on my machine so I am using port 9000 for my test app.
I keep getting back Bad Gateway.
The test application is an empty .net core application with a welcome page
From the Bad Gateway response I assume that Traefik is not routing the request correctly or that the container is not picking up the request.
I have tried numerous traefik labels and cannot still get the request to oute correctly.
I can access the Traefik dashboard on docker.localhost:8080
But if I access my app on webapp3.localhost:9000 I get a "Bad Request"
docker-compose.yml
version: '3.4'
services:
webapp3:
container_name: webapp3
image: ${DOCKER_REGISTRY-}webapp3
build:
context: .
dockerfile: WebApp3/Dockerfile
networks:
- web
labels:
- "traefik.backend=webapp3"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:webapp3.localhost"
- "traefik.port=80"
traefik:
container_name: traefik
image: traefik
command: --api --docker --logLevel=DEBUG
restart: always
ports:
- "443:443"
- "9000:80"
- "8080:8080"
volumes:
- ./docker/traefik:/etc/traefik/
- /var/run/docker.sock:/var/run/docker.sock:ro
- /dev/null:/traefik.toml
networks:
- web
labels:
- "traefik.enable=true"
- "traefik.backend=traefik"
- "traefik.frontend.rule=Host:docker.localhost"
- "traefik.port=8080"
- "traefik.docker.network=web"
networks:
web:
external : true
docker-compose.override.yml
version: '3.4'
services:
webapp3:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80;http://+:9000
volumes:
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

Resources