Traefik
Docker Compose
Firstly start be creating a docker-compose.yaml
file, which will be used to hold the configuration for Traefik
.
Traefik Docker Compose
Below is an example docker compose file that has been used to host a variety of services within docker containers.
version: '3.9'networks: frontend: external: true backend: external: trueservices: traefik: container_name: traefik image: traefik:v3.1.4 ports: - 80:80 - 443:443 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./config/traefik/:/etc/traefik/ networks: - frontend - backend command: - '--api.dashboard=true' - '--log.level=INFO' - '--accesslog=true' - '--providers.docker=true' - '--providers.docker.exposedByDefault=false' - '--providers.docker.network=frontend' - '--providers.docker.network=backend' - '--entrypoints.http=true' - '--entrypoints.http.address=:80' - '--entrypoints.https=true' - '--entrypoints.https.address=:443' - '--entrypoints.https.address=:27017' # mongodb # below is en-gb IPv4 Cloudflare IPs from https://www.cloudflare.com/en-gb/en-en/ips/ - '--entryPoints.web.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22' - '--certificatesresolvers.myresolver.acme.email=' - '--certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme.json' - "--certificatesresolvers.myresolver.acme.dnschallenge=true" - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" - '--certificatesresolvers.myresolverr53.acme.email=' - '--certificatesresolvers.myresolverr53.acme.storage=/etc/traefik/acme.json' - "--certificatesresolvers.myresolverr53.acme.dnschallenge=true" - "--certificatesresolvers.myresolverr53.acme.dnschallenge.provider=route53" - "--metrics.prometheus=true" # - "--metrics.add.internals" - "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0" - "--metrics.prometheus.addEntryPointsLabels=true" - "--metrics.prometheus.addrouterslabels=true" - "--metrics.prometheus.addServicesLabels=true" - "--entryPoints.metrics.address=:8899" - "--metrics.prometheus.entryPoint=metrics" environment: - "CF_DNS_API_TOKEN=" - "AWS_ACCESS_KEY_ID=" - "AWS_SECRET_ACCESS_KEY=" labels: - traefik.enable=true - traefik.http.routers.mydashboard.rule=Host(`traefik.<domain>`) - traefik.http.routers.mydashboard.entrypoints=https - traefik.http.routers.mydashboard.tls=true - traefik.http.routers.mydashboard.tls.certresolver=myresolver - traefik.http.routers.mydashboard.service=api@internal - traefik.http.routers.mydashboard.middlewares=myauth restart: unless-stopped
whoami-proxy: image: ghcr.io/goauthentik/proxy ports: - 9000:9000 - 9443:9443 environment: AUTHENTIK_HOST: https://authentik.<domain> AUTHENTIK_INSECURE: "false" AUTHENTIK_TOKEN: # Starting with 2021.9, you can optionally set this too # when authentik_host for internal communication doesn't match the public URL # AUTHENTIK_HOST_BROWSER: https://external-domain.tld labels: traefik.enable: true traefik.port: 9000 traefik.http.routers.authentik.rule: Host(`<domain>`) && PathPrefix(`/outpost.goauthentik.io/`) # `authentik-proxy` refers to the service name in the compose file. traefik.http.middlewares.authentik.forwardauth.address: http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version restart: unless-stopped
whoami: image: traefik/whoami:v1.10.3 container_name: whoami networks: - frontend - backend labels: - traefik.enable=true - traefik.http.routers.whoami.rule=Host(`whoami.<domain>`) # - traefik.http.routers.whoami.middlewares=authentik@docker - traefik.http.services.whoami.loadbalancer.server.port=80 - traefik.http.routers.whoami.entrypoints=https - traefik.http.routers.whoami.tls=true - traefik.http.routers.whoami.tls.certresolver=myresolver - traefik.http.routers.whoami.service=whoami - traefik.http.services.whoami.loadbalancer.server.scheme=http - "--certificatesresolvers.myresolver.acme.dnschallenge=true" - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" # - traefik.http.middlewares.mywwwredirect.redirectregex.regex=^https://www\.(.*) # - traefik.http.middlewares.mywwwredirect.redirectregex.replacement=https://$${1} # - traefik.http.routers.mywhoami.middlewares=mywwwredirect restart: unless-stopped
Components
Note: all the configuration above, is done using “Labels” which are part of the documentation provided by Traefik on their official website. The labels are an alternative to using the traefik.yaml
file
- Ports : Exposes HTTP (80), HTTPS (443)
- Volumes: Configuration storage / acccess should it be required without having to access the container directly.
- Docker Socket for container management
--certificatesresolvers.myresolver.acme.storage
for SSL certificate storage- Network custom networks that are used throughout the rest of the docker containers deployed behind traefik.
- environment specific configuration that is defined to access relevant services, required by Traefik in order to function.
- whoami is a “test” container that displays a variety of information, used for troubleshooting.
Creating the Networks
Before deploying, networks need to be created using the Docker CLI:
docker network create frontend
docker network create backend
Traefik Configuration (traefik.yaml)
global: checkNewVersion: false sendAnonymousUsage: false
certificatesResolvers: route53: acme: email: <email> storage: /etc/traefik/certs/route53-acme.json caServer: 'https://acme-v02.api.letsencrypt.org/directory' keyType: EC256 dnsChallenge: provider: route53 resolvers: - "1.1.1.1:53" - "8.8.8.8:53"
Important Notes
- ACME Configuration - Primarily for HTTPS, Traefik will communicate with Lets Encrypt to obtain, issue and renew certificates as needed.
- email - Used for any important communications from Lets Encrypt notifications.
Preparing acme.json
Create an empty acme.json
file with restricted permissions to securely store SSL certificates. Based on the above configuration this needs to be created in the ./config/traefik
folder.
touch acme.jsonchmod 600 acme.json
Steps above are crucial to make sure that SSL certificates are kept securely and confidential.
Deploy Traefik
With configuration completed (acme.json
), and the docker networks created, deploy Traefik using Docker Compose:
docker compose up -d
Securing Services with HTTPS: Example
Deploying traefik’s whoami container, using traefik labels to enable HTTPs.
Docker Compose for Traefik Whoami container
whoami: image: traefik/whoami:v1.10 container_name: whoami networks: - frontend - backend labels: - traefik.enable=true - traefik.http.routers.whoami.rule=Host(`whoami.<domain>`) - traefik.http.services.whoami.loadbalancer.server.port=80 - traefik.http.routers.whoami.entrypoints=https - traefik.http.routers.whoami.tls=true - traefik.http.routers.whoami.tls.certresolver=myresolver - traefik.http.routers.whoami.service=whoami - traefik.http.services.whoami.loadbalancer.server.scheme=http - "--certificatesresolvers.myresolver.acme.dnschallenge=true" - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" restart: unless-stopped
Highlights
- Labels: Configure routing rules, entry points, certificate resolver (SSL / TLS), Loadbalancer (Access via Traefik), DNS Challenge (endpoint / service has a valid dns record, controlled through Cloudflare)
- Networks: Ensures that Traefik’s Whoami container has the correct network access, which allows Traefik to provide the proper routing.
- Metrics: Metrics have now been added as of 15/12/2024, which are scraped as part of the Grafana configuration.
Deployment Steps
- Prepare Configuration Files: Create an empty
acme.json
with restrictive permissions (chmod 600 acme.json
) and update theLabels
on the above docker compose example as required. - Deploy Traefik: Use
docker compose up -d
in the directoy containing the above traefik docker compose filedocker-compose.yaml
3.Verify Traefik Operation: Check if the Dashboard can be accessed. Configuration has been removed from the above example, so it will need to be added according to the official documentation supplied by Traefik themselves. 4.Deploy Services: Repeat the Deployment Steps for additional services required, ensuring that the appropriate labels from Traefik are included.