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.yamlor it can get defined inside ofdocker-compose labels sectionEntrypoints 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
routerandservice, 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