How to use Traefik and Envoy in the same project to handle grpc-web? - traefik

I've got a service up and running on traefik with LetsEncrypt at grpc.mydomain.com. However, traefik doesn't support routing grpc-web request due to some issue with CORS (https://github.com/containous/traefik/issues/4210). Envoy appears to be an alternative to traefik which works with grpc-web, but I don't want to go about reconfiguring everything.
If I put envoy at envoy.mydomain.com then it actually hits traefik first and traefik can't route the grpc-web requests to envoy. So this doesn't work.
If I put envoy outside of traefik (mydomain.com:9091) then envoy doesn't have the TLS support that traefik has.
Do I need to switch everything to envoy? Is there an alternative I haven't considered? Any guidance welcome :)
Current Traefik Setup:
traefik:
image: traefik:v2.0.0
container_name: traefik
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.grpc.address=:8090
- --providers.docker
- --api
- --serversTransport.rootCAs=/certs/grpc.cert
# Lets Encrypt Resolvers
- --certificatesresolvers.leresolver.acme.email=${EMAIL}
- --certificatesresolvers.leresolver.acme.storage=/etc/acme/cert.json
- --certificatesresolvers.leresolver.acme.tlschallenge=${TLS_CHALLENGE}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/acme/:/etc/acme/
- ./secrets/grpc.cert:/certs/grpc.cert
# Dynamic Configuration
labels:
# Dashboard
- "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.tls.certresolver=leresolver"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.middlewares=authtraefik"
# https://docs.traefik.io/middlewares/basicauth/
# password generated from `echo $(htpasswd -nb admin $PASSWORD) | sed -e s/\\$/\\$\\$/g`
- "traefik.http.middlewares.authtraefik.basicauth.users=admin:$$apr1$$6VzI3S0N$$29FC82dYEbjFN9tPSfWLX1"
# global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
ports:
- 80:80
- 443:443
- 8090:8090
networks:
- internal
- proxied
grpc_server:
image: ${GRPC_IMAGE}
container_name: grpc_server
volumes:
- /tmp/keyset.json:/tmp/keyset.json
- ./secrets/:/secrets/
working_dir: /app/__main__/
labels:
- "traefik.http.routers.combined_server.rule=Host(`grpc.${DOMAIN}`)"
- "traefik.http.routers.combined_server.entrypoints=grpc"
- "traefik.http.routers.combined_server.tls=true"
- "traefik.http.routers.combined_server.tls.certresolver=leresolver"
# http
- "traefik.http.services.grpc-svc.loadbalancer.server.scheme=h2c"
- "traefik.http.services.grpc-svc.loadbalancer.server.port=8090"
expose:
- 8090
networks:
- internal
- proxied
I also tried setting these to fix the CORS error but got nowhere.
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,PUT,DELETE,POST,OPTIONS"
- "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout"
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
- "traefik.http.middlewares.testheader.headers.alloworigin=*"

A way to approach this issue is by using 2 different URLs that are both being handled by traefik at first. One URL is being used for "direct grpc" (grpc.mydomain.com), the other one for grpc-web (let's call it grpc-web.mydomain.com). Traefik does TLS termination for both.
The grpc.mydomain.com traffic is directly passed to the container running the grpc_server. The grpc-web.mydomain.com traffic is passed to envoy which acts as a grpc-web-proxy and then passes the traffic to the grpc_server.
So as you are using docker-compose, you would need to add an envoy service to your docker-compose.yml:
---
version: '3'
services:
traefik:
# traefik configuration from your question
# ...
grpc-server:
# grpc_server configuration from your question
# ...
envoy:
image: envoyproxy/envoy:v1.14.1
restart: unless-stopped
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
labels:
- traefik.enable=true
- traefik.http.routers.envoy.rule=Host(`grpc-web.mydomain.com`)
- traefik.http.services.envoy.loadbalancer.server.port=8080
- traefik.http.routers.envoy.tls=true
- traefik.http.routers.envoy.tls.certresolver=leresolver
The envoy.yaml configuration (mounted in the volumes section above) looks like this:
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: grpc_service
max_grpc_timeout: 0s
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.grpc_web
- name: envoy.cors
- name: envoy.router
clusters:
- name: grpc_service
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
hosts: [{ socket_address: { address: grpc-server, port_value: 8090 }}]
This is a pretty basic grpc-web config for envoy. The important part to notice is that we set address: grpc-server, port_value: 8090 in the configuration of the "grpc_service" cluster configuration to the service name from the docker-compose.yml and to the port your grpc-server is listening on. Please note I renamed your service from grpc_server to grpc-server as the underscore is not a valid charater in hostnames.
On the client side, use:
"grpc-web.mydomain.com" in your javascript (grpc-web) code.
"grpc.mydomain.com" when writing a client in another language (like golang for example).
I created a working example, which can be found under: https://github.com/rbicker/greeter

If you want to get rid of deprecated warnings in envoy, you can update envoy.yaml from this answer with those three changes:
replace:
- name: envoy.http_connection_manager
config:
with:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
replace
- name: envoy.grpc_web
- name: envoy.cors
- name: envoy.router
with
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.cors
- name: envoy.filters.http.router
replace
hosts: [{ socket_address: { address: grpc-server, port_value: 8090 }}]
with
load_assignment:
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: grpc-server
port_value: 8090

Related

How to use Envoy as a Reverse Proxy for a specific URL on localhost

I want to use Envoy as a reverse proxy in which I want to redirect the request from
http://example.com:3443/node-exporter/metrics
to
http://localhost:9100/metrics
I want to redirect to a specific URL /metrics on the port 9100.
This is my current envoy_conf.yaml file
listeners:
- name: prom_listener
address:
socket_address : {address: 0.0.0.0, port_value: 3443}
filter_chains:
- name: prom_filter_chain
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: http_connection_manager
route_config:
virtual_hosts:
- name: prom_local_host
domains: ["*"]
routes:
- name: node-exporter-route
match: {prefix: "/node-exporter/"}
route:
cluster: node-exporter-cluster-server
timeout: 0s
idle_timeout: 0s
http_filters:
- name: envoy.filters.http.router
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: node-exporter-cluster-server
type: static
connect_timeout: 2s
load_assignment:
cluster_name: node-exporter-cluster-server
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 9100
What changes (additions/deletions) should I make in this in order to achieve the reverse proxying to a specific url on the localhost and port mentioned?
With your configuration, when you are requesting example.com:3443/node-exporter/metrics, you are actually trying to access 127.0.0.1:9100/node-exporter/metrics, which does not exist.
To access 127.0.0.1:9100/metrics (notice the missing /node-exporter part of the URL), you only have to configure your route to tell Envoy to rewrite the prefix. You should use the prefix_rewrite option to strip the /node-exporter part:
routes:
- name: node-exporter-route
match: {prefix: "/node-exporter/"}
route:
cluster: node-exporter-cluster-server
prefix_rewrite: "/"
timeout: 0s
idle_timeout: 0s

How to setup Traefik as reverse proxy for ASP.NET Core app with kestrel?

So long ago I started studying the data of the solution, but I am so stupid that I have not found a solution to how to configure file docker-compose for a simple ASP.NET Core for traefik proxy.
I took an example of a simple ASP.NET Core application from the Microsoft site, which, after deployment, is available at localhost:8443 using https, because earlier I released a self-signed (aspnetapp.pfx), ok.
Then I unfolded the traefik and configured the dashboard I see that traefik gets information about the aspnet_demo container, but at web app addresses, or webapp.mydomen.com/ or localhost nothing is available - maximum I get the error ERR_TOO_MANY_REDIRECTS in browser.
In logs traefik when referring to webapp.mydomen.com I get "RequestURI ": "/ "
What did you forget to point out?
I understand that the content aspnet_demo get on 443 port, so I tell Traefik where to look, but nothing...
Help me please understanding this. Thank you
My docker compose ASP.NET Core app looks like this:
version: "3.8"
services:
aspnet_demo:
image: mcr.microsoft.com/dotnet/core/samples:aspnetapp
container_name: aspnet_sample
ports:
- 8080:80
- 8443:443
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
volumes:
- ~/.aspnet/https:/https:ro
networks:
- traefik-reverse-proxy
labels:
- traefik.enable=true
- traefik.http.routers.aspnet.entrypoints=web
- traefik.http.routers.aspnet.rule=Host(`webapp`)
- traefik.http.routers.aspnet_secure.entrypoints=web-secure
- traefik.http.routers.aspnet_secure.rule=Host(`webapp.mydomen.com`)
- traefik.http.routers.aspnet_secure.tls=true
- traefik.http.services.aspnet.loadbalancer.server.port=443
networks:
traefik-reverse-proxy:
external: true
My docker compose Traefik looks like this:
version: "3.8"
services:
traefik:
image: traefik:v2.9
ports:
- "80:80"
- "443:443"
- "8080:8080"
networks:
- traefik-reverse-proxy
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./configuration/dynamic.yaml:/traefik_conf/dynamic.yaml"
- "./configuration/traefik.yml:/traefik.yml:ro"
- "./cert/:/traefik_conf/cert/"
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.entrypoints=web-secure"
- "traefik.http.routers.traefik.rule=Host(`traefiklocal.mydomen.com`)"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=tls"
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=unixhost:$$apr1$$vqyMX723$$6nZ1lC3/2JN6QJyeEhJB8/"
networks:
traefik-reverse-proxy:
external: true
My static config Traefik looks like this:
api:
dashboard: true
insecure: true
log:
level: DEBUG
entryPoints:
web:
address: ":80"
forwardedHeaders:
insecure: true
http:
redirections:
entryPoint:
to: web-secure
web-secure:
address: ":443"
providers:
docker:
watch: true
exposedbydefault: false
file:
directory: /traefik_conf/
watch: true
filename: dynamic.yaml
My dynamic config Traefik:
tls:
certificates:
# first certificate
- certFile: "/traefik_conf/cert/pem_com_2022.pem"
keyfile: "/traefik_conf/cert/star_com_2022.key"
# second certificate
- certFile: "/traefik_conf/cert/aspnetapp.pem"
keyfile: "/traefik_conf/cert/aspnetapp.key"
stores:
- default

Envoy proxy returning 'no healthy upstream' and/or ERR_EMPTY_RESPONSE for ASP.NET application

I'm trying to setup an example ASP.NET project that uses envoy to route between the secure and non-secure versions of the app. The application works fine in Docker on both http and https, but when I try to route to it through envoy I get 'no healthy upstream' on the http site, and ERR_EMPTY_RESPONSE on the https site.
My envoy.yaml:
static_resources:
listeners:
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
http_filters:
- name: envoy.filters.http.router
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/admin"
direct_response:
status: 403
body:
inline_string: "Forbidden, yo"
- match:
prefix: "/"
route:
cluster: exampleagg-http
- name: listener_https
address:
socket_address:
address: 0.0.0.0
port_value: 443
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
http_filters:
- name: envoy.filters.http.router
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/admin"
direct_response:
status: 403
body:
inline_string: "Forbidden, yo"
- match:
prefix: "/"
route:
cluster: exampleagg-https
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain:
filename: /etc/https/aspnetapp.crt
private_key:
filename: /etc/https/aspnetapp.key
clusters:
- name: exampleagg-http
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
load_assignment:
cluster_name: exampleagg-http
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: http://example-api/WeatherForecast
port_value: 80
- name: exampleagg-https
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
load_assignment:
cluster_name: exampleagg-https
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: https://example-api/WeatherForecast
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"#type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain:
filename: /etc/https/aspnetapp.crt
private_key:
filename: /etc/https/aspnetapp.key
My docker-compose.yaml:
networks:
envoy:
name: envoy
services:
api-gateway:
image: envoyproxy/envoy:v1.23-latest
container_name: api-gateway
volumes:
- ./ApiGateways/Envoy/config:/etc/envoy
- ${USERPROFILE}/.aspnet/https:/etc/https/
networks:
- envoy
ports:
- "8080:80"
- "8081:443"
depends_on:
- example-api
example-api:
image: ${REGISTRY:-hexsorcerer}/example-proxy-envoy:${PLATFORM:-linux}-${TAG:-latest}
container_name: example-api
volumes:
- ${USERPROFILE}/.aspnet/https:/https/
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: "https://+;http://+"
ASPNETCORE_HTTPS_PORT: 443
ASPNETCORE_Kestrel__Certificates__Default__Password: "password"
ASPNETCORE_Kestrel__Certificates__Default__Path: /https/aspnetapp.pfx
networks:
- envoy
expose:
- "80"
- "443"
ports:
- "5000:80"
- "5001:443"
build:
context: .
dockerfile: Services/Example/Example.API/Dockerfile
The Dockerfile for the example application:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# It's important to keep lines from here down to "COPY . ." identical in all Dockerfiles
# to take advantage of Docker's build cache, to speed up local container builds
COPY "ExampleEnvoyProxy.sln" "ExampleEnvoyProxy.sln"
COPY "Services/Example/Example.API/Example.API.csproj" "Services/Example/Example.API/Example.API.csproj"
#RUN dotnet restore "ExampleEnvoyProxy.sln"
COPY . .
WORKDIR /src/Services/Example/Example.API
RUN dotnet publish -c Release -o /app
EXPOSE 80 443
FROM build AS publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Example.API.dll"]
I've been hacking away at this for days and made some good progress, but just can't quite get there. Any help would be greatly appreciated.
After not getting any responses for a couple weeks, I was forced to keep hacking around on this and I finally figured it out.
I think the biggest problem with what I was doing was a misunderstanding about how proxy servers route traffic. I was attempting to route the incoming path '/' to a backed service path of '/WeatherForecast', but that's not how it works. Your incoming endpoint will be "passed along" to the backend service, it's simply the cluster that you choose to pass it to. This is probably clear to veterans but as someone who doesn't work on these often it wasn't obvious to me at first.
There was also an issue of certificates, and I ended up generating one for the app and one for envoy, each of which were different formats, that also had to be trusted on my machine. This took a little extra effort for the envoy cert, but it worked much better than trying to use a single cert for both.
I documented what I learned with some instructions and a fully working example here.

Multiple domains with Traefik

I am new to Traefik but trying to migrate from jwilder/nginx-proxy and letsencrypt-companion to Traefik.
I have setup Traefik with this config file:
traefik.yml
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
api:
dashboard: true
insecure: true
certificatesResolvers:
le:
acme:
email: username#gmail.com
storage: acme.json
httpChallenge:
# used during the challenge
entryPoint: web
providers:
docker:
endpoint: unix:///var/run/docker.sock
exposedByDefault: false
docker-compose.yml
version: '3'
services:
traefik:
image: traefik:v2.2
restart: always
ports:
- 80:80
- 443:443
- 8080:8080
networks:
- web
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /data/disk1/traefik/traefik.yml:/traefik.yml
- /data/disk1/traefik/acme.json:/acme.json
container_name: traefik
When starting one container on domain #1
docker-compose.yml
version: "3"
services:
confluence:
container_name: confluence
image: atlassian/confluence-server:7.6.2
volumes:
- /data/disk1/atlassian/application-data/confluence:/var/atlassian/application-data/confluence
ports:
- "8090:8090"
external_links:
- postgres:postgres
environment:
- CATALINA_CONNECTOR_PROXYNAME=confluence.tld
- CATALINA_CONNECTOR_PROXYPORT=443
- CATALINA_CONNECTOR_SCHEME=https
- CATALINA_CONNECTOR_SECURE=true
- VIRTUAL_HOST=confluence.tld
- VIRTUAL_NETWORK=web
- VIRTUAL_PORT=8090
- LETSENCRYPT_EMAIL=user#tld
- LETSENCRYPT_HOST=confluence.tld
labels:
- traefik.enable=true
- traefik.http.routers.confluence.rule=Host(`confluence.tld`)
- traefik.http.routers.confluence.tls=true
- traefik.http.routers.confluence.tls.certresolver=le
- traefik.http.routers.confluence.service=confluence
- traefik.http.services.confluence.loadbalancer.server.port=8090
networks:
- web
restart: always
networks:
web:
external:
name: web
It works perfect.
NOTE: I have kept the environment variables for jwilder/nginx-proxy for the time being
When launching another container with different tld I can't get that working.
E.g.
docker-compose.yml
version: "3"
services:
confluence:
container_name: myapp
image: nginx:latest
volumes:
- /data/disk1/myapp/www/:/usr/share/nginx/html:ro
- /data/disk1/myapp/conf/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "9999:80"
environment:
- VIRTUAL_HOST=www.tld2,tld2
- VIRTUAL_NETWORK=web
- VIRTUAL_PORT=9999
- LETSENCRYPT_EMAIL=user#tld2
- LETSENCRYPT_HOST=www.tld2,tld2
labels:
- traefik.enable=true
- traefik.http.routers.myapp.rule=Host(`tld2`) || Host(`www.tld2`)
- traefik.http.routers.myapp.tls=true
- traefik.http.routers.myapp.tls.certresolver=le
- traefik.http.routers.myapp.service=tld2
- traefik.http.services.myapp.loadbalancer.server.port=9999
networks:
- web
restart: always
networks:
web:
external:
name: web
It doesn't work but everything looks OK in Traefik dashboard.
Any ideas?
There is an error in the second docker-compose.yml:
You define the router named mypp to use a service named tld2:
traefik.http.routers.myapp.service=tld2
but your service is named myapp:
traefik.http.services.myapp.loadbalancer.server.port=9999
This should have generated an error in Traefik's log regarding an unresolvable service.
To fix this, configure your router myapp to use the service myapp:
traefik.http.routers.myapp.service=myapp

How to redirect to the dashboard from a URL?

I currently access the V2 dashboard through http://traefik.my.server:8080/dashboard/ (Traefik runs in a docker container and 8080 is exposed to the host).
I would like to change that so that the dashboard is available at http://traefik.my.server/dashboard
I tried to add the following labels to configure this behavior but I get a 404 when accessing http://traefik.my.server/dashboard
- traefik.http.routers.dashboard.rule=Host(`traefik.my.server:`) && Path(`/dashboard`)
- traefik.http.services.dashboard.loadbalancer.server.port=8080
- traefik.http.routers.dashboard.entryPoints=http
(the http entrypoint is port 80)
What is the correct way to set up such redirectio
Recommend read:
https://docs.traefik.io/v2.1/operations/dashboard/#secure-mode
https://blog.containo.us/traefik-2-0-docker-101-fc2893944b9d
https://github.com/containous/blog-posts/tree/master/2019_09_10-101_docker
FYI it's not redirection but a routing.
https://community.containo.us/t/how-to-redirect-to-the-dashboard-from-a-url/4082/2
Following up on #Idez help at https://community.containo.us/t/how-to-redirect-to-the-dashboard-from-a-url/4082, a working configuration is
The docker-compose file:
services:
traefik:
container_name: traefik
image: traefik
ports:
- 80:80
- 443:443
restart: unless-stopped
volumes:
- /etc/docker/container-data/traefik:/etc/traefik
- /var/run/docker.sock:/var/run/docker.sock
- /etc/localtime:/etc/localtime:ro
labels:
- traefik.http.routers.api.rule=Host(`traefik.mydomain.org`)
- traefik.http.routers.api.service=api#internal
- traefik.http.routers.api.middlewares=lan
- traefik.http.middlewares.lan.ipwhitelist.sourcerange=192.168.10.0/24, 192.168.20.0/24
- traefik.enable=true
version: "3"
Configuration file
global:
sendAnonymousUsage: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
api:
dashboard: true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
defaultRule: "Host(`{{ index .Labels \"com.docker.compose.service\" }}.mydomain.org`)"
log:
level: INFO
#level: DEBUG
certificatesResolvers:
le:
acme:
email: le#mydomain.org
storage: /etc/traefik/acme.json
tlsChallenge: {}
#caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"