1- # Lab 05 — Advanced Integration: traefik with full IT-Stack ecosystem
2- ---
31services :
2+
3+ # ── Keycloak DB ───────────────────────────────────────────────────
4+ kc-db :
5+ image : postgres:16-alpine
6+ environment :
7+ POSTGRES_DB : keycloak
8+ POSTGRES_USER : kcadmin
9+ POSTGRES_PASSWORD : Lab05Password!
10+ networks :
11+ - kc-db-net
12+ volumes :
13+ - kc-db-int:/var/lib/postgresql/data
14+ healthcheck :
15+ test : ["CMD-SHELL", "pg_isready -U kcadmin"]
16+ interval : 5s
17+ timeout : 3s
18+ retries : 20
19+
20+ # ── Keycloak SSO ──────────────────────────────────────────────────
21+ keycloak :
22+ image : quay.io/keycloak/keycloak:24.0
23+ command : start-dev
24+ depends_on :
25+ kc-db :
26+ condition : service_healthy
27+ environment :
28+ KC_BOOTSTRAP_ADMIN_USERNAME : admin
29+ KC_BOOTSTRAP_ADMIN_PASSWORD : Lab05Password!
30+ KC_DB : postgres
31+ KC_DB_URL : " jdbc:postgresql://kc-db:5432/keycloak"
32+ KC_DB_USERNAME : kcadmin
33+ KC_DB_PASSWORD : Lab05Password!
34+ KC_HTTP_PORT : " 8080"
35+ KC_HOSTNAME_STRICT : " false"
36+ KC_PROXY : edge
37+ networks :
38+ - proxy-int-net
39+ - kc-db-net
40+ healthcheck :
41+ test : ["CMD-SHELL", "curl -sf http://localhost:8080/health/ready || exit 1"]
42+ interval : 10s
43+ timeout : 5s
44+ retries : 30
45+ start_period : 60s
46+ labels :
47+ - " traefik.enable=true"
48+ - " traefik.http.routers.keycloak.rule=PathPrefix(`/realms`) || PathPrefix(`/admin/realms`)"
49+ - " traefik.http.routers.keycloak.entrypoints=web"
50+ - " traefik.http.services.keycloak.loadbalancer.server.port=8080"
51+
52+ # ── oauth2-proxy (ForwardAuth) ────────────────────────────────────
53+ oauth2-proxy :
54+ image : quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
55+ depends_on :
56+ keycloak :
57+ condition : service_healthy
58+ command :
59+ - --provider=oidc
60+ - --oidc-issuer-url=http://keycloak:8080/realms/it-stack
61+ - --client-id=oauth2-proxy
62+ - --client-secret=Lab05Password!
63+ - --cookie-secret=YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4
64+ - --email-domain=*
65+ - --upstream=static://202
66+ - --http-address=0.0.0.0:4180
67+ - --redirect-url=http://localhost:4180/oauth2/callback
68+ - --cookie-secure=false
69+ - --skip-jwt-bearer-tokens=true
70+ networks :
71+ - proxy-int-net
72+ labels :
73+ - " traefik.enable=true"
74+ - " traefik.http.routers.oauth2.rule=PathPrefix(`/oauth2`)"
75+ - " traefik.http.routers.oauth2.entrypoints=web"
76+ - " traefik.http.services.oauth2.loadbalancer.server.port=4180"
77+
78+ # ── Protected app (requires SSO) ─────────────────────────────────
79+ app-protected :
80+ image : traefik/whoami:latest
81+ environment :
82+ WHOAMI_NAME : " protected-app"
83+ networks :
84+ - proxy-int-net
85+ labels :
86+ - " traefik.enable=true"
87+ - " traefik.http.routers.app-protected.rule=PathPrefix(`/protected`)"
88+ - " traefik.http.routers.app-protected.entrypoints=web"
89+ - " traefik.http.routers.app-protected.middlewares=forward-auth,secure-headers"
90+ - " traefik.http.middlewares.forward-auth.forwardauth.address=http://oauth2-proxy:4180"
91+ - " traefik.http.middlewares.forward-auth.forwardauth.trustForwardHeader=true"
92+ - " traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
93+ - " traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true"
94+ - " traefik.http.services.app-protected.loadbalancer.server.port=80"
95+
96+ # ── Public app (no auth) ──────────────────────────────────────────
97+ app-public :
98+ image : traefik/whoami:latest
99+ environment :
100+ WHOAMI_NAME : " public-app"
101+ networks :
102+ - proxy-int-net
103+ labels :
104+ - " traefik.enable=true"
105+ - " traefik.http.routers.app-public.rule=PathPrefix(`/public`)"
106+ - " traefik.http.routers.app-public.entrypoints=web"
107+ - " traefik.http.services.app-public.loadbalancer.server.port=80"
108+
109+ # ── Prometheus: scrapes Traefik metrics ───────────────────────────
110+ prometheus :
111+ image : prom/prometheus:latest
112+ command :
113+ - --config.file=/etc/prometheus/prometheus.yml
114+ - --storage.tsdb.retention.time=1h
115+ volumes :
116+ - ./integration/prometheus.yml:/etc/prometheus/prometheus.yml:ro
117+ ports :
118+ - " 9090:9090"
119+ networks :
120+ - proxy-int-net
121+
122+ # ── Traefik ───────────────────────────────────────────────────────
4123 traefik :
5124 image : traefik:v3.0
6- container_name : it-stack-traefik
7- restart : unless-stopped
125+ command :
126+ - --api.dashboard=true
127+ - --api.insecure=true
128+ - --entrypoints.web.address=:80
129+ - --entrypoints.metrics.address=:8082
130+ - --metrics.prometheus=true
131+ - --metrics.prometheus.entrypoint=metrics
132+ - --metrics.prometheus.addRoutersLabels=true
133+ - --metrics.prometheus.addServicesLabels=true
134+ - --providers.docker=true
135+ - --providers.docker.exposedbydefault=false
136+ - --accesslog=true
137+ - --accesslog.format=json
8138 ports :
9- - " 80:$firstPort"
10- environment :
11- - IT_STACK_ENV=lab-05-integration
12- - KEYCLOAK_URL=
13- - DB_HOST=
14- - REDIS_HOST=
15- - SMTP_HOST=
16- - GRAYLOG_HOST=
17- extra_hosts :
18- - " lab-id1:10.0.50.11"
19- - " lab-db1:10.0.50.12"
20- - " lab-proxy1:10.0.50.15"
139+ - " 80:80"
140+ - " 8080:8080"
141+ - " 8082:8082"
142+ volumes :
143+ - /var/run/docker.sock:/var/run/docker.sock:ro
144+ - traefik-logs:/var/log/traefik
21145 networks :
22- - it-stack-net
146+ - proxy-int-net
147+ depends_on :
148+ keycloak :
149+ condition : service_healthy
23150
24151networks :
25- it-stack -net :
152+ proxy-int -net :
26153 driver : bridge
154+ kc-db-net :
155+ driver : bridge
156+ internal : true
157+
158+ volumes :
159+ kc-db-int :
160+ traefik-logs:
0 commit comments