If you're lucky, someone else in your organization may have already configured Traefik , an HTTP reverse proxy and load balancer for microservices. Otherwise, you can follow their tutorial to quickly launch the application with docker-compose.
But, if you are ready to improve your installation, you can read the official documentation . Or, if you are like me, you may want to check other people's setups. 😉
I have decided to share with you my personal configuration of Traefik below. It can inspire you to explore concepts that you are not yet familiar with. I won't particularly describe each instruction, so if in doubt, check their documentation! 🤷
This configuration below is made for Docker Swarm and all files are written in YAML. If your configuration is in TOML format, you should be able to switch easily between them.
Static configuration (traefik.yml)
# Traefik static configuration file (/etc/traefik/traefik.yml)
# See https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-static-configuration
# and https://doc.traefik.io/traefik/reference/static-configuration/cli/
api :
dashboard : true # Enable the dashboard
# Certificate Resolvers are responsible for retrieving certificates from an ACME server
# See https://doc.traefik.io/traefik/https/acme/#certificate-resolvers
certificatesResolvers :
letsEncrypt :
acme :
email : " letsEncrypt@benjaminrancourt.ca" # Email address used for registration
storage : " /etc/traefik/acme/acme.json" # File or key used for certificates storage
tlsChallenge : {}
entryPoints :
http :
address : " :80" # Create the HTTP entrypoint on port 80
http :
redirections : # HTTPS redirection (80 to 443)
entryPoint :
to : " https" # The target element
scheme : " https" # The redirection target scheme
https :
address : " :443" # Create the HTTPS entrypoint on port 443
global :
checknewversion : true # Periodically check if a new version has been released.
sendanonymoususage : true # Periodically send anonymous usage statistics.
providers :
docker :
endpoint : " unix:///var/run/docker.sock" # Listen to the UNIX Docker socket
exposedByDefault : false # Only expose container that are explicitly enabled (using label traefik.enabled)
network : " traefik-net" # Default network to use for connections to all containers.
swarmmode : true # Activates the Swarm Mode (instead of standalone Docker).
swarmModeRefreshSeconds : 15 # Defines the polling interval (in seconds) in Swarm Mode.
watch : true # Watch Docker Swarm events
file :
filename : " /etc/traefik/config.yml" # Link to the dynamic configuration
watch : true # Watch for modifications
providersThrottleDuration : 10 # Configuration reload frequency
Enter fullscreen mode
Exit fullscreen mode
The static configuration file, in the traefik.yml
file.
Dynamic configuration (config.yml)
Psst, if you want to replace a value from any of the middleware below, check out my post titled How to override an HTTP header in Traefik !
# Traefik dynamic configuration file
# See https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-dynamic-configuration
http :
middlewares :
# A basic authentification middleware, to protect the Traefik dashboard to anyone except myself
# Use with traefik.http.routers.myRouter.middlewares: "traefikAuth@file"
traefikAuth :
basicAuth :
users :
- " admin:PASSWORD_HASHED"
# Recommended default middleware for most of the services
# Use with traefik.http.routers.myRouter.middlewares: "default@file"
# Equivalent of traefik.http.routers.myRouter.middlewares: "default-security-headers@file,error-pages@file,gzip@file"
default :
chain :
middlewares :
- default-security-headers
- error-pages
- gzip
# Add automatically some security headers
# Use with traefik.http.routers.myRouter.middlewares: "default-security-headers@file"
default-security-headers :
headers :
browserXssFilter : true # X-XSS-Protection=1; mode=block
contentTypeNosniff : true # X-Content-Type-Options=nosniff
forceSTSHeader : true # Add the Strict-Transport-Security header even when the connection is HTTP
frameDeny : true # X-Frame-Options=deny
referrerPolicy : " strict-origin-when-cross-origin"
sslRedirect : true # Allow only https requests
stsIncludeSubdomains : true # Add includeSubdomains to the Strict-Transport-Security header
stsPreload : true # Add preload flag appended to the Strict-Transport-Security header
stsSeconds : 63072000 # Set the max-age of the Strict-Transport-Security header (63072000 = 2 years)
# Serve the error pages when the status is included inside the following ranges
# Use with traefik.http.routers.myRouter.middlewares: "error-pages@file"
error-pages :
errors :
query : " erreur{status}/"
service : traefik-error-pages
status :
- " 403-404"
- " 500"
- " 503"
# Enables the GZIP compression (https://docs.traefik.io/middlewares/compress/)
# if the response body is larger than 1400 bytes
# if the Accept-Encoding request header contains gzip
# if the response is not already compressed (Content-Encoding is not set)
# Use with traefik.http.routers.myRouter.middlewares: "gzip@file"
gzip :
compress : {}
services :
# Error pages
traefik-error-pages :
loadBalancer :
servers :
- url : " https://www.usherbrooke.ca/error-pages/"
# See https://doc.traefik.io/traefik/https/tls/
tls :
options :
# To use with the label "traefik.http.routers.myrouter.tls.options=modern@file"
modern :
minVersion : " VersionTLS13" # Minimum TLS Version
sniStrict : true # Strict SNI Checking
# To use with the label "traefik.http.routers.myrouter.tls.options=intermediate@file"
intermediate :
cipherSuites :
- " TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
- " TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- " TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
- " TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
- " TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
- " TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
minVersion : " VersionTLS12" # Minimum TLS Version
sniStrict : true # Strict SNI Checking
# To use with the label "traefik.http.routers.myrouter.tls.options=old@file"
old :
cipherSuites :
- " TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
- " TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- " TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
- " TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
- " TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
- " TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
- " TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
- " TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
- " TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
- " TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
- " TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
- " TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
- " TLS_RSA_WITH_AES_128_GCM_SHA256"
- " TLS_RSA_WITH_AES_256_GCM_SHA384"
- " TLS_RSA_WITH_AES_128_CBC_SHA256"
- " TLS_RSA_WITH_AES_128_CBC_SHA"
- " TLS_RSA_WITH_AES_256_CBC_SHA"
- " TLS_RSA_WITH_3DES_EDE_CBC_SHA"
minVersion : " TLSv1" # Minimum TLS Version
sniStrict : true # Strict SNI Checking
# Generated 2021-08-12, Mozilla Guideline v5.6, Traefik 2.4.8
# https://ssl-config.mozilla.org/#server=traefik&version=2.4.8&config=old&guideline=5.6
# https://ssl-config.mozilla.org/#server=traefik&version=2.4.8&config=intermediate&guideline=5.6
Enter fullscreen mode
Exit fullscreen mode
The dynamic configuration file, in the config.yml
file.
docker-compose.yml
version : " 3.8"
services :
traefik :
deploy :
labels :
traefik.docker.network : " traefik-net"
traefik.enable : " true"
traefik.http.routers.traefik.entrypoints : " https"
traefik.http.routers.traefik.middlewares : " traefikAuth@file,default@file"
traefik.http.routers.traefik.rule : " Host(`${TRAEFIK_SUBDOMAIN}.${TRAEFIK_DOMAIN}`)"
traefik.http.routers.traefik.service : " api@internal"
traefik.http.routers.traefik.tls.certresolver : " letsEncrypt"
traefik.http.routers.traefik.tls.options : " modern@file"
traefik.http.routers.traefik.tls : " true"
traefik.http.services.traefik.loadbalancer.server.port : 8080
traefik.http.services.traefik.loadbalancer.sticky.cookie.httpOnly : " true"
traefik.http.services.traefik.loadbalancer.sticky.cookie.secure : " true"
mode : global
# Schedule Traefik on the Swarm manager nodes, as the Swarm API is only exposed on the manager nodes
# See https://docs.traefik.io/providers/docker/#docker-api-access_1
placement :
constraints :
- node.role == manager
# Published on https://hub.docker.com/_/traefik?tab=tags
image : traefik:2.4.8 # See https://github.com/containous/traefik/releases
networks :
- traefik-net
ports :
# To be able to listen on port 80 (http)
- mode : host
published : 80
target : 80
# To be able to listen on port 443 (https)
- mode : host
published : 443
target : 443
volumes :
- /etc/localtime:/etc/localtime:ro # Set the container timezone by sharing the read-only localtime
- /home/ranb2002/traefik/config.yml:/etc/traefik/config.yml:ro # Set the dynamic configuration for the file provider
- /home/ranb2002/traefik/traefik.yml:/etc/traefik/traefik.yml:ro # Set the static configuration
- /var/opt/traefik:/etc/traefik/acme # Set the location where my ACME certificates are saved to
- /var/run/docker.sock:/var/run/docker.sock:ro # Give access to the UNIX Docker socket
networks :
traefik-net :
driver : overlay
external : true
Enter fullscreen mode
Exit fullscreen mode
The docker-compose.yml
file for Traefik.
If you want an example of another application using the Traefik labels, check out the Code section of my Testing certificates generated by Traefik and Let's Encrypt post.
If you have any tips for improving this setup, let me know! 😎