Here's my use case regarding the header middleware running in Docker:
I'd like to be able to create one middleware called std-headers with the file provider (std-headers@file), and then combine that with additional security features from a second or third middleware (i.e.: traefik-headers@docker,allowed-hosts@file).
I've tried multiple ways with and without using Chain, but it appears that the headers are added as one 'block' or 'set' - meaning all of the Headers are added at once, and if a second middleware also tries to modify the Headers, the second one will be ignored. When I look at the dashboard I can see the middlewares showing up for the router, but found that only one is actually being applied.
I'm not looking to replace headers (I'd expect an error/conflict), but I would like to leave off ContentSecurityPolicy for example and specify that per container.
Is it currently possible to do this? I would test by having all headers in one middleware (working ok), then separate the STS headers (easy to identify) and try to combine them with chain, or by calling both of them individually, etc. I can combine the headers middleware with auth or addprefix, but can't combine multiple header middlewares together.
I'm also curious how this is handled inside docker-compose with labels. I'd love to add an example to the docs once I figure it out. In meantime will check out the code
Resurrecting this thread (Now end of Feb 2020). I just stumbled into this today as well. As of 2.1 it is still an issue. As a result I have lots of duplicated header code floating around in my compose files.
I don't know if I have misunderstood the problem you are describing, I am running 2.2.8 and using using chains have multiple middleware definitions adding (custom) headers with each set of custom headers present in the final output.
I've provided my config below in case helpful - have I misunderstood the problem you are describing?
[http.middlewares.middlewares-secure-headers]
[http.middlewares.middlewares-secure-headers.headers]
accessControlAllowMethods= ["GET", "OPTIONS", "PUT"]
accessControlMaxAge = 100
hostsProxyHeaders = ["X-Forwarded-Host"]
sslRedirect = true
stsSeconds = 63072000
stsIncludeSubdomains = true
stsPreload = true
forceSTSHeader = true
# frameDeny = true #overwritten by customFrameOptionsValue
contentTypeNosniff = true
browserXssFilter = true
# sslForceHost = true # add sslHost to all of the services
referrerPolicy = "same-origin"
# Setting contentSecurityPolicy is more secure but it can break things. Proper auth will reduce the risk.
# the below line also breaks some apps due to 'none' - sonarr, radarr, etc.
# contentSecurityPolicy = "frame-ancestors '*.tld.domain:*';object-src 'none';script-src 'none';"
featurePolicy = "camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';"
[http.middlewares.middlewares-secure-headers.headers.customResponseHeaders]
X-Robots-Tag = "none,noarchive,nosnippet,notranslate,noimageindex,"
server = ""
X-DJR-Debug = "debug header"
[http.middlewares.middlewares-test-header]
[http.middlewares.middlewares-test-header.header]
[http.middlewares.middlewares-test-header.headers.customResponseHeaders]
X-Custom-Response-Header = "Header value 1"
[http.middlewares.middlewares-test-header2]
[http.middlewares.middlewares-test-header2.header]
[http.middlewares.middlewares-test-header2.headers.customResponseHeaders]
X-Custom-Response-Header = "Header value 2"
[http.middlewares.middlewares-test-header3]
[http.middlewares.middlewares-test-header3.header]
[http.middlewares.middlewares-test-header3.headers.customResponseHeaders]
X-Custom-Test-Header = "Header value 3"
X-Custom-Another-Header = "Header value 4"
X-Custom-Different-Header = "Header value 5"
[http.middlewares.chain-test-headers]
[http.middlewares.chain-test-headers.chain]
middlewares = ["middlewares-test-header", "middlewares-test-header3", "middlewares-secure-headers"]