Traefik 2: access to .well-known acme folder, What do you think? - docker

I had problem with my mailserver is it was not working properly when i added mailbox to Outlook. It warned me that i use wrong certificate, on closer inspection it showed default email docker creator certificate. Even though webmail is protected with SSL from Traefik.
After researching I manage to come up with this, it is combination of ones guy docker compose, cannot find the link for his post. And my previous attempt to host acme challenge on my flask website, what was overwritten by default with Nginx Proxy manager, so I abandon it.
But now while working with Traefik, what provides much more flexibility i was able to do it:
This is one page on my flask website, what returns files from within the .well-known folder, which is mapped in each docker container what needs access to lets encrypt certification process, behind reverse proxy.
#app.route('/.well-known/acme-challenge/<acmechalleng>')
def acme(acmechalleng):
try:
# acme_folder is file path to folder where challenges are stored
# for example: acmechall_folder = os.path.abspath('acmefiles/')
acme_folder=config.acmechall_folder
extr = {}
# Sets up ignored file names what will not be showed
ignore_files='.paths.json'
try:
items = json.load(open(os.path.join(acme_folder, '.paths.json')))
except Exception:
items = ""
for root, dirs, files in os.walk(acme_folder):
for f in files:
# this filters files we do not want to show ie: paths file
if f not in ignore_files:
full_path = os.path.join(root, f)
path = full_path.split(acme_folder,1)[1]
path = path.replace("\\", "/")
split_path = path.split('/')
extr.update({path[1:]: 0})
if items != extr:
with open(os.path.join(acme_folder, '.paths.json'), 'w', encoding='utf-8') as f:
json.dump(extr, f, ensure_ascii=False, indent=4)
# Only files what are in .pahts.json will be allowed to be read
items = json.load(open(os.path.join(acme_folder, '.paths.json')))
existing = []
for key, arr in items.items():
existing.append(key)
if acmechalleng in existing:
with open(os.path.join(acme_folder, acmechalleng),"rb") as f:
content = f.readlines()
return Response(content)
else:
return render_template('404.html', **_auto_values), 404
except Exception as err:
return render_template('404.html', **_auto_values), 404
Poste.io mail server Docker File, with access to .well-known challenges for Letsencrypt
version: '3'
networks:
traefikauth_net:
external: true
services:
mailserver:
image: analogic/poste.io
container_name: mailserver
hostname: mail.mydomain.com
networks:
- traefikauth_net
restart: unless-stopped
ports:
- "25:25"
- "587:587"
- "993:993"
environment:
- HOSTNAME=poste.mydomain.com
- TZ=Europe/London
- LETSENCRYPT_EMAIL=admin#mydomain.com
- LETSENCRYPT_HOST=mydomain.com
- VIRTUAL_HOST=poste.mydomain.com
- HTTPS=OFF
- DISABLE_CLAMAV=TRUE
- DISABLE_RSPAMD=TRUE
volumes:
- /opt/traefik/.well-known:/opt/www/.well-known/acme-challenge
- /opt/mailserver:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.poste-letsencrypt.rule=HostRegexp(`mydomain.com`,`{subdomain:[a-z]*}.mydomain.com`) && PathPrefix(`/.well-known/`)"
- "traefik.http.routers.poste-letsencrypt.entrypoints=http"
- "traefik.http.routers.poste-letsencrypt.service=mail"
- "traefik.http.services.poste-letsencrypt.loadbalancer.server.port=80"
- "traefik.http.routers.mail.rule=Host(`poste.mydomain.com`)"
- "traefik.http.routers.mail.entrypoints=https"
- "traefik.http.routers.mail.tls.certresolver=cloudflare"
- "traefik.http.routers.mail.service=mail"
- "traefik.http.services.mail.loadbalancer.server.port=80"
The main website, on "mydomain.com" needs also Traefik labels:
volumes:
- /opt/traefik/.well-known:/var/www/wellknown
labels:
- "traefik.enable=true"
- "traefik.http.routers.flask-letsencrypt.entrypoints=http"
- "traefik.http.routers.flask-letsencrypt.rule=HostRegexp(`mydomain.com`) && PathPrefix(`/.well-known/`)"
- "traefik.http.services.flask-letsencrypt.loadbalancer.server.port=80"
- "traefik.http.routers.flask-letsencrypt.service=myflask"
- "traefik.http.routers.myflask.entrypoints=https"
- "traefik.http.routers.myflask.rule=Host(`mydomain.com`)"
- "traefik.http.routers.myflask.service=myflask"
- "traefik.http.routers.myflask.tls=true"
- "traefik.http.routers.myflask.tls.certresolver=cloudflare"
- "traefik.http.services.myflask.loadbalancer.server.port=80"
I also have normal CertResolver for all the other domains what is in main Traefik file as follow traefik.yml:
certificatesResolvers:
cloudflare:
acme:
email: admin#mydomain.com
storage: /letsencrypt/acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "1.0.0.1:53"
entryPoints:
http:
address: ":80"
https:
address: ":443"
Traefik 2 docker-compose:
version: '3'
services:
traefik:
image: traefik
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
- /opt/traefik/traefik.yml:/traefik.yml:ro
- /opt/traefik/conf:/additionalsettings
- /opt/traefik/folderacme:/letsencrypt
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.api.rule=Host(`traefik.mydomain.com`)'
- 'traefik.http.routers.api.entrypoints=https'
- 'traefik.http.routers.api.service=api#internal'
- 'traefik.http.routers.api.tls=true'
- 'traefik.http.routers.api.middlewares=authelia#docker'
- "traefik.http.routers.api.tls.certresolver=cloudflare"
- "traefik.http.routers.api.tls.domains[0].main=mydomain.com"
- "traefik.http.routers.api.tls.domains[0].sans=*.mydomain.com"
- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://logmein.mydomain.com/"
- "traefik.http.middlewares.authelia.forwardauth.trustforwardheader=true"
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'
- 'traefik.http.middlewares.authelia-basic.forwardauth.address=http://authelia:9091/api/verify?auth=basic'
- 'traefik.http.middlewares.authelia-basic.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia-basic.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email'
# global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
environment:
- CF_API_EMAIL=<cloudflare api email>
- CF_API_KEY=<cloudflare api key for certresolver>
ports:
- 80:80
- 443:443
command:
- '--api'
- '--providers.docker=true'
- '--providers.docker.exposedByDefault=false'
- '--entrypoints.http=true'
- '--entrypoints.http.address=:80'
- '--entrypoints.http.http.redirections.entrypoint.to=https'
- '--entrypoints.http.http.redirections.entrypoint.scheme=https'
- '--entrypoints.https=true'
- '--entrypoints.https.address=:443'
What do you think? I believe that python code could be much smaller, especially that part what stores the path in Json but i use that from my other project, and there I needed more then path to the file. This way I believe nobody should be able access other files, only those in ACME folder.

