Traefik architecture:
- Providers [file, k8, docker](like plugins for configurations)
- Static & dynamic configuration
- EntryPoint (Frontend)
- Service (Backend)
- Routers - Rules Host(
example.com
), link entrypoint to the service - Middlewares (e.g. Compress) are optional
- Treafik starts with static config which points to the dynamic config
- Entrypoints binds to ip/address
- Service defines backend
- Touters maps entrypoint to service through rules
Static configurations include entry points and resolvers. Dynamic configurations includes services, routers and middlewares.
Traefik looks for traefik.yaml for config file.
docker network create web
cd docker-provider && docker-compose up
One config contains Features:
- Http Routing
- Https Routing
- Jaeger/Zipkin tracing support
- Middlewares:
- basic auth
- errorpages
- rate limiting
- http to https redirect
version: "3.7"
services:
whoami:
image: containous/whoami
container_name: "whoami"
labels:
### whoami router
traefik.enable: true
traefik.http.routers.whoami.entrypoints: web
traefik.http.routers.whoami.rule: Host(`whoami.$MY_DOMAIN`)
### https-redirect middleware
traefik.http.routers.whoami.middlewares: traefik-https-redirect
### whoami-secure router
traefik.http.routers.whoami-secure.entrypoints: websecure
traefik.http.routers.whoami-secure.rule: Host(`whoami.$MY_DOMAIN`)
traefik.http.routers.whoami-secure.tls: true
traefik.http.routers.whoami-secure.tls.certresolver: web
traefik.http.routers.whoami-secure.middlewares: errorpages,ratelimit
networks:
- web
depends_on:
- traefik
nginx:
image: nginx:latest
container_name: "nginx"
labels:
### nginx router
traefik.enable: true
traefik.http.routers.nginx.entrypoints: web
traefik.http.routers.nginx.rule: Host(`hello.$MY_DOMAIN`)
### https-redirect middleware
traefik.http.routers.nginx.middlewares: traefik-https-redirect
### nginx-secure router
traefik.http.routers.nginx-secure.entrypoints: websecure
traefik.http.routers.nginx-secure.rule: Host(`hello.$MY_DOMAIN`)
traefik.http.routers.nginx-secure.tls: true
traefik.http.routers.nginx-secure.tls.certresolver: web
traefik.http.routers.nginx-secure.middlewares: errorpages,ratelimit
volumes:
- "./index.html:/usr/share/nginx/html/index.html:ro"
networks:
- web
depends_on:
- traefik
traefik:
image: traefik:v2.2.1
hostname: traefik
container_name: traefik
command:
- "--accesslog=true"
- "--accesslog.filepath=access.log"
- "--accesslog.bufferingsize=100"
- "--log.level=ERROR"
- "--api.insecure=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.web.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.web.acme.email=$ACME_EMAIL"
- "--certificatesresolvers.web.acme.storage=acme.json"
- "--tracing.jaeger=true"
- "--tracing.jaeger.samplingServerURL=http://jaeger:5778/sampling"
- "--tracing.jaeger.localAgentHostPort=jaeger:6831"
#- "--tracing.zipkin=true"
#- "--tracing.zipkin.httpEndpoint=http://zipkin:9411/api/v2/spans"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./usersfile:/data/usersfile:ro"
- "./acme.json:/acme.json"
networks:
- web
labels:
### traefik router
traefik.enable: true
traefik.http.routers.api.rule: Host(`traefik.$MY_DOMAIN`)
traefik.http.routers.api.service: api@internal
### basicauth middleware
traefik.http.routers.traefik.middlewares: traefik-auth
traefik.http.routers.traefik-secure.middlewares: traefik-auth,errorpages,ratelimit
traefik.http.middlewares.traefik-auth.basicauth.usersfile: /data/usersfile
### https-redirect middleware
traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme: https
traefik.http.routers.traefik.middlewares: traefik-https-redirect
### nginx-secure router
traefik.http.routers.traefik-secure.entrypoints: websecure
traefik.http.routers.traefik-secure.rule: Host(`traefik.$MY_DOMAIN`)
traefik.http.routers.traefik-secure.tls: true
traefik.http.routers.traefik-secure.tls.certresolver: web
traefik.http.routers.traefik-secure.service: api@internal
### errorpages middleware
traefik.http.middlewares.errorpages.errors.status: 400-599
traefik.http.middlewares.errorpages.errors.service: error
traefik.http.middlewares.errorpages.errors.query: /{status}.html
### rate limiting middleware
traefik.http.middlewares.ratelimit.ratelimit.average: 8
depends_on:
- error
jaeger:
image: jaegertracing/all-in-one:latest
container_name: jaeger
ports:
- "5775:5775/udp"
- "6831:6831/udp"
- "6832:6832/udp"
- "5778:5778"
# - "16686:16686"
- "14268:14268"
- "9411:9411"
labels:
### jaeger service
traefik.http.services.jaeger.loadbalancer.server.port: 16686
traefik.http.routers.jaeger.service: jaeger
### jaeger router
traefik.enable: true
traefik.http.routers.jaeger.entrypoints: web
traefik.http.routers.jaeger.rule: Host(`jaeger.$MY_DOMAIN`)
### jaeger-secure router
traefik.http.routers.jaeger-secure.entrypoints: websecure
traefik.http.routers.jaeger-secure.rule: Host(`jaeger.$MY_DOMAIN`)
traefik.http.routers.jaeger-secure.tls: true
traefik.http.routers.jaeger-secure.tls.certresolver: web
### basicauth middleware
traefik.http.routers.jaeger.middlewares: traefik-auth
traefik.http.routers.jaeger-secure.middlewares: traefik-auth,errorpages,ratelimit
### https-redirect middleware
traefik.http.routers.jaeger.middlewares: traefik-https-redirect
networks:
- web
# environment:
# COLLECTOR_ZIPKIN_HTTP_PORT: 9411
depends_on:
- traefik
hotrod:
image: jaegertracing/example-hotrod:1.17
command: all
container_name: hotrod
labels:
### hotrod service
traefik.http.routers.hotrod.service: hotrod
traefik.http.services.hotrod.loadbalancer.server.port: 8080
### hotrod router
traefik.enable: true
traefik.http.routers.hotrod.entrypoints: web
traefik.http.routers.hotrod.rule: Host(`hot.$MY_DOMAIN`)
### basicauth middleware
traefik.http.routers.hotrod.middlewares: traefik-auth
traefik.http.routers.hotrod-secure.middlewares: traefik-auth
### https-redirect middleware
traefik.http.routers.hotrod.middlewares: traefik-https-redirect
### hotrod-secure router
traefik.http.routers.hotrod-secure.entrypoints: websecure
traefik.http.routers.hotrod-secure.rule: Host(`hot.$MY_DOMAIN`)
traefik.http.routers.hotrod-secure.tls: true
traefik.http.routers.hotrod-secure.middlewares: errorpages,ratelimit
traefik.http.routers.hotrod-secure.tls.certresolver: web
environment:
JAEGER_AGENT_HOST: "jaeger"
JAEGER_AGENT_PORT: "6831"
networks:
- web
depends_on:
- traefik
- jaeger
# zipkin:
# image: openzipkin/zipkin-slim
# container_name: "zipkin"
# labels:
# ### zipkin service
# traefik.http.services.zipkin.loadbalancer.server.port: 9411
# traefik.http.routers.zipkin.service: zipkin
# ### zipkin router
# traefik.enable: true
# traefik.http.routers.zipkin.entrypoints: web
# traefik.http.routers.zipkin.rule: Host(`zipkin.$MY_DOMAIN`)
# ### basicauth middleware
# traefik.http.routers.zipkin.middlewares: traefik-auth
# traefik.http.routers.zipkin-secure.middlewares: traefik-auth
# ### https-redirect middleware
# traefik.http.routers.zipkin.middlewares: traefik-https-redirect
# ### zipkin-secure router
# traefik.http.routers.zipkin-secure.entrypoints: websecure
# traefik.http.routers.zipkin-secure.rule: Host(`zipkin.$MY_DOMAIN`)
# traefik.http.routers.zipkin-secure.tls: true
# traefik.http.routers.zipkin-secure.tls.certresolver: web
# networks:
# - web
# ports:
# - "9411:9411"
# depends_on:
# - traefik
portainer:
image: portainer/portainer
container_name: portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- portainer_data:/data
labels:
### portainer router
traefik.enable: true
traefik.http.routers.portainer.entrypoints: web
traefik.http.routers.portainer.rule: Host(`portainer.$MY_DOMAIN`)
### basicauth middleware
traefik.http.routers.portainer.middlewares: traefik-auth
### https-redirect middleware
traefik.http.routers.portainer.middlewares: traefik-https-redirect
### portainer-secure router
traefik.http.routers.portainer-secure.entrypoints: websecure
traefik.http.routers.portainer-secure.rule: Host(`portainer.$MY_DOMAIN`)
traefik.http.routers.portainer-secure.tls: true
traefik.http.routers.portainer-secure.middlewares: traefik-auth,errorpages,ratelimit
traefik.http.routers.portainer-secure.tls.certresolver: web
networks:
- web
depends_on:
- traefik
error:
container_name: error
image: guillaumebriday/traefik-custom-error-pages
labels:
traefik.enable: true
traefik.http.routers.error.rule: Host(`error.$MY_DOMAIN`)
traefik.http.routers.error.service: error
traefik.http.services.error.loadbalancer.server.port: 80
traefik.http.routers.error.entrypoints: web
networks:
- web
networks:
web:
external: true
volumes:
portainer_data:
external: true
## Load balancing between two servers
## see all.yaml
http:
routers:
allBackendRouter:
rule: "Host(`$MY_DOMAIN`)"
service: allBackend
services:
allBackend:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:1111/"
- url: "http://$MY_DOMAIN:2222/"
## Passing load through path
## see split.yaml
http:
routers:
allbackendrouter:
rule: "Host(`$MY_DOMAIN`) && Path(`/`)"
service: allbackend
app1router:
rule: "Host(`$MY_DOMAIN`) && Path(`/app1`)"
service: app1backend
app2router:
rule: "Host(`$MY_DOMAIN`) && Path(`/app2`)"
service: app2backend
services:
app1backend:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:1111/"
app2backend:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:2222/"
allbackend:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:1111/"
- url: "http://$MY_DOMAIN:2222/"
## Block destination endpoint by Path
## see blockadmin.yaml
http:
routers:
allBackendRouter:
rule: "Host(`$MY_DOMAIN`)"
service: allBackend
adminblocker:
rule: "Host(`$MY_DOMAIN`) && Path(`/admin`)"
service: blackhole
services:
blackhole:
loadBalancer:
servers:
allBackend:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:1111/"
- url: "http://$MY_DOMAIN:2222/"
## Weighted Round Robin
## see wrrr.yaml
http:
routers:
allbackendrouter:
rule: "Host(`$MY_DOMAIN`)"
service: wrr
services:
wrr:
weighted:
services:
- name: backend1
weight: 5
- name: backend2
weight: 1
backend1:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:1111/"
backend2:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:2222/"
tcp:
routers:
allBackendRouter:
rule: "HostSNI(`*`)"
service: allBackend
services:
allBackend:
loadBalancer:
servers:
- address: "$MY_DOMAIN:1111"
- address: "$MY_DOMAIN:2222"
## Jaeger tracing
tracing:
jaeger:
localAgentHostPort: 127.0.0.1:6831
## Basic Authorization
http:
routers:
allBackendRouter:
rule: "Host(`$MY_DOMAIN`)"
service: allBackend
allBackendRouterSecured:
entryPoints:
- http
middlewares:
- auth
rule: "(PathPrefix(`/dashboard`) || PathPrefix(`/api`))"
service: api@internal
services:
allBackend:
loadBalancer:
servers:
- url: "http://$MY_DOMAIN:1111/"
- url: "http://$MY_DOMAIN:2222/"
passHostHeader: false
middlewares:
auth:
basicAuth:
users:
- "admin:{SHA}2iRQKCF1byRkk6qCLh1AdHhU1tQ="