This episode opens up the Traefik middleware concept: the request chain and response chain, execution order, how to chain many middlewares on a single router, HTTP, TCP, and plugin middleware types, and common patterns for authentication, security headers, and request-response modification.

Middleware is one of the features that makes Traefik so flexible. Imagine every passing request as a pipe: middlewares are the filters installed along that pipe, each one modifying or inspecting what flows through. Episode 8 introduces the basic concepts used by all subsequent episodes in this phase.
There are two key insights: execution order and the bidirectional nature. Middlewares run in sequence according to their registration order, and because middlewares wrap a service, the response from the backend also passes through all the same middlewares. Wrong ordering often produces unpredictable behavior — let us build the right intuition from the start.
When a request arrives, Traefik runs the router's middlewares in sequence: the first middleware receives the request, modifies it, forwards it to the second, and so on until the service. When the service answers, the response flows in the opposite direction through the same middlewares, in reverse order:
request : m1 -> m2 -> m3 -> service
response: m1 <- m2 <- m3 <- serviceAn important consequence: a middleware sees the request on the inbound path and the response on the outbound path. The headers middleware, for example, can add request headers on the inbound path, then add response headers on the outbound path — both in a single definition.
A middleware is defined once with a name, then referenced by routers. In Docker, definitions are written as labels, while the attachment is done on the router label:
services:
app:
image: nginx:alpine
labels:
- traefik.enable=true
- traefik.http.routers.app.rule=Host(`app.localhost`)
- traefik.http.routers.app.middlewares=auth,headers,compress
- traefik.http.middlewares.auth.basicauth.users=admin:$apr1$H6uskkkW$IgXLP6ewTrSuBkPqGkHpv5
- traefik.http.middlewares.headers.headers.customresponseheaders.X-Custom=hello
- traefik.http.middlewares.compress.compress=trueThe app router runs three middlewares in sequence: auth (authentication), headers (added headers), then compress (compression). The order in the middlewares=auth,headers,compress list determines the execution order — the leftmost middleware runs first.
Order determines the final result. Two real examples:
compress runs before auth, Traefik wastes CPU compressing a request that will ultimately be rejected. Put "decision" middlewares (auth, rate limit) at the front.redirectregex middleware changes the URL, so a stripprefix middleware attached to it works on the new URL, not the old one.Rule of thumb: decision middlewares first, transformation middlewares last. Authentication, rate limiting, and circuit breakers should run before header changes or compression.
The same structure can be written in the file provider (episode 19). Notice how middleware definitions are separated from the router, and the router only mentions their names:
http:
middlewares:
api-protect:
chain:
middlewares:
- api-rate
- api-auth
- api-headers
api-rate:
rateLimit:
average: 100
burst: 50
api-auth:
basicAuth:
users:
- "admin:$2y$05$0UvReaDF8s0BbQpqBFBp8e1gV6Q2Y0hH9o5QyTq3a4j7kLmZxS2C"
api-headers:
headers:
customResponseHeaders:
X-Content-Type-Options: "nosniff"
routers:
api:
rule: "Host(`api.localhost`)"
entrypoints:
- web
service: api-svc
middlewares:
- api-protectHere api-protect is a chain type middleware: a container that holds three other middlewares and runs them in order. The router only mentions one name, api-protect, but effectively runs rate limiting, authentication, then header addition. This chain pattern is very tidy for groups of middlewares shared together.
All examples above use named middlewares: defined first, then referenced. This enables reuse — the same middleware can be used by many routers. Traefik also supports inline middlewares in some contexts, but named ones are far easier to read and maintain. For all subsequent episodes, we consistently use named middlewares.
Most Traefik production configurations use these three patterns:
basicauth or forwardauth installed at the front to protect resources.headers adds X-Frame-Options, X-Content-Type-Options, and Content-Security-Policy to every response.stripprefix, addprefix, redirectregex adjust paths and URLs before reaching the backend.We will dissect the first pattern in episode 9, the second in episode 10, and the third in episode 11.
Info
Middleware names are global within a single provider. If two file providers define middlewares with the same name, the second definition overrides the first — use unique names so they do not collide.
Key takeaways:
In episode 9 next we will cover authentication middlewares — BasicAuth with htpasswd, DigestAuth, ForwardAuth with Authelia, Authentik, and OAuth2 Proxy integration, and IPWhiteList for restricting access based on source address. Authentication is the first line of defense for every service.