Try to understand what is traefik and Try to use its forward auth module
The official website
https://doc.traefik.io/traefik/
Trust me, you would learn nothing from there.
Clear Responsibilities
Providers is the ‘config file’ for traefik, it can be defined in a single file called
traefik_dynamic_config.yaml
or it can get defined inside ofdocker-compose labels section
Entrypoints listen for incoming traffic (ports, http(web), https(websecure))
Routers defines the rules to forward different requests to different services (by host-domain, URL path, headers and so on…)
Middlewares is in the middle of
router
andservice
, it can be used to modify the request URL, headers, or simply drop the request based on some condition (header authentication, rate limiting, and so on…)Services defines the service URL,
http://**
orh2c://**
(you could also define load balancing here)
Still in struggling? Watch the video below.
Video Tutorial
https://www.youtube.com/watch?v=Gk9WER6DunE&ab_channel=AFKDeveloper
Let’s see if we can understand its forward auth
example (I wrote it)
#docker-compose.yml
version: "3.9"
services:
traefik:
image: "traefik:v2.9.6"
restart: unless-stopped
container_name: traefik
ports:
- "80:80" # <== http
- "443:443" # <== https
- "8080:8080" # <== :8080 is where the dashboard(config info table) runs on
command:
- "--log.level=DEBUG"
- "--api.insecure=true" # <== Set to false in PRODUCTION!
- "--providers.file.directory=/traefik_dynamic_configs" # <== config_folder
- "--providers.file.watch=true" # <== when you change config yaml file, it will do a reload automaticlly
- "--providers.docker=true" # <== also use docker-compose's label config
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik_dynamic_configs:/traefik_dynamic_configs" # <== Volume for dynamic conf file
whoami:
image: "traefik/whoami"
expose: #expose port to other container by using http://whoami:80
- "80"
labels:
- "traefik.enable=true" # <== Enable traefik to proxy this container
- "traefik.http.routers.whoami_config.rule=Host(`whoami.yingshaoxo.xyz`)" # <== Your Sub Domain Name
# - "traefik.http.routers.whoami_config.rule=PathPrefix(`/auth`)" # an alternative, may be yingshaoxo.xyz/auth
# - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/auth" # define a middleware
# - "traefik.http.routers.whoami_config.middlewares=test-stripprefix" # <== use that middleware
- "traefik.http.middlewares.whatevername.forwardauth.address=http://host.docker.internal:1110/auth" # <== This defines a middleware for the auth, it was written by python
- "traefik.http.routers.whoami_config.middlewares=whatevername" # <== Use the middleware defined above. If you want to use two middleware, use ',' to separate them, like 'middleware1, middleware2'
- "traefik.http.services.whoami_config.loadbalancer.server.scheme=http"
- "traefik.http.services.whoami_config.loadbalancer.server.port=80" # define the final service, which is 127.0.0.1:80 in this container
# ./traefik_dynamic_configs/dynamic.yaml
# https://doc.traefik.io/traefik/providers/file/#configuration-examples
http:
routers:
whoami_router:
entryPoints:
- web
- websecure
# rule: "Host(`whoami.yingshaoxo.xyz`)"
rule: PathPrefix(`/whoami`) # yingshaoxo.xyz/whoami
middlewares:
- test-stripprefix
service: service_whoami
middlewares:
test-stripprefix:
stripPrefix:
prefixes:
- "/whoami"
services:
service_whoami:
loadBalancer:
servers:
- url: http://whoami:80
passHostHeader: true
#auth.py
from flask import Flask, request
app = Flask(__name__)
@app.route("/auth")
def index():
print(request.headers)
return "Hello World!"
if __name__ == '__main__':
#suppose it serves at http://host.docker.internal:1110/auth
#which is at the host machine related to the docker container
app.run(host="0.0.0.0", port="1110", debug=True)
Change the hosts file to simulate the DNS behavior:
#/etc/hosts
127.0.0.1 yingshaoxo.xyz whoami.yingshaoxo.xyz
Run the python file, then run docker-compose:
python auth.py &
docker-compose up
Run the following command, you shall see the python script print something out from the traefik
:
# no forward auth
curl yingshaoxo.xyz/whoami/
Run the following command, you shall see the python script also print something out from the traefik
:
# have forward auth
curl whoami.yingshaoxo.xyz
If you still couldn’t understand
Give up on it, it’s not on your level
But for me, I never give up.
Here are some config files I use for GRPC:
#docker-compose
version: "3.9"
services:
traefik:
image: "traefik:v2.9.6"
container_name: "traefik"
command:
# - "--accesslog=true"
# - "--accessLog.filePath=/tmp/traefik_log.txt"
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.file.directory=/traefik_dynamic_configs"
- "--providers.file.watch=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./configs/traefik_dynamic_configs:/traefik_dynamic_configs" # <== Volume for dynamic conf file
dragonfly:
image: docker.dragonflydb.io/dragonflydb/dragonfly
ports:
- '6379:6379'
restart: unless-stopped
# whoami:
# image: "traefik/whoami"
# expose: #expose port to other container by using http://whoami:80
# - "80"
# restart: unless-stopped
weloveparty_account_auth_service:
build:
context: ../python_user_auth_system
dockerfile: ./Dockerfile
image: yingshaoxo/weloveparty_account_auth_service
expose:
- "40051"
- "40052"
# ports:
# - "40051:40051"
# - "40052:40052"
volumes:
- type: bind
source: ./configs/o365_token.txt
target: /code/o365_token.txt
- type: bind
source: ./configs/config.py
target: /code/src/config.py
- ./configs/user_database:/code/data
environment:
- redis_network_name=dragonfly
restart: unless-stopped
# labels:
# - "traefik.enable=true"
# - "traefik.http.routers.gost-grpc.tls=false"
# - "traefik.http.routers.gost-grpc.rule=Host(`auth.weloveparty.domain.local`)"
# - "traefik.http.services.gost-grpc.loadbalancer.server.port=40052"
# - "traefik.http.services.gost-grpc.loadbalancer.server.scheme=h2c"
#./configs/traefik_dynamic_configs/traefik_dynamic_config.yaml
http:
routers:
grpc_auth_router:
entryPoints:
- web
- websecure
# rule: "Host(`auth.weloveparty.domain.local`)"
rule: PathPrefix(`/auth`)
middlewares:
- test-stripprefix
service: weloveparty_account_auth_service
middlewares:
test-stripprefix:
stripPrefix:
prefixes:
- "/auth"
services:
weloveparty_account_auth_service:
loadBalancer:
servers:
- url: h2c://weloveparty_account_auth_service:40052
# - url: h2c://host.docker.internal:40052
passHostHeader: true
# /etc/hosts
127.0.0.1 weloveparty.domain.local auth.weloveparty.domain.local