Traefik websocket secure ( wss ) and https on the same domain with docker - docker

I struggled on this for at least the last day and didn't found a solution. I want to connect Websocket and https on the same docker. I have tried many thing.
Here is my configuration:
Traefik V2 first :
here is the docker container
version: '3'
services:
reverse-proxy:
image: traefik:v2.7.1
container_name: traefik
ports:
- "80:80"
- "443:443"
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:
name: web
~
here is my toml file
[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"
[entryPoints.wss]
address = ":8000"
[providers]
[providers.docker]
watch = true
exposedByDefault = false
network = "web"
[certificatesResolvers]
[certificatesResolvers.default]
[certificatesResolvers.default.acme]
email = "contact#queel.io"
storage = "acme.json"
caServer = "https://acme-v01.api.letsencrypt.org/directory"
[certificatesResolvers.default.acme.tlsChallenge]
I want to connect on https and wss on the same node container exposing two ports
here is my docker-compose for this
node:
build: ./docker/node_api
volumes:
- ./node:/src
tty: true
networks:
- web
ports:
- ":8000"
- ":8081"
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.http.routers.node.rule=Host(`api.${HOST}`)"
- "traefik.http.routers.node.entrypoints=websecure"
- "traefik.tcp.services.node.loadbalancer.server.port=8000"
- "traefik.http.routers.wss.rule=Host(`ws.${HOST}`)"
- "traefik.tcp.services.wss.loadbalancer.server.port=8081"
#- "traefik.http.services.wss.loadBalancer.sticky.cookie=true"
# - "traefik.http.routers.wss.tls=true"
#- "traefik.http.routers.wss.tls.certResolver=default"
#- "traefik.http.routers.wss.entrypoints=wss"
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=https"
#- "traefik.http.routers.wss.tls.certresolver=default"
depends_on:
- elastic
- neo
working_dir: /src
Has you can see I tried many solutions, but none is working, maybe you should help me find the combination of the goog ones. It seems has I have seen elsewhere that the X-Forwarded-Proto is the solution. For new the wss connection is not working
Could you help me with that

The anwser is quite simple, my socket server was not started. The config stay the same for the main part and I have only to have :
- "traefik.http.routers.wss.rule=Host(`ws.${HOST}`)"
- "traefik.tcp.services.wss.loadbalancer.server.port=8081"
- "traefik.http.routers.wss.entrypoints=websecure"
entrypoint=websecure is enought for wss since it's over http.
I didn't manage to use the two service in a single container so i swapped the container in two container.

Related

Traefic docker container reverse-proxy redirect fails to ports provided by other containers: Gateway timeout

Setup: I have a variety of native applications and docker applications on a nas device.
(simplistic example).
host
: 8080 (console)
: 81 (apache)
: <port> and more (individual nas applications)
- container:traefik
:80
- container:nginx
:90
- container:customcode
:4000
- and more (individual applications)
:<port>
(host is 192.168.1.22).
**All containers and applications work and are reachable via 'http://192.168.1.22:<port>'
I was attempting to use traefik with simplistic names to manage the ports.
i.e.
'apache' redirect to http://192.168.1.22:81 (host exposed) - works
'nas' redirect to http://192.168.1.22:8080 (host exposed) - works
'nginx' redirect to http://192.168.1.22:90 (container exposed) -
fails
The traefik setup is able to redirect to all ports on the host itself, but none of the ports exposed by docker. This works for sites on different hosts as well. for ports exposed by containers I get a 'Gateway timeout' error
(only Log file entry: "'504 Gateway Timeout' caused by: dial tcp 192.168.1.22:90: i/o timeout").
I cannot use labels on the containers as they don't (and some cannot) share networks. I just want traefik to route to the IP:Port without worrying about if the port is provided by a container or not.
traefik.toml
loglevel = "ERROR"
[Log]
filePath = "/etc/traefik/traefik.log"
level = "DEBUG"
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[api]
dashboard = true
[providers.docker]
watch = false
exposedByDefault = false
endpoint = "unix:///var/run/docker.sock"
[providers.file]
watch = true
filename = "/etc/traefik/services.toml"
services.toml
[http]
[http.services]
[http.services.nas]
[http.services.nas.loadBalancer]
[[http.services.nas.loadBalancer.servers]]
url = "http://192.168.1.22:8080/"
[http.services.test90]
[http.services.test90.loadBalancer]
[[http.services.test90.loadBalancer.servers]]
url = "http://192.168.1.22:90/" #this does not work#
[http.services.test81]
[http.services.test81.loadBalancer]
[[http.services.test81.loadBalancer.servers]]
url = "http://192.168.1.22:81/"
docker compose:
version: "3.5"
services:
traefik:
image: "traefik:2.4"
container_name: "traefik"
restart: always
environment:
- PUID=<id>
- PGID=<id>
ports:
- "443:443"
- "80:80"
volumes:
- "/shr/traefik/:/etc/traefik/"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik`)"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.entrypoints=http,https"
- "traefik.http.routers.traefik.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:<pass>"
- "traefik.http.routers.nas.entrypoints=http"
- "traefik.http.routers.nas.rule=Host(`nas`)"
- "traefik.http.routers.nas.service=nas#file"
- "traefik.http.routers.test81.entrypoints=http"
- "traefik.http.routers.test81.rule=Host(`apache`)"
- "traefik.http.routers.test81.service=test81#file"
- "traefik.http.routers.test90.entrypoints=http"
- "traefik.http.routers.test90.rule=Host(`nginx`)"
- "traefik.http.routers.test90.service=test90#file"
networks:
- proxy
whoami:
image: "traefik/whoami"
container_name: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami`)"
- "traefik.http.routers.whoami.entrypoints=http"
networks:
- proxy
networks:
proxy:
external:
name: proxy
You might need to assing the correct traefik network in the application that causes the problem:
In the docker-compose.yml:
labels:
[...]
- "traefik.enable=true"
- "traefik.docker.network=foobar"
[...]
Where "foobar" is the docker network that traefik is also in. Ideally, an external docker network.
It seems that adding network_mode: "host" to the docker-compose and removing the custom network fixed the issue.

'Internal Server Error' when deploying Application with Traefik and LetsEncrypt

I'm new to SSL certificates with Traefik and have been having real trouble getting a successful deployment.
I have a server and domain that I have deployed my application on using Traefik and Http without issue. I would now like to deploy the same application, running on port 9000, to be deployed in Https using LetsEncrypt following the Traefik docs . I can verify that the certificate has been properly created using an SSL checker, however, when I try to visit the site I get Internal Server Error. There are no errors reported in either of the docker logs and I cannot figure out what to try next.
docker-compose.yml
version: '2'
services:
traefik:
image: traefik:v1.7
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.toml:/traefik.toml
- /opt/traefik/acme.json:/acme.json
container_name: traefik
app:
image: myapp_image
container_name: app
restart: always
networks:
- web
ports:
- "9000:9000"
labels:
- "traefik.docker.network=web"
- "traefik.enable=true"
- "traefik.basic.frontend.rule=Host:myapp.com"
- "traefik.basic.port=9000"
- "traefik.basic.protocol=http"
- "traefik.admin.frontend.rule=Host:myapp.com"
- "traefik.admin.protocol=https"
- "traefik.admin.port=9000"
networks:
web:
external: true
traefik.toml
debug = false
logLevel = "ERROR"
defaultEntryPoints = ["https","http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "myapp.com"
watch = true
exposedByDefault = false
[acme]
email = "myemail#email.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"
Finally was able to find a workable solution for this. I may have just been using old information but the best reference to host an application with Traefik on Https using LetsEncrypt was found here.
The working Yaml example is below. Using this example will also eliminate the need for a Toml 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.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.myresolver.acme.email=postmaster#example.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/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.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=myresolver"

Using Traefik 2 as TCP proxy for MariaDB (Docker)

I am trying to use Traefik as a reverse proxy for MariaDB so I can connect from my Client.
Currently Traefik is working fine with HTTP and HTTPS for multiple WordPress Container but i am having trouble configuring it for MariaDB.
Here is the current config:
Traefik Compose File:
version: '3.5'
networks:
traefik:
name: traefik
services:
traefik:
image: traefik:latest
restart: always
container_name: traefik
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.toml:/traefik.toml:ro
- ./acme.json:/acme.json
ports:
- 80:80
- 443:443
- 3306:3306
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.local`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=username:$$apr1$$j994eiLb$$KmPfiii4e9VkZwTPW2/RF1"
networks:
- traefik
Traefik Configuration File (traefik.toml):
# Network traffic will be entering our Docker network on the usual web ports
# (ie, 80 and 443), where Traefik will be listening.
[entyPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address= ":443"
[entryPoints.websecure.http.tls]
certResolver = "resolver"
# [entryPoints.ssh]
# address = ":2222"
[entryPoints.mariadb]
address = ":3306"
#Redirection from HTTP to HTTPS
[entryPoints.web.http]
[entryPoints.web.http.redirections]
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
scheme = "https"
#Integration with Let's Encrypt
[certificatesResolvers.resolver.acme]
email = "service#local"
storage = "acme.json"
[certificatesResolvers.resolver.acme.tlsChallenge]
#[log]
# level = "DEBUG"
[api]
#Defaul=true
dashboard = true
# Enable retry sending request if network error
[retry]
# These options are for Traefik's integration with Docker.
[providers.docker]
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false
network = "traefik"
MariaDB Compose File:
version: '3.5'
networks:
traefik:
external:
name: traefik
services:
dbtest:
image: mariadb:latest
restart: always
container_name: dbtest
environment:
- MYSQL_DATABASE=admin
- MYSQL_USER=admin
- MYSQL_PASSWORD=admin
- MYSQL_ROOT_PASSWORD=admin
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik"
- "traefik.tcp.routers.mariadb.entrypoints=mariadb"
- "traefik.tcp.routers.mariadb.rule=HostSNI(`test.local`)"
- "traefik.tcp.routers.mariadb.tls=true"
# - "traefik.tcp.routers.mariadb.service=dbtest"
# - "traefik.tcp.services.mariadb.loadbalancer.server.port=3306"
When I try to connect to the database from my Client it doesn't work
Anyone having experience or a good example for that?
Looks like it is not possible to specify a Hostname like test.local. Instead you need to use a catchall *.
The labels I used for MariaDB are:
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.mariadb.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mariadb.entrypoints=mariadb"
- "traefik.tcp.routers.mariadb.service=mariadb-svc"
- "traefik.tcp.services.mariadb-svc.loadbalancer.server.port=3306"
I use the following in a docker-compose file. Of course you can adjust port number to whatever you want.
Static Configuration:
traefik:
ports:
# db - postgres
- 5432:5432
# This override command section REPLACES the one in the docker-compose file.
command:
- --providers.docker
- --providers.docker.exposedbydefault=false
- --accesslog
- --log
- --api
# These create named entry points for later use in routers.
# You don't need to specify an entrypoint if the in port = out port. It will
# automatically figure that out.
- --entryPoints.postgres.address=:5432
Dynamic Configuration:
db:
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.tcp.routers.db-tcp.rule=HostSNI(`*`)
- traefik.tcp.routers.db-tcp.entrypoints=postgres
- traefik.tcp.routers.db-tcp.service=db-proxy
- traefik.tcp.services.db-proxy.loadbalancer.server.port=5432
Your traefik.toml has a typo in line 3: [entyPoints]
I think it's missing an r

Using a domain name without a subdomain causes routing to fail

I'm trying to create a simple app using traefik to handling routing and SSL, but I'm running into issues when I want to use 'example.com' instead of 'subdomain.example.com'
If I try to include a service with a frontend rule of just 'example.com' the only rule that works is 'monitor.example.com'. 'api.example.com' won't work and returns a 404. If I comment out the frontend rule for 'example.com' then 'api.example.com' works again. But, no matter what, 'monitor.example.com' works fine. Additionally, 'example.com' always returns a 404 no matter what as well.
Here's my docker-compose file:
version: '3'
services:
reverse-proxy:
image: traefik
restart: always
command: --docker
ports:
- 80:80
- 443:443
networks:
- web
labels:
- "traefik.frontend.rule=Host:monitor.example.com"
- "traefik.port=8080"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.backend=traefik"
environment:
- CLOUDFLARE_EMAIL=###
- CLOUDFLARE_API_KEY=###
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/project/traefik/traefik.toml:/traefik.toml
- /home/project/traefik/acme.json:/acme.json
container_name: traefik
api:
image: api
expose:
- 5080
restart: always
networks:
- web
container_name: api
labels:
- "traefik.frontend.rule=Host:api.example.com"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.port=5080"
- "traefik.backend=api"
app:
image: app
restart: always
networks:
- web
container_name: app
labels:
- "traefik.frontend.rule=Host:example.com"
- "traefik.enable=true"
- "traefik.docker.network=web"
- "traefik.backend=app"
- "traefik.port=80"
networks:
web:
external: true
And here's my traefik configuration:
defaultEntryPoints = ["https", "http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[entryPoints.trdash]
address = ":8080"
[entryPoints.trdash.auth]
[entryPoints.trdash.auth.basic]
users = [
"admin:###",
]
[api]
entryPoint = "trdash"
[acme]
email = "###"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
onDemand = false
[[acme.domains]]
main = "example.com"
[[acme.domains]]
main = "*.example.com"
[acme.dnsChallenge]
provider = "cloudflare"
Any help would be appreciated, thanks!
EDIT:
Okay, I seem to have solved my own problem by disabling the 'orange cloud' on the domains I'm using on Cloudflare. Additionally I had to remove my http to https redirect rules inside of the traefik.toml file. I don't understand why this is a problem, so I'm going to leave the question open. This really seems to negate much of the value which Cloudflare provides.
It turns out the issue was enabling the Cloudflare proxy (orange cloud) without enabling the backend SSL. So long as I have SSL certs on the server (which I do via Let's Encrypt) I can turn Cloudflare SSL to 'Full (strict)' and it appears that the routing works fine now.
Thanks to Daniel Tomcej on the Traefik Slack for helping me find this answer.

Traefik + Nextcloud results in bad gateway

I have 3 services up and running.
A mariadb & nextcloud instance:
version: '2.1'
volumes:
nextcloud:
db:
services:
db:
image: mariadb
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=my_root_password
- MYSQL_PASSWORD=my_password
- MYSQL_DATABASE=my_database
- MYSQL_USER=my_user
app:
image: nextcloud
restart: always
networks:
- web
- default
ports:
- 9000
labels:
- "traefik.backend=app"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:my_host"
- "traefik.enable=true"
- "traefik.port=9000"
- "traefik.default.protocol=http"
networks:
web:
external: true
And a traefik service:
version: '2'
services:
traefik:
image: traefik:1.5.4
restart: always
ports:
- 80:80
- 443:443
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.toml:/traefik.toml
- /opt/traefik/acme.json:/acme.json
container_name: traefik
networks:
web:
external: true
This traefik instance is using this config file:
debug = false
logLevel = "ERROR"
defaultEntryPoints = ["https","http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[retry]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "my_host"
watch = true
exposedByDefault = false
[acme]
email = "my_email"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"
Now when I goto my host, it redirects to HTTPS but then it just displays bad gateway and nothing else. It should display the nextcloud web application. Anyone know why this is happening? I am running the compose files using the docker-compose up -d command.
It might be too late now but I also ran into this issue myself, so posting an answer to what resolved it for me.
Nextcloud exposes port 80 on the container's IP address which Traefik is trying to connect to. So you incorrectly specified the port for 'traefik.port' label. Change it from 9000 to 80.

Resources