Related

Neo4j Docker Compose with Python FastAPI, Traefic on https, "Connection refused"

I'm using a Docker compose with multiple containers (a custom version of Full Stack FastAPI, but with Neo4j included).
Full docker-compose.yml here and an excerpt for neo4j:
neo4j:
image: neo4j
networks:
- ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- default
ports:
- "6477:6477"
- "7474:7474"
- "7687:7687"
volumes:
- app-neo4j-data:/data
- app-neo4j-plugins:/plugins
env_file:
- .env
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH=${NEO4J_USERNAME?Variable not set}/${NEO4J_PASSWORD?Variable not set}
- NEO4J_dbms_default__advertised__address=0.0.0.0
- NEO4J_dbms_default__listen__address=0.0.0.0
- NEO4J_dbms_connector_bolt_advertised__address=0.0.0.0:7687
- NEO4J_dbms_connector_bolt_listen__address=0.0.0.0:7687
- NEO4J_dbms_connector_http_listen__address=:7474
- NEO4J_dbms_connector_http_advertised__address=:7474
- NEO4J_dbms_connector_https_listen__address=:6477
- NEO4J_dbms_connector_https_advertised__address=:6477
- NEO4J_dbms_connector_bolt_listen__address=:7687
- NEO4J_dbms_mode=SINGLE
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.rule=Host(`neo4j.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.entrypoints=http
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.middlewares=${STACK_NAME?Variable not set}-https-redirect
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.rule=Host(`neo4j.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.tls.certresolver=le
- traefik.http.services.${STACK_NAME?Variable not set}-neo4j.loadbalancer.server.port=7474
replicas: 1
resources:
limits:
memory: 1024M
reservations:
memory: 500M
restart_policy:
condition: on-failure
I try to reach bolt from the backend with bolt://login:password#neo4j:7687 but get the following error:
neo4j.exceptions.ServiceUnavailable: Couldn't connect to neo4j:7687 (resolved to ('10.0.3.11:7687',)):
Failed to establish connection to ResolvedIPv4Address(('10.0.3.11', 7687)) (reason [Errno 111] Connection refused)
I have reviewed an extraordinary number of responses on Stackoverflow, but not getting anywhere. This does work on dev, but I haven't implemented https there, so I'm not sure if that's what's causing the problem.
I'm at a loss and would appreciate any guidance.
This particular issue wasn't related to Docker or Neo4j directly. Rather it is that it takes finite time to initialise the database. The solution is to retry the connection. Here's the way I went about it:
from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed
max_tries = 60 * 5 # 5 minutes
wait_seconds = 1
#retry(
stop=stop_after_attempt(max_tries),
wait=wait_fixed(wait_seconds),
before=before_log(logger, logging.INFO),
after=after_log(logger, logging.WARN),
)
def initNeo4j() -> None:
try:
init_gdb()
except Exception as e:
raise e
Where init_gdb() is the script initialising Neo4j.
The issue arises after Docker completes instantiation of the containers and the main backend server begins to initialise and build itself. When the admin user is created, the database must be up and running, if it isn't, you get this error.
Given the same error is used to cover a multitude of issues, it isn't necessarily clear that the database isn't ready, rather than that some setting to reach it is incorrect.

Traefik custom error middleware for HTTP status 502 doesn’t work

I would like to serve custom error pages for common HTTP error codes. I was following this tutorial. For this purpose, I created the following docker-compose.yml file to test the functionality. It consists of:
errorPageHandler which is a nginx server which is able to return static HTML pages (404.html and 502.html).
whoami1 which routes the request to port 80 of traefik/whoami image
whoami2 which routes the request to non-existent port 81 of traefik/whoami image which results in 502 - Bad Gateway
version: "3.7"
services:
errorPageHandler:
image: "nginx:latest"
networks:
- traefik-net
volumes:
- "./ErrorPages:/usr/share/nginx/ErrorPages"
- "./default.conf:/etc/nginx/conf.d/default.conf"
deploy:
replicas: 1
labels:
# enable Traefik for this service
- "traefik.enable=true"
- "traefik.docker.network=traefik-net"
# router (catches all requests with lowest possible priority)
- "traefik.http.routers.error-router.rule=HostRegexp(`{catchall:.*}`)"
- "traefik.http.routers.error-router.priority=1"
- "traefik.http.routers.error-router.middlewares=error-pages-middleware"
# middleware
- "traefik.http.middlewares.error-pages-middleware.errors.status=400-599"
- "traefik.http.middlewares.error-pages-middleware.errors.service=error-pages-service"
- "traefik.http.middlewares.error-pages-middleware.errors.query=/{status}.html"
# service
- "traefik.http.services.error-pages-service.loadbalancer.server.port=80"
whoami1:
image: "traefik/whoami"
networks:
- traefik-net
deploy:
replicas: 1
labels:
# enable Traefik for this service
- "traefik.enable=true"
- "traefik.docker.network=traefik-net"
# router
- "traefik.http.routers.whoami1.rule=HostRegexp(`whoami1.local`)"
- "traefik.http.routers.whoami1.service=whoami1"
# service
- "traefik.http.services.whoami1.loadbalancer.server.port=80"
- "traefik.http.services.whoami1.loadbalancer.server.scheme=http"
whoami2:
image: "traefik/whoami"
networks:
- traefik-net
deploy:
replicas: 1
labels:
# enable Traefik for this service
- "traefik.enable=true"
- "traefik.docker.network=traefik-net"
# router
- "traefik.http.routers.whoami2.rule=HostRegexp(`whoami2.local`)"
- "traefik.http.routers.whoami2.service=whoami2"
# service
- "traefik.http.services.whoami2.loadbalancer.server.port=81" # purposely wrong port
- "traefik.http.services.whoami2.loadbalancer.server.scheme=http"
networks:
traefik-net:
external: true
name: traefik-net
Folder ErrorPages contains two static HTML files, 404.html and 502.html. Content of default.conf is:
server {
listen 80;
server_name localhost;
error_page 404 /404.html;
error_page 502 /502.html;
location / {
root /usr/share/nginx/ErrorPages;
internal;
}
}
I added the following entries to my hosts file (172.15.16.17 is IP of the server where Traefik and all of the mentioned services are deployed):
172.15.16.17 error404.local
172.15.16.17 whoami1.local
172.15.16.17 whoami2.local
My observations:
When I visit http://error404.local, Traefik routes the request to nginx and 404.html is returned. This is expected behavior because http://error404.local doesn't match any of the routes defined in Traefik.
When I visit http://whoami1.local, Traefik routes request to whoami1 service and information about container is displayed on the page (expected behavior).
When I visit http://whoami2.local, Traefik doesn't route request to nginx service, but it displays its default Bad Gateway page. Why doesn't it route the request to the nginx?
The traefik routers (whoami1 and whoami2) needs to use the error middleware that you defined
https://doc.traefik.io/traefik/middlewares/http/errorpages/
Traefik error middleware docs
So add the following labels to their respective containers
- "traefik.http.whoami1.middlewares=error-pages-middleware"
- "traefik.http.whoami2.middlewares=error-pages-middleware"
the Traefik dashboard will show that the routes are using the middleware (refer image) One of my routes from my traefik dashboard
Another option would be to add the middleware to the entrypoint so that all routes use the error middleware (Add this to traefik container compose)
command:
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.middlewares=error-pages-middleware#docker"

How to redirect from http to https using middleware in treafik?

I am testing treafik to set it up for exposing my docker containers with SSL.
I seams to mostly work but I am having some issues http to https redirect. I have middleware that shows up in the dashboard as successful but when I go http option of the address I get 404
Here is my docker-compose.yml for traefik
version: "3.3"
services:
traefik:
image: traefik:v2.5
restart: always
container_name: traefik
ports:
- "80:80" # <== http
- "8080:8080" # <== :8080 is where the dashboard runs on
- "443:443" # <== https
command:
- --api.insecure=false # <== Enabling insecure api, NOT RECOMMENDED FOR PRODUCTION
- --api.dashboard=true # <== Enabling the dashboard to view services, middlewares, routers, etc.
- --api.debug=true # <== Enabling additional endpoints for debugging and profiling
- --log.level=DEBUG # <== Setting the level of the logs from traefik
- --providers.docker=true # <== Enabling docker as the provider for traefik
- --providers.docker.exposedbydefault=false # <== Don't expose every container to traefik
- --providers.file.filename=/config/dynamic.yaml # <== Referring to a dynamic configuration file
- --providers.docker.network=web # <== Operate on the docker network named web
- --entrypoints.web.address=:80 # <== Defining an entrypoint for port :80 named web
- --entrypoints.web.http.redirections.entryPoint.to=web-secure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --entrypoints.web-secured.address=:443 # <== Defining an entrypoint for https on port :443 (not really nee$
- --certificatesresolvers.mytlschallenge.acme.tlschallenge=true # <== Enable TLS-ALPN-01 (not really needed)
- --certificatesresolvers.mytlschallenge.acme.email=email#domain.com # <== Set your email (not really needed)
- --certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json # <== SSL stuff we don't need.
volumes:
- ./letsencrypt:/letsencrypt # <== Volume for certs (TLS) (not really needed)
- /var/run/docker.sock:/var/run/docker.sock # <== Volume for docker admin
- ./config/:/config # <== Volume for dynamic conf file, **ref: line 27
networks:
- web # <== Placing traefik on the network named web, to access containers on this network
labels:
- "traefik.enable=true" # <== Enable traefik on itself to view dashboard and assign subdomain to$
- "traefik.http.routers.api.rule=Host(`traefik.testing.domain.com`)" # <== Setting the domain for the d$
- "traefik.http.routers.api.service=api#internal" # <== Enabling the api to be a service to acce$
networks:
web:
external: true
name: web
Here is the config/dynamic.yaml for traefik to set up middleware
## Setting up the middleware for redirect to https ##
http:
middlewares:
httpsredirect:
redirectScheme:
scheme: https
permanent: true
And here is test docker containers docker-compose.yml
version: '3.3'
services:
whoami:
# A container that exposes an API to show its IP address
image: traefik/whoami
networks:
- web
labels:
- "traefik.enable=true"
- "treafik.http.routers.whoami.entrypoints=web,web-secure"
- "traefik.http.routers.whoami.rule=Host(`whoami.testing.domain.com`)"
- "traefik.http.routers.whoami.tls=true"
- "traefik.http.routers.whoami.middlewares=httpsredirect#file" # <== This is a middleware to redirect to htt$
- "traefik.http.routers.whoami.tls.certresolver=mytlschallenge"
networks:
web:
external: true
name: web
Try the following from redirect regex
Docker
# Redirect with domain replacement
# Note: all dollar signs need to be doubled for escaping.
labels:
- "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^https://localhost/(.*)"
- "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}"
For kubernetes
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: http-to-https-redirect
spec:
redirectRegex:
regex: ^http://(www.)?yourdomain.com/(.*)
replacement: https://yourdomain.com
permanent: true
And you inject the middleware in your ingress route
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute
spec:
tls: {}
entryPoints:
- web
- websecure
routes:
- match: "HostRegexp(`{sub:(www.)?}yourdomain.com`) && PathPrefix(`/`)"
kind: Rule
services:
- name: your-service
port: 80

Tracing requests over their lifetime … through Docker Containers?

Tracing makes finding parts in code, worthwhile a developers time and attention, much easier. For that reason, I attached Jaeger as tracer to a set of microservices inside Docker containers. I use Traefik as ingress controller/ service-mesh to route and proxy requests.
The problem I am facing is, that something's wrong with the tracing config in Traefik. Jaeger can not find the span context to connect the single/ service-dependend spans to a whole trace.
The following line appears in the logs:
{
"level":"debug",
"middlewareName":"tracing",
"middlewareType":"TracingEntryPoint",
"msg":"Failed to extract the context: opentracing: SpanContext not found in Extract carrier",
"time":"2021-02-02T23:16:51+01:00"
}
What I tried/ searched/ confirmed so far:
I already checked ports (they are open inside the Docker host network) and everything's reachable. So interconnectivity is not the problem here.
The forwarding of headers is set via Docker Compose labels: loadbalancer.passhostheader=true.
The following snippets describe the Docker Compose setup.
Traefik: Ingress Controller
This is a stripped down version of the traefik Container.
# Network
ROOT_DOMAIN=example.test
DEFAULT_NETWORK=traefik
---
version: '3'
services:
image: "traefik:2.4.2"
hostname: "controller"
restart: on-failure
security_opt:
- no-new-privileges:true
ports:
- "443:443"
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
- "8082:8082"
- "8083:8083"
networks:
- default
working_dir: /etc/traefik
volumes:
- /private/etc/localtime:/etc/localtime:ro
- ${PWD}/controller/static.yml:/etc/traefik/traefik.yml:ro
- ${PWD}/controller/dynamic.yml:/etc/traefik/dynamic.yml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- cert-storage:/usr/local/share/ca-certificates:ro
- ${PWD}/logs/traefik:/var/log/traefik
volumes:
cert-storage:
driver_opts:
type: none
o: bind
device: ${PWD}/certs/certs
networks:
default:
external: true
name: ${DEFAULT_NETWORK}
Traefik is set up using the file provider as base and Docker Compose labels on top of it:
# static.yaml (Traefik conf)
debug: true
log:
level: DEBUG
filePath: /var/log/traefik/error.log
format: json
serversTransport:
insecureSkipVerify: true
api:
dashboard: true
insecure: true
debug: true
providers:
docker:
exposedByDefault: false
swarmMode: false
watch: true
defaultRule: "Host(`{{ normalize .Name }}.example.test`)"
endpoint: "unix:///var/run/docker.sock"
network: traefik
file:
filename: /etc/traefik/dynamic.yml
watch: true
tracing:
serviceName: "controller"
spanNameLimit: 250
jaeger:
samplingType: const
samplingParam: 1.0
samplingServerURL: http://tracer:5778/sampling
localAgentHostPort: 127.0.0.1:6831
gen128Bit: true
propagation: jaeger
traceContextHeaderName: "traefik-trace-id"
collector:
endpoint: http://tracer:14268/api/traces?format=jaeger.thrift
Jaeger: Open Tracing/ Open Telemetry
---
version: '3'
services:
tracer:
image: "jaegertracing/all-in-one:1.21.0"
hostname: "tracer"
command:
- "--log-level=info"
- "--admin.http.host-port=:14269"
- "--query.ui-config=/usr/local/share/jaeger/ui/conf.json"
environment:
SPAN_STORAGE_TYPE: memory
restart: on-failure
security_opt:
- no-new-privileges:true
expose:
- 5775/udp
- 6831/udp
- 6832/udp
- 5778
- 14250
- 14268
- 14269
- 14271
- 16686
- 16687
volumes:
- /private/etc/localtime:/etc/localtime:ro
- ${PWD}/tracer/conf:/usr/local/share/jaeger
- ${PWD}/logs/jaeger:/var/log/#TODO
- cert-storage:/usr/local/share/ca-certificates
networks:
- default
labels:
- "traefik.enable=true"
- "traefik.docker.network=${DEFAULT_NETWORK}"
# Admin UI router
- "traefik.http.routers.tracer-router.rule=Host(`tracer.$ROOT_DOMAIN`)"
- "traefik.http.routers.tracer-router.entrypoints=https"
- "traefik.http.routers.tracer-router.tls=true"
- "traefik.http.routers.tracer-router.tls.options=default"
- "traefik.http.routers.tracer-router.service=tracer"
# Service/ Load Balancer
- "traefik.http.services.tracer.loadbalancer.passhostheader=true"
- "traefik.http.services.tracer.loadbalancer.server.port=16686"
- "traefik.http.services.tracer.loadbalancer.server.scheme=http"
I'm not 100% sure what the problem is you're experiencing, but here's some things to consider.
According to this post on the Traefik forums, that message you're seeing is debug level because it's not something you should be worried about. It's just logging that no trace context was found, so a new one will be created. That second part is not in the message, but apparently that's what happens.
You should check to see if you're getting data appearing in Jaeger. If you are, that message is probably nothing to worry.
If you are getting data in Jaeger, but it's not connected, that will be because Traefik can only only work with trace context that is already in inbound requests, but it can't add trace context to outbound requests. Within your application, you'll need to implement trace propagation so that your outbound requests include the trace context that was received as part of the incoming request. Without doing that, every request will be sent without trace context and will start a new trace when it is received at the next Traefik ingress point.
The problem actually was with the traceContextHeaderName. Sadly I can not tell exactly what the problem was as the git diff only shows that nothing changed around traefik and jaeger at the point where I fixed it. I assume config got "stuck" somehow. I tracked down the related lines in source, but as I am no Go-Dev, I can only guess if there's a bug.
What I did was to switch back to uber-trace-id, which magically "fixed" it. After I ran some traces and connected another service (node, npm jaeger-client with process.env.TRACER_STATE_HEADER_NAME set to an equal value), I switched back to traefik-trace-id and things worked.

Use traefik middleware globally

i am trying to declare https redirect inside the traefik.yml file. For now i tried to add those rules inside the traefik service in docker-compose.yml. That worked like a charm. Although i'd prefer to configure this global and middleware redirect inside the traefik.yml file and then just reference it in the traefik service on docker-compose.yml.
What i had before
version: '3'
networks:
web:
external: true
services:
traefik:
image: traefik:v2.1
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./.traefik/traefik.yml:/traefik.yml
- ./.traefik/acme.json:/acme.json
networks:
- web
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`$HOSTNAME`)"
- "traefik.http.routers.traefik.service=api#internal"
- "traefik.http.routers.traefik.tls.certresolver=le"
- "traefik.http.routers.traefik.entrypoints=https"
# Global redirect to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
# Middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
That worked easily and redirected all other domains from http to https.
What i want now
I want to declare those redirects inside the traefik.yml.
So far i have done this.
api: {}
entryPoints:
http:
address: ":80"
https:
address: ":443"
log:
level: DEBUG
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: web
http:
# Global redirect to https
routers:
http-catchall:
rule: hostregexp(`{host:.+}`)"
entrypoints:
http
middlewares:
- redirect-to-https
# Middleware redirect
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
certificatesResolvers:
le:
acme:
email: john#doe.com
storage: acme.json
# Activate for Development: Certificate will not be valid. It's only for testing if it can be obtained.
#caServer: https://acme-staging-v02.api.letsencrypt.org/directory
httpChallenge:
entryPoint: http
As you can see i declared the http settings.
My question is now how can i reference those settings into my traefik service?
I tried it with
- "traefik.http.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https"
- "traefik.http.middlewares.traefik=redirect-to-https#file"
None of them work. Some show the middleware in the dashboard but it is not linked to any settings.
Did anyone find a solution to this? I can't get out anything from the docs about this. I think it must be linked somehow to the #file.
Thank you
#file means that the middleware was defined in the file provider.
You can add a file provider like this in traefik.yml.
providers:
file:
directory: "/path/to/dynamic/conf"
Create a file in that directory with the middleware.
http:
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
You can now reference redirect-to-https#file in your labels.
- "traefik.http.middlewares.traefik=redirect-to-https#file"
NOTE: Some of your configuration in traefik.yml might need to be moved to your new yml file. I am new to Traefik and have not full knownlegde of why yet.
See the following sections in documentation:
https://docs.traefik.io/middlewares/overview/#provider-namespace
https://docs.traefik.io/providers/file/
In fact, you don't need to set this middleware to traefik in labels block. If you have such configuration in your traefik.yml:
http:
routers:
http-catchall:
rule: hostregexp(`{host:.+}`)
entrypoints:
- http
middlewares:
- redirect-to-https
middlewares:
redirect-to-https:
redirectScheme:
scheme: https
permanent: false
It means - all traffic which came to entrypoint http should use middleware redirect-to-https and be redirected to another entrypoint: https. This configuration is globally.
So, you just have to set your container to https entrypoint (as you did, in your example)
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=https"
- "traefik.http.routers.traefik.rule=Host(`traefik.mydomain.ua`)"
- "traefik.http.routers.traefik.tls=true"
- "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
- "traefik.http.routers.traefik.service=api#internal"

Resources