Skip to content

Instantly share code, notes, and snippets.

@Voronenko
Last active May 2, 2023 13:18
Show Gist options
  • Save Voronenko/0db47595a0395b742db76262be45e0c4 to your computer and use it in GitHub Desktop.
Save Voronenko/0db47595a0395b742db76262be45e0c4 to your computer and use it in GitHub Desktop.
traefik behind traefik
MY_DOMAIN1=<domain for Traefik1's dashboard>
TRAEFIK1_NET=traefik1_net
CF_API_EMAIL=<your CF API email>
CF_ZONE_API_TOKEN=<your Zone API Token>
CF_DNS_API_TOKEN=-<your DNS token>
TRAEFIK2_DNS_MAPPER=traefik2:<static ip of traefik2 in NET1>
TAEAFIK2_HOST_SNI=`traefik.<Traefik2's dashboard domain>`
TRAEFIK2_NET1_ADDRESS=traefik2:443
MY_DOMAIN2=<domain for Traefik2's dashboard>
TRAEFIK1_NET=traefik1_net
TRAEFIK2_NET=traefik2_net
TRAEFIK2_NET1_IPV4=<static ip of traefik2 in NET1>
# this .env file should not be used for substitution in docker-compose.yml as the environment variables will only be available in the running container
CF_API_EMAIL=<your CF API email>
CF_ZONE_API_TOKEN=<your Zone API Token>
CF_DNS_API_TOKEN=-<your DNS token>

I am using separate domains for the Traefik1 and Traefik2 dashboards. Traefik1 is using a TCP router to forward requests to Traefik2, as requests are still encrypted when passing through Traefik1. I am using constraints to limit the containers each Traefik instance creates routes for. I already created a second network in order to demonstrate the isolation of each proxy's "subcontainers"

version: "3.3"
services:
traefik1:
image: "traefik:v2.6.1"
container_name: "traefik1"
restart: "always"
hostname: "traefik1"
ports:
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./dynamic.yml:/dynamic.yml:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./acme.json:/acme.json"
labels:
- "my.zone=zone1"
- "traefik.enable=true"
- "traefik.http.routers.traefik1.entrypoints=websecure"
- "traefik.http.routers.traefik1.tls.certresolver=lets-encr"
- "traefik.http.routers.traefik1.tls.domains[0].main=traefik.$MY_DOMAIN1"
- "traefik.http.routers.traefik1.rule=Host(`traefik1.$MY_DOMAIN1`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.traefik1.service=api@internal"
# adding DNS mapping to /etc/hosts in order to avoid Traefik issues in case of wrong container starting order
extra_hosts:
- "$TRAEFIK2_DNS_MAPPER"
# used to pass environment variables into the container in order to support environment substition in traefik files
env_file:
- ".env1"
networks:
default:
external:
name: $TRAEFIK1_NET
version: '3.3'
services:
traefik2:
image: "traefik:v2.6.1"
container_name: "traefik2"
restart: "always"
hostname: "treafik2"
env_file:
- ".env_traefik2"
ports:
- "443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/traefik.yml:ro"
- "./acme.json:/acme.json"
labels:
- "my.zone=zone2"
- "traefik.enable=true"
- "traefik.http.routers.traefik2.entrypoints=websecure"
- "traefik.http.routers.traefik2.tls.certresolver=lets-encr"
- "traefik.http.routers.traefik2.tls.domains[0].main=traefik.$MY_DOMAIN2"
- "traefik.http.routers.traefik2.rule=Host(`traefik.$MY_DOMAIN2`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
- "traefik.http.routers.traefik2.service=api@internal"
networks:
traefik1_net:
ipv4_address: $TRAEFIK2_NET1_IPV4
traefik2_net: null
networks:
traefik1_net:
external:
name: $TRAEFIK1_NET
traefik2_net:
external:
name: $TRAEFIK2_NET
tcp:
routers:
to_traefik2:
entrypoints:
- "websecure"
rule: HostSNI({{ env "TRAEFIK2_HOST_SNI" }})
tls:
passthrough: true
service: traefik2
services:
traefik2:
loadBalancer:
servers:
- address: {{ env "TRAEFIK2_NET1_ADDRESS" }}
## STATIC CONFIGURATION
log:
level: INFO
api:
insecure: false
dashboard: true
entryPoints:
websecure:
address: ":443"
providers:
file:
filename: dynamic.yml
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
constraints: Label(`my.zone`, `zone1`)
certificatesResolvers:
lets-encr:
acme:
email: <your email>
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
## STATIC CONFIGURATION
log:
level: INFO
api:
insecure: false
dashboard: true
entryPoints:
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
constraints: Label(`my.zone`, `zone2`)
certificatesResolvers:
lets-encr:
acme:
email: <your email>
storage: acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment