Compare commits

...

204 Commits

Author SHA1 Message Date
Romain 32da599169 Prepare release v3.6.18 2026-06-03 11:50:05 +02:00
romain 468e0c8d55 Merge branch v2.11 into v3.6 2026-06-03 11:10:58 +02:00
Kevin Pollet dcbe752df5 Change default values and expose configuration for Kubernetes client QPS and Burst
Co-authored-by: Anatole Lucet <anatole.lucet@proton.me>
2026-06-03 11:06:05 +02:00
Romain 855561306f Prepare release v2.11.47 2026-06-03 11:02:05 +02:00
Romain f25d48e039 Bump golang.org/x/crypto to v0.52.0 2026-06-03 09:14:05 +02:00
romain d468a3e4d0 Merge branch v2.11 into v3.6 2026-06-03 09:14:04 +02:00
Marcell Pünkösd 3697409701 Fix race condition in tests accessing global variables in parallel 2026-06-01 16:18:05 +02:00
Kevin Pollet af31587841 Bump github.com/bytedance/sonic to v1.15.1 2026-05-30 10:30:05 +02:00
Yuxiao Zeng 8c05c1b1a7 Improve file provider behavior regarding dangling symlinks 2026-05-29 14:14:05 +02:00
Kevin Pollet 9c94e3b493 Bump github.com/moby/spdystream to v0.5.1 2026-05-29 09:48:09 +02:00
Kevin Pollet fc83948b1e Bump golang.org/x/net to v0.55.0 2026-05-29 09:14:05 +02:00
Romain 892bcc288b Reject requests with different paths after StripPrefix and StripPrefixRegex normalisation 2026-05-28 15:56:25 +02:00
Julien Salleyron 5026ca97d0 Move snicheck to ctx instead of simulated routing 2026-05-28 10:30:07 +02:00
Sébastien Lemay 2c03850b90 Capitalize NGINX in kubernetesIngressNGINX 2026-05-28 09:38:12 +02:00
Romain f9d9b72380 Avoid ingress path matcher injection and backport 11d251415 2026-05-27 16:32:10 +02:00
Emile Vauge 9d5b03d2ea Add @LBF38 as a current maintainer 2026-05-22 17:24:05 +02:00
Cali Nelson 1db7d439a4 Allow query parameters to be dropped from RequestPath in access log 2026-05-22 15:40:06 +02:00
Nick ee07d0f4d2 Escape exact gRPC method matches 2026-05-22 11:42:06 +02:00
Mark Bonnekessel 1c9a3d21ed Remove whitespace in HTML tag 2026-05-22 10:20:06 +02:00
quyentonndbs 30c118e552 Polish grammar in migration guides 2026-05-22 10:08:06 +02:00
Emile Vauge a6b16426f2 Surface the Ingress status race condition during NGINX coexistence 2026-05-22 09:52:05 +02:00
Armin ecf5182056 Fix typo in accesslogs field name 2026-05-22 09:42:17 +02:00
Sheddy 8d2e7db6e3 Replace generated File routing reference page 2026-05-21 15:24:07 +02:00
Simon Delicata 6736725654 docs: add AGENTS.md contributor guide for AI agents 2026-05-20 14:32:06 +02:00
Kaan f2b11cd50d fix(accesslog): escape double quotes in quoted log fields 2026-05-18 16:02:06 +02:00
Romain 4d9031bdb2 Add error on basic auth build if users is empty 2026-05-18 15:06:09 +02:00
Kevin Pollet 32c0861937 Prepare release v3.6.17 2026-05-11 14:44:04 +02:00
kevinpollet c876ed1191 Merge branch v2.11 into v3.6 2026-05-11 14:22:35 +02:00
Kevin Pollet 22460f0a62 Prepare release v2.11.46 2026-05-11 14:20:05 +02:00
kevinpollet 72fcf30d6b Merge branch v2.11 into v3.6 2026-05-11 11:16:29 +02:00
Kevin Pollet 83cc8fee5d Make resolveReference method as a function 2026-05-11 11:14:06 +02:00
romain fc482fda97 Merge branch v2.11 into v3.6 2026-05-11 09:35:34 +02:00
Romain 36a565a599 Fix cross-provider ref check for Kubernetes CRD provider 2026-05-07 16:58:05 +02:00
romain 8c7634bcde Merge branch v2.11 into v3.6 2026-05-07 11:47:33 +02:00
Romain 28604083a4 Add CrossProviderNamespaces option
Co-authored-by: Gina A. <70909035+gndz07@users.noreply.github.com>
2026-05-06 14:49:23 +02:00
Kevin Pollet 801eb2f149 Prepare release v3.6.16 2026-05-05 15:36:05 +02:00
kevinpollet 9f3f1725d2 Merge branch v2.11 into v3.6 2026-05-05 15:01:52 +02:00
Kevin Pollet ee94dc5343 Prepare release v2.11.45 2026-05-05 14:22:05 +02:00
Julien Salleyron 7be1506b42 Bump go.opentelemetry.io/otel 2026-05-05 10:54:05 +02:00
Michael e4537f8b04 Migrate to github.com/moby/moby modules 2026-05-04 16:06:05 +02:00
Sebastiaan van Stijn 8f99bbcfba Migrate to github.com/moby/moby modules 2026-05-04 15:50:05 +02:00
Gina A. 29d2340ca4 Bump Axios version 2026-05-04 14:54:05 +02:00
Gina A. bd6a685be3 Bump webui dependencies 2026-05-04 14:48:05 +02:00
Romain e6abf7c3c8 Remove cross-provider sanitization for Kubernetes service loading
Co-authored-by: Gina A. <70909035+gndz07@users.noreply.github.com>
2026-05-04 11:12:05 +02:00
mliang2 80103b1db2 Fix typo in default CORS allowed headers 2026-05-04 10:28:05 +02:00
Pushkin f91bae1257 Update Helm chart values link for Kubernetes Gateway 2026-04-30 14:42:05 +02:00
Romain c5ce3f847a Prepare release v3.6.15 2026-04-29 14:36:05 +02:00
mmatur 59357eeaf8 Merge branch v2.11 into v3.6 2026-04-29 12:45:03 +02:00
Ludovic Fernandez 5ece7043c0 Bump github.com/go-acme/lego/v4 to v4.35.2 2026-04-29 12:04:05 +02:00
Romain 98cf988d30 Prepare release v2.11.44 2026-04-29 11:56:10 +02:00
Michael ad4abde146 Bump github.com/go-acme/lego to v4.35.2 2026-04-29 11:44:05 +02:00
Ludovic Fernandez 72c55e7e1d Bump github.com/vulcand/oxy to v2.1.0 2026-04-27 17:16:06 +02:00
Tom Wieczorek 6a6d96d7fe Make FLAGS Make variable usable 2026-04-27 15:46:05 +02:00
Gina A. 0fdea20eb1 Add errorRequestHeaders option to Errors middleware 2026-04-24 14:40:06 +02:00
Kevin Pollet 28e655452c Do not require a port for ExternalName services 2026-04-24 11:16:05 +02:00
Ludovic Fernandez 2e80ad282a Bump github.com/go-acme/lego/v4 to v4.35.1 2026-04-23 15:10:11 +02:00
Michael a6664c95b5 Prepare release v3.6.14 2026-04-22 10:54:05 +02:00
mmatur 379d691e09 Merge v2.11 into v3.6 2026-04-22 10:29:41 +02:00
Michael a9ce32a8dc Prepare release v2.11.43 2026-04-22 10:26:05 +02:00
Kevin Pollet 53752744d5 Deprecate ForwardAuth.TrustForwardHeader option 2026-04-21 11:00:07 +02:00
Kevin Pollet 13302a212e Cleanup and make ForwardAuth logs consistent 2026-04-21 10:22:05 +02:00
mmatur 4aea15feea Merge v2.11 into v3.6 2026-04-20 11:19:04 +02:00
Julien Salleyron 5e1de22584 Fix trustForwardHeader on forward auth middleware 2026-04-17 15:42:05 +02:00
Michel Loiseleur 184de70aef Remove duplicate step in CI 2026-04-17 10:52:06 +02:00
Ludovic Fernandez f4766d74c7 Bump github.com/go-acme/lego/v4 to v4.34.0 2026-04-16 15:36:06 +02:00
Kevin Pollet 1a43505387 Sanitize the request URL after stripping the prefix 2026-04-16 14:26:06 +02:00
Romain df00d82fc7 Honor allowCrossNamespace with chain middleware CRD 2026-04-15 10:36:06 +02:00
orbisai0security 0ed3b8ddb1 Upgrade form-data to 2.5.4, 3.0.4, 4.0.4 2026-04-15 09:12:05 +02:00
Romain 61b5bc4ad1 Remove untrusted X headers with underscores 2026-04-14 16:38:06 +02:00
parkerfath 85b9b6903e Clarify install config watchNamespace watches only one namespace 2026-04-13 15:14:05 +02:00
Emile Vauge e3db821484 Update vulnerability submission guidelines 2026-04-13 11:24:06 +02:00
Romain 8c4fc89579 Remove map lookup making the basic auth notFoundSecret empty 2026-04-13 10:24:08 +02:00
Nicolas Mengin afeedb2885 Reverse versions order in migration guide 2026-04-10 16:28:06 +02:00
Murat Aslan 091d13b5e4 Make SameSite cookie value case-insensitive 2026-04-09 17:10:13 +02:00
Rajakavitha Kodhandapani 79ec5fd65e Update ingressroute.md 2026-04-09 16:40:07 +02:00
isayme ba3afa5e2b docs: yaml indent 4 space 2026-04-09 14:08:06 +02:00
Vitor Hugo 210344f950 Downgrade log level for missing container on inspect 2026-04-09 11:42:07 +02:00
Romain 94764103c4 Prepare release v3.6.13 2026-04-07 11:52:04 +02:00
Sebastiaan van Stijn 756e91acdd Bump github.com/klauspost/compress v1.18.4 and fix TestNegotiation 2026-04-07 10:48:05 +02:00
Kevin Pollet e32a5a04bc Clarify IngressClass selection logic 2026-04-02 15:54:05 +02:00
Michel Loiseleur 3ce463ddd1 Fix documentation on how to restrict the scope of service discovery 2026-04-01 14:18:09 +02:00
Antonin 012b483fbe docs: OVHcloud (OpenStack Octavia) to Cloud-Specific IP Management 2026-03-31 17:44:05 +02:00
iTob191 cc195a3f87 Fix default value of http.sanitizePath in docs 2026-03-30 15:44:05 +02:00
srmes 70dd1517e8 Fix docker-compose.yaml location in traefik/setup/docker/ 2026-03-26 15:54:14 +01:00
Sheddy cdb4ce0a52 Add redirects for deleted pages 2026-03-26 11:42:05 +01:00
Nicolas Mengin c32177e1ec Add missing redirects for Getting started 2026-03-26 11:08:06 +01:00
Kevin Pollet b782bd32d4 Prepare release v3.6.12 2026-03-26 10:54:04 +01:00
kevinpollet 1b2e82453c Merge branch v2.11 into v3.6 2026-03-26 10:12:28 +01:00
Kevin Pollet e4b2c648bf Prepare release v2.11.42 2026-03-26 09:48:04 +01:00
jv 7816ed8e34 Fix comment and unnecessary allocation in withRoutingPath 2026-03-26 09:40:05 +01:00
parkerfath 8eb4d34294 Clarify doc: NGINX Ingress watchNamespace watches only one namespace 2026-03-26 09:14:09 +01:00
Sheddy cf29feb81c Improve Kubernetes Ingress Routing Documentation 2026-03-25 16:52:05 +01:00
Michel Loiseleur f5eb6c9de5 Remove hidden files in documentation 2026-03-25 16:40:07 +01:00
Gina A. 3c74d627d5 Add ingress-nginx migration banner on documentation pages 2026-03-24 17:52:12 +01:00
Michael 25ab6f46d0 Fix allow colons and tildes in api.basePath validation 2026-03-24 17:32:05 +01:00
Gina A. f19aaa769c Fix StripPrefix and StripPrefixRegex to slice the prefix using encoded prefix length
Co-authored-by: Mathis Urien <contact.lbf38@gmail.com>
2026-03-24 17:06:05 +01:00
Michael 30d5258c75 Fix postgres STARTTLS with TLS termination 2026-03-24 11:18:05 +01:00
Ludovic Fernandez c60ef319ba Bump github.com/go-acme/lego/v4 to v4.33.0 2026-03-23 16:34:06 +01:00
Michael 930ff2aa09 Fix auth-response-headers whitespace trimming in ingress-nginx provider 2026-03-23 14:14:04 +01:00
Julien Salleyron 51f6b0435f Prevent duplicate user headers in basic and digest auth middleware 2026-03-20 16:24:05 +01:00
Michael 70c45a6f9c Bump google.golang.org/grpc to v1.79.3 2026-03-20 09:12:05 +01:00
Sheddy 4fa1f31f79 clarify CNAME explanation in ACME Documentation 2026-03-19 14:06:05 +01:00
Romain 33219a0af8 Prepare release v3.6.11 2026-03-19 10:12:04 +01:00
romain b1b520b186 Merge branch v2.11 into v3.6 2026-03-18 15:51:33 +01:00
Romain f2c198c9f3 Prepare release v2.11.41 2026-03-18 10:40:06 +01:00
Nicolas Mengin 3166deb308 Improve the multi tenant security note 2026-03-18 10:10:07 +01:00
LBF38 f79caa5717 Fix proxy-ssl-verify annotation 2026-03-18 09:08:04 +01:00
Desel72 31400876de Remove AGPL license in code 2026-03-17 15:44:05 +01:00
Romain 122175ac2f Make basic auth check timing constant
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2026-03-17 15:36:05 +01:00
Gina A. 11d251415a Fix ingress router's rule
Co-authored-by: Mathis Urien <contact.lbf38@gmail.com>
2026-03-17 15:12:05 +01:00
Sheddy 154fcf86ae Remove unsupported servers[n].address from TCP label examples 2026-03-17 11:22:05 +01:00
Alexander 69a738ccf0 Fix incorrect hostname matching between listener and route 2026-03-16 16:42:05 +01:00
Michel Loiseleur f143e15595 Fix start up message format. 2026-03-16 15:58:05 +01:00
Michael d7cc334238 Add OTel-conformant trace context attributes to access logs 2026-03-16 11:52:57 +01:00
Rémi BUISSON a377b3aba1 Bump mkdocs-traefiklabs to use consent mode 2026-03-13 12:58:04 -03:00
Emile Vauge 6d6374d499 Add vulnerability submission quality guidelines 2026-03-13 06:50:04 -03:00
Romain 832f48d9bf Support fragmented TLS client hello
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2026-03-11 13:56:06 -03:00
Diego Monti 65cca1291d Fix unnecessary escaping of pipe in regexp examples 2026-03-11 10:50:05 -03:00
Gina A. b460351f7e Add maxResponseBodySize configuration on HTTP provider 2026-03-11 10:24:05 -03:00
Michael 3b97d37c98 Fix webui ci 2026-03-09 12:56:04 -03:00
Michael 043583490b Prepare release v3.6.10 2026-03-06 11:56:05 -03:00
mmatur 25b06d0199 Merge branch v2.11 into v3.6 2026-03-06 15:24:18 +01:00
Jesper Noordsij c7d5507462 Use modern WaitGroup.Go function in additional places 2026-03-06 11:22:06 -03:00
Michael bb7bb49226 Prepare release v2.11.40 2026-03-06 11:10:04 -03:00
Kevin Pollet 9ab7fb860d Bump github.com/valyala/fasthttp to v1.69.0 2026-03-06 11:00:12 -03:00
Michael 8291b1d049 Fix go-version for CI 2026-03-06 10:58:04 -03:00
mmatur 10992086b8 Merge current v2.11 into v3.6 2026-03-06 10:11:25 +01:00
Michael fc32e6dc0b Fix priority display in dashboard and ACME bypass redirect 2026-03-06 06:04:05 -03:00
Romain 86a8f87acd Prepare release v2.11.39 2026-03-06 05:56:04 -03:00
Kim Alvefur d5745c3807 Correct documentation for Digest auth 2026-03-06 04:54:05 -03:00
Michael 1268d9bc22 Bump Docker and OpenTelemetry dependencies 2026-03-05 11:52:04 -03:00
Romain c662b9ac6b Remove path parsing with grpc healthcheck 2026-03-05 11:00:06 -03:00
Romain ef1d71f786 Fix Gateway API router's rules
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2026-03-05 06:02:07 -03:00
Kevin Pollet 2b71f6f518 Bump golang.org/x/net to v0.51.0 2026-03-04 06:26:05 -03:00
Varun Chawla 7a95bac64f Fix HasSecureHeadersDefined returning false when stsSeconds is 0 2026-03-03 12:12:05 -03:00
Romain a71d4d640f Bump go.opentelemetry.io/otel dependencies 2026-03-03 11:42:05 -03:00
Sebastiaan van Stijn 8b3111c42a Bump github.com/testcontainers/testcontainers-go to v0.40.0 2026-03-03 11:00:07 -03:00
Sebastiaan van Stijn c605e5e139 Replace uses of hashicorp/go-multierror with stdlib errors.Join 2026-03-03 06:00:17 -03:00
Mathieu Parent 734cc21fb4 Remove unused context import from test file 2026-03-03 05:26:04 -03:00
Nicolas Mengin 88deb9b211 Fix API basepath option documentation 2026-02-27 12:30:05 -03:00
fuyu 3ec1ee585f Fix incorrect TOML example in entrypoints docs 2026-02-26 15:14:04 +01:00
Gina A. a0654afa97 Fix basePath validation for dashboard template 2026-02-25 17:12:15 +01:00
Dos Moonen 0d60499f13 Add missing .http to TOML table names 2026-02-23 19:20:04 +01:00
Michael 65f9d06632 Prepare release v3.6.9 2026-02-23 18:06:04 +01:00
mmatur 13dc9a6892 Merge v2.11 into v3.6 2026-02-23 17:34:52 +01:00
Michael 7c55452b21 Prepare release v2.11.38 2026-02-23 16:28:04 +01:00
Michael 95b3f45311 Fix Go version pinning in CI workflows 2026-02-23 16:00:05 +01:00
Jesper Noordsij c98fddbd03 Simplify Go version refs in CI templates 2026-02-23 15:08:05 +01:00
Julien Salleyron 7a3ffcc3d9 Fix TLS handshake error handling 2026-02-23 14:06:05 +01:00
Gina A. 4595c7a920 Add maxResponseBodySize configuration to forwardAuth middleware 2026-02-23 11:30:06 +01:00
Jesper Noordsij 288e4e2e2b Upgrade golangci-lint 2026-02-23 11:04:04 +01:00
LBF38 7494b5c9ff Fix case sensitivity on x-forwarded headers for Connection 2026-02-23 10:04:10 +01:00
Apflkuacha 3d8908860f Correct encoded characters allowance in entrypoints.md 2026-02-23 09:06:04 +01:00
Ludovic Fernandez d39036f454 Bump github.com/go-acme/lego/v4 to v4.32.0 2026-02-19 15:52:06 +01:00
Nicolas Mengin 34ce2e9dbd Add temporary note to advertise the incoming NGINX annotations 2026-02-18 12:46:05 +01:00
Mateus Devino b8c30c2b2d Update docker in-depth setup guide 2026-02-17 16:38:05 +01:00
kevinpollet b97d27f7b7 Merge branch v2.11 into v3.6 2026-02-13 15:44:04 +01:00
Kevin Pollet 526a34c8ec Remove deprecated swarm:1.0.0 image used in DockerSuite 2026-02-13 15:32:04 +01:00
Patrick Evans 2924e9ad5a Make labelSelector option casing more consistent 2026-02-13 09:22:04 +01:00
Andreas b8fca6e460 Handle empty/missing User-Agent header 2026-02-12 15:36:05 +01:00
Tobias Genannt 9eea5c4152 Increased content width in documentation 2026-02-12 14:50:04 +01:00
Michael 2f215ab9a1 Prepare release v3.6.8 2026-02-11 17:26:05 +01:00
Romain f6ce751a06 Reject absolute URL in healthcheck path configuration 2026-02-11 16:10:05 +01:00
mmatur a28da8a226 Merge v2.11 into v3.6 2026-02-11 14:45:21 +01:00
Michael 7747b40310 Prepare release v2.11.37 2026-02-11 10:42:04 +01:00
Romain 31e566e9f1 Remove conn deadline after STARTTLS negociation
Co-authored-by: Michael <michael.matur@gmail.com>
2026-02-11 09:48:05 +01:00
Michael 72e2454e42 Cap TLS record length to RFC 8446 limit in ClientHello peeking 2026-02-11 09:22:04 +01:00
mmatur 256fcbed5e Merge v2.11 into v3.6 2026-02-10 14:55:09 +01:00
Romain 0beed101ec Validate healthcheck path configuration
Co-authored-by: Michael <michael.matur@gmail.com>
2026-02-10 14:52:05 +01:00
Kevin Pollet 4b3c971ea3 Use url.Parse to validate X-Forwarded-Prefix value 2026-02-10 14:48:06 +01:00
Michael d337748873 Fix ObservabilityConfig SetDefaults 2026-02-09 10:48:05 +01:00
Anurag Ekkati ef546944b1 Clarify SNI selection 2026-02-05 14:32:05 +01:00
Evgenii Domashenkin 29d1c751c1 Use ParentBased sampler to respect parent span sampling decision 2026-02-02 15:20:05 +01:00
Romain f1e850ae0b Prepare release v2.11.36 2026-02-02 11:24:20 +01:00
Mateus Devino 6b2bb3cb24 Fix typo on JWT documentation 2026-02-02 09:18:04 +01:00
mmatur f2b68f29a1 Merge v2.11 into v3.6 2026-02-02 05:33:16 +01:00
Jesper Noordsij c320bb4adb Bump to go1.25 2026-01-30 17:30:05 +01:00
Yuito Akatsuki (Tani Yutaka) 75ac25bb31 Fix the errors middleware's document for Kubernetes CRD 2026-01-29 15:44:07 +01:00
Sheddy b3528b4f4d Clean Up Menu Entries & Update Expose Overview 2026-01-29 14:24:04 +01:00
Kevin Pollet 7d13368150 Remove number prefix in ingress-nginx fixtures 2026-01-29 11:56:04 +01:00
Michael f32d58c577 Fix flakiness unit tests 2026-01-29 11:42:06 +01:00
Sheddy 72ba481bbc Document Path matcher placeholder removal in v3 migration guide 2026-01-28 17:26:04 +01:00
Kevin Pollet 3678d2332f Fix verifyServerCertMatchesURI function behavior
Co-authored-by: Mathis Urien <contact.lbf38@gmail.com>
2026-01-28 12:04:05 +01:00
Marten 121dfa6060 Fix kubernetes.md with correct http redirections 2026-01-27 14:32:04 +01:00
mmatur 5c97bfbbbc Merge v2.11 into v3.6 2026-01-27 11:40:47 +01:00
Michael ed990f279a Upgrade github action versions 2026-01-27 11:20:10 +01:00
mmatur fb54793b93 Merge v2.11 into v3.6 2026-01-26 17:20:11 +01:00
Rémi BUISSON 7e5ee8988e chore: pin GitHub Actions to SHA hashes for supply chain security 2026-01-26 15:14:05 +01:00
Emile Vauge d4d61dbd80 Add @gndz07 as a current maintainer 2026-01-26 15:04:05 +01:00
Sheddy 91381590d3 Split Expose User Guides & Add Multi-Layer Routing Section 2026-01-26 14:36:04 +01:00
Julien Salleyron 85cd5485b7 Avoid recursion with services 2026-01-26 10:28:04 +01:00
Gina A. 9ac5d3ac1c Bump dependencies of documentation and webui 2026-01-22 12:10:07 +01:00
Romain d675b163b3 Bump github.com/containerd/containerd to v1.7.29 2026-01-22 09:54:04 +01:00
Julien Salleyron 139b59def9 Remove invalid private key in log 2026-01-21 10:26:04 +01:00
Benjamin Schwartz ef5d040fd6 Alter TLS renewal period 2026-01-21 09:38:04 +01:00
Romain 7cb25da31c Remove extra dots in migration guide 2026-01-20 15:40:05 +01:00
dathbe 63820e1d78 Remove extraneous dots in migration guide 2026-01-20 09:34:04 +01:00
Sheddy bb35197d5a Improve the structure of the routing reference pages 2026-01-16 14:48:06 +01:00
Sheddy 6cd85caa99 Improve Service Reference page 2026-01-16 11:26:05 +01:00
mmatur 3315a9fbec Merge current v2.11 into v3.6 2026-01-16 09:13:54 +01:00
understood-the-assignment 27b27e9b1f Document negative priority support for routers 2026-01-15 10:00:05 +01:00
Jesper Noordsij 34d8491ac2 Bump github.com/quic-go/quic-go to v0.59.0 2026-01-14 18:15:35 +01:00
Michael 51343bc15f Upgrade golangci-lint 2026-01-14 17:26:08 +01:00
Alessandro Marotta 105bf1cfd6 Fix migration guide URLs in deprecation notice 2026-01-14 17:12:07 +01:00
625 changed files with 16619 additions and 61686 deletions
+5 -6
View File
@@ -10,7 +10,6 @@ on:
- 'script/gcg/**'
env:
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:
@@ -51,20 +50,20 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
env:
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz
+4 -4
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
@@ -28,7 +28,7 @@ jobs:
run: ./docs/scripts/lint.sh docs
- name: Setup python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: 'pip'
@@ -41,7 +41,7 @@ jobs:
mkdocs build --strict
- name: Setup ruby
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.4'
@@ -54,7 +54,7 @@ jobs:
# Comes from https://github.com/gjtorikian/html-proofer?tab=readme-ov-file#caching-with-continuous-integration
- name: Cache HTMLProofer
uses: actions/cache@v4
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: tmp/.htmlproofer
key: ${{ runner.os }}-htmlproofer
+7 -6
View File
@@ -28,17 +28,18 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: setup go
uses: actions/setup-go@v5
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
if: ${{ matrix.language == 'go' }}
with:
go-version-file: 'go.mod'
go-version-file: '.go-version'
check-latest: true
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@38e701f46e33fb233075bf4238cb1e5d68e429e4 # v3.31.11
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -52,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@38e701f46e33fb233075bf4238cb1e5d68e429e4 # v3.31.11
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -65,6 +66,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@38e701f46e33fb233075bf4238cb1e5d68e429e4 # v3.31.11
with:
category: "/language:${{matrix.language}}"
+2 -2
View File
@@ -20,12 +20,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
+8 -9
View File
@@ -7,7 +7,6 @@ on:
- v*
env:
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:
@@ -23,16 +22,16 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
env:
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Build
@@ -42,19 +41,19 @@ jobs:
run: echo ${GITHUB_REF##*/}
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz
+12 -14
View File
@@ -6,7 +6,6 @@ on:
- 'v*.*.*'
env:
GO_VERSION: '1.24'
CGO_ENABLED: 0
VERSION: ${{ github.ref_name }}
TRAEFIKER_EMAIL: "traefiker@traefik.io"
@@ -30,21 +29,21 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
env:
# Ensure cache consistency on Linux, see https://github.com/actions/setup-go/pull/383
ImageOS: ${{ matrix.os }}
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz
@@ -63,7 +62,7 @@ jobs:
echo "GORELEASER_CONFIG_FILE_PATH=$GORELEASER_CONFIG_FILE_PATH" >> $GITHUB_ENV
- name: Build with goreleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
distribution: goreleaser
# 'latest', 'nightly', or a semver
@@ -71,7 +70,7 @@ jobs:
args: release --clean --timeout="90m" --config "${{ env.GORELEASER_CONFIG_FILE_PATH }}"
- name: Artifact binaries
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ${{ matrix.os }}-binaries
path: |
@@ -89,12 +88,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz
@@ -111,7 +110,7 @@ jobs:
echo "${TRAEFIKER_RSA}" | base64 --decode > ~/.ssh/traefiker_rsa
- name: Download All Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: dist/
pattern: "*-binaries"
@@ -128,9 +127,8 @@ jobs:
--exclude .idea \
--exclude .github \
--exclude dist .
chown -R "$(id -u)":"$(id -g)" dist/
gh release create ${VERSION} ./dist/**/traefik*.{zip,tar.gz} ./dist/traefik*.{tar.gz,txt} --repo traefik/traefik --title ${VERSION} --notes ${VERSION} --latest=false
./script/deploy.sh
./script/deploy.sh
+2 -2
View File
@@ -14,9 +14,9 @@ jobs:
if: github.repository == 'traefik/traefik'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: imjasonh/setup-crane@v0.4
- uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4
- name: Sync
run: |
+6 -4
View File
@@ -2,7 +2,7 @@ name: Build Web UI
on:
workflow_call: {}
env:
SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS: 360 # 15 days
SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS: 48 # 2 days
jobs:
build-webui:
@@ -10,7 +10,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
@@ -18,7 +18,7 @@ jobs:
run: corepack enable
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: webui/.nvmrc
cache: yarn
@@ -34,6 +34,8 @@ jobs:
working-directory: ./webui
run: |
yarn install
yarn tsc
yarn lint
yarn build
- name: Package webui
@@ -41,7 +43,7 @@ jobs:
tar czvf webui.tar.gz ./webui/static/
- name: Artifact webui
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: webui.tar.gz
path: webui.tar.gz
@@ -12,7 +12,6 @@ on:
- 'integration/integration_test.go'
env:
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:
@@ -22,14 +21,15 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Avoid generating webui
run: |
+15 -16
View File
@@ -10,7 +10,6 @@ on:
- 'script/gcg/**'
env:
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:
@@ -20,14 +19,14 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Avoid generating webui
@@ -38,14 +37,14 @@ jobs:
run: make binary-linux-amd64
- name: Save go cache build
uses: actions/cache/save@v4
uses: actions/cache/save@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.cache/go-build
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-build-cache-${{ hashFiles('**/go.mod', '**/go.sum') }}
- name: Artifact traefik binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: traefik
path: ./dist/linux/amd64/traefik
@@ -63,18 +62,18 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Download traefik binary
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: traefik
path: ./dist/linux/amd64/
@@ -83,15 +82,15 @@ jobs:
run: chmod +x ./dist/linux/amd64/traefik
- name: Restore go cache build
uses: actions/cache/restore@v4
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.cache/go-build
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-build-cache-${{ hashFiles('**/go.mod', '**/go.sum') }}
- name: Generate go test Slice
id: test_split
uses: hashicorp-forge/go-test-split-action@v2.0.0
uses: hashicorp-forge/go-test-split-action@ddb2685fb140c29505663b405af7eb2cd953dd13 # v2.0.1
with:
packages: ./integration
total: ${{ matrix.parallel }}
@@ -12,7 +12,6 @@ on:
- 'integration/integration_test.go'
env:
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:
@@ -22,17 +21,18 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Set up KO
uses: ko-build/setup-ko@v0.6
uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6
env:
KO_DOCKER_REPO: ko.local
+10 -13
View File
@@ -9,9 +9,6 @@ on:
- '**.md'
- 'script/gcg/**'
env:
GO_VERSION: '1.24'
jobs:
generate-packages:
name: List Go Packages
@@ -20,14 +17,14 @@ jobs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Generate matrix
@@ -46,14 +43,14 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Tests
@@ -65,7 +62,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
@@ -73,7 +70,7 @@ jobs:
run: corepack enable
- name: Set up Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: webui/.nvmrc
cache: 'yarn'
+14 -20
View File
@@ -6,8 +6,7 @@ on:
- '*'
env:
GO_VERSION: '1.24'
GOLANGCI_LINT_VERSION: v2.0.2
GOLANGCI_LINT_VERSION: v2.10.1
MISSPELL_VERSION: v0.7.0
jobs:
@@ -17,18 +16,18 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
version: "${{ env.GOLANGCI_LINT_VERSION }}"
@@ -37,14 +36,14 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: Install misspell ${{ env.MISSPELL_VERSION }}
@@ -58,14 +57,14 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
go-version-file: '.go-version'
check-latest: true
- name: go generate
@@ -73,11 +72,6 @@ jobs:
make generate
git diff --exit-code
- name: go mod tidy
run: |
go mod tidy
git diff --exit-code
- name: make generate-crd
run: |
make generate-crd
+1
View File
@@ -0,0 +1 @@
1.25
+24 -2
View File
@@ -36,6 +36,7 @@ linters:
- nilnil # Not relevant
- nlreturn # Not relevant
- noctx # Too strict
- noinlineerr # Too strict
- nonamedreturns # Too strict
- paralleltest # Not relevant
- prealloc # Too many false-positive.
@@ -47,6 +48,7 @@ linters:
- varnamelen # Not relevant
- wrapcheck # Too strict
- wsl # Too strict
- wsl_v5 # Too strict
settings:
depguard:
@@ -295,19 +297,39 @@ linters:
source: 'errors.New\("Nomad provider'
text: 'ST1005: error strings should not be capitalized'
- path: (.+)\.go
text: 'struct-tag: unknown option ''inline'' in JSON tag'
text: 'omitzero: Omitempty has no effect on nested struct field'
linters:
- modernize
- path: (.+)\.go
text: 'struct-tag: unknown option "inline" in json tag'
linters:
- revive
- path: (.+)\.go
text: 'struct-tag: unknown option ''omitzero'' in TOML tag'
text: 'struct-tag: unknown option "omitzero" in toml tag'
linters:
- revive
- path: (pkg/types/.+|pkg/api/.+|pkg/observability/types/.+)\.go
text: 'var-naming: avoid meaningless package names'
linters:
- revive
- path: ((cmd|pkg)/version/.*|pkg/config/runtime/.*|pkg/log/.*|pkg/(middlewares/)?metrics/.*|pkg/muxer/http/.+|pkg/provider/http/.+|pkg/tls/.+|pkg/proxy/httputil/.+|pkg/observability/metrics/.+)\.go
text: 'var-naming: avoid package names that conflict with Go standard library package names'
linters:
- revive
- path: (.+)\.go$
text: 'SA1019: http.CloseNotifier has been deprecated' # FIXME must be fixed
- path: (.+)\.go$
text: 'SA1019: dynamic.(TCPIPWhiteList|IPWhiteList) is deprecated: please use IPAllowList instead.'
- path: (.+)\.go$
text: 'SA1019: middlewareTCP.Spec.IPWhiteList is deprecated: please use IPAllowList instead.'
- path: (.+)\.go$
text: 'SA1019: cfg.(SSLRedirect|SSLTemporaryRedirect|SSLHost|SSLForceHost|FeaturePolicy) is deprecated'
- path: (.+)\.go$
text: 'SA1019: c.Providers.(ConsulCatalog|Consul|Nomad).Namespace is deprecated'
- path: pkg/middlewares/auth/basic_auth_test.go
text: 'SA1008: keys in http.Header are canonicalized, "x-user" is not canonical; fix the constant or use http.CanonicalHeaderKey'
- path: pkg/middlewares/auth/digest_auth_test.go
text: 'SA1008: keys in http.Header are canonicalized, "x-user" is not canonical; fix the constant or use http.CanonicalHeaderKey'
- path: pkg/provider/kubernetes/crd/kubernetes.go
text: "Function 'loadConfigurationFromCRD' has too many statements"
linters:
+113
View File
@@ -0,0 +1,113 @@
# Traefik — Contributor Guide for AI Agents
Traefik is a modern HTTP reverse proxy and load balancer that discovers services from orchestrators (Kubernetes, Docker, Nomad, ...) and wires up routing dynamically. This file is the canonical guide for AI coding agents (Claude Code, Codex, Gemini, Cursor, ...) working in this repository; `CLAUDE.md` is a thin pointer to this file. For everything not covered here, defer to [`CONTRIBUTING.md`](./CONTRIBUTING.md) and [`docs/content/contributing/`](./docs/content/contributing/).
> **Training-data notice.** Traefik evolved significantly between v2 and v3 (label formats, provider names, CRD shapes, middleware names). If anything you think you know about Traefik contradicts this file or the current code, trust this file and the code — not your training data.
## Core vocabulary
These terms appear everywhere in the code and configuration. Use them precisely; they are not interchangeable.
- **EntryPoint** — a network listener (port + protocol).
- **Router** — matches an incoming request and selects a service.
- **Middleware** — transforms a request or response in the routing chain (auth, headers, rate limiting, ...).
- **Service** — defines how to load-balance to backend servers.
- **Provider** — a source of dynamic configuration (Kubernetes CRD, Docker labels, a file, an HTTP endpoint, ...).
- **Static vs Dynamic configuration** — two distinct domains:
- *Static* is set at startup (entrypoints, providers, global options) and lives under [`pkg/config/static`](./pkg/config/static).
- *Dynamic* is produced by providers at runtime (routers, services, middlewares) and lives under [`pkg/config/dynamic`](./pkg/config/dynamic).
These terms are accurate for the code, but user-facing docs deliberately hide the distinction to keep things simpler for readers: when writing or editing under [`docs/content/`](./docs/content), prefer **install configuration** (over *static*) and **routing configuration** (over *dynamic*).
At request time the components chain in this order:
```
Client → EntryPoint → Router → Middleware chain → Service → Backend
```
The middleware chain is ordered: middlewares run in the sequence declared on the router, and the router match happens *before* any middleware runs.
## Where things live
- `cmd/traefik/` — main.
- `pkg/provider/` — one subpackage per provider (Kubernetes, Docker, file, ...).
- `pkg/server/` — routing core, middleware chain, configuration watcher.
- `pkg/middlewares/` — HTTP and TCP middleware implementations.
- `pkg/config/static`, `pkg/config/dynamic` — the two config domains above.
- `pkg/plugins/` — Yaegi and WASM plugin runtimes.
- `pkg/observability/logs/` — logging helpers; the project uses `github.com/rs/zerolog` exclusively.
- `webui/` — React dashboard. Built assets under `webui/static/` are embedded into the Go binary via `//go:embed` (see `webui/embed.go`) and must be regenerated with `make generate-webui` (Docker required) — they are not meant to be hand-edited.
- `integration/` — integration tests; reusable fixtures under `integration/fixtures/`.
- `docs/content/` — MkDocs sources for the public documentation.
## Before you edit
Read two or three existing files in the same package before adding a new one, and copy their structure. Do not invent new directory layouts, file-naming conventions, or abstraction boundaries — match the neighbours. When adding a new provider, read two existing providers under `pkg/provider/`; when adding a middleware, read two under `pkg/middlewares/`.
## Build, test, lint
The Go version is declared in [`go.mod`](./go.mod) — check there rather than hard-coding a version. All day-to-day commands go through `make`:
```bash
make binary # build the traefik binary (runs generate-webui first)
make test-unit # run Go unit tests
make test-integration # run integration tests (requires Docker)
make lint # run golangci-lint
make validate-files # misspell, shellcheck, generated-files check
make validate # lint + validate-files (run this before pushing)
make fmt # gofumpt / goimports
make generate # regenerate non-CRD generated code (deepcopy, etc.)
make generate-crd # regenerate Kubernetes CRD clientset + deepcopy
make generate-webui # rebuild the embedded WebUI assets (Docker required)
make docs-serve # preview the documentation locally
```
Full environment setup (Docker, `GOPATH` layout, Tailscale for Docker Desktop users, how to target a single integration test via `TESTFLAGS`) is documented in [`docs/content/contributing/building-testing.md`](./docs/content/contributing/building-testing.md). CI runs `make validate` and fails if `make generate` or `make generate-crd` leave the tree dirty — always commit regenerated files alongside the source change that triggered them.
## Code style
Standard Go formatting (`gofumpt`/`goimports`) and `golangci-lint` cover most rules automatically; run `make lint` to catch them. Two project-specific rules that tooling does **not** enforce:
- **Comments answer *why*, not *what*.** Comments that restate what the code already says are noise: they go stale and waste review time. Only add a comment when it records *why* the code exists — a constraint, a past incident, a spec reference, an edge case. Comments explaining *how* should be rare and usually indicate the code needs to be clearer. When a comment is present, it **must end with a period**.
- **Assertion messages are minimal.** Prefer `assert.Equal(t, expected, actual)` over `assert.Equal(t, expected, actual, "detailed explanation")`. The test name provides the context; a descriptive message is usually noise.
Prefer modern standard-library packages (`slices`, `maps`, `cmp`, ...) over hand-rolled helpers or third-party libraries when the Go version in `go.mod` supports them.
## Common patterns
- **Logging.** The project uses `github.com/rs/zerolog` exclusively — do not import `log`, `slog`, or `logrus`. Inside a middleware, get a logger via `middlewares.GetLogger(ctx, name, typeName)` (see [`pkg/middlewares/middleware.go`](./pkg/middlewares/middleware.go)) where `typeName` is a package-level `const` like `const typeNameForward = "ForwardAuth"`. Elsewhere, extract the logger from the context with `log.Ctx(ctx)` and attach it to a new context with `.WithContext(ctx)`.
- **Context propagation.** `context.Context` is always the first argument, named `ctx`. Avoid `context.Background()` in request paths; propagate from the caller. Define custom context keys as unexported struct types (`type myKey struct{}`) to prevent collisions.
## Testing conventions
- Unit tests live next to the code as `*_test.go` files using `testing.T` with `testify/assert` and `testify/require`.
- Use `require.*` for preconditions that must stop the test on failure (setup, must-not-be-nil). Use `assert.*` for independent checks where you want the test to keep running and report every failure.
- Integration tests under `integration/` are built on `testify/suite` (see `integration/integration_test.go`) and reuse fixtures from `integration/fixtures/`. New fixtures should follow the pattern of the existing ones.
- New providers require integration tests.
- Prefer running a focused test over the whole suite while iterating. When iterating on a failing test, capture the output to a file once and grep it (`... > /tmp/out.log 2>&1`) rather than re-running the suite with different `TESTFLAGS`. See [`docs/content/contributing/building-testing.md`](./docs/content/contributing/building-testing.md) for the `TESTFLAGS` invocation.
## Documentation
User-facing features need matching documentation updates under `docs/content/`. Integrate new pages into the existing structure rather than creating parallel sections. Preview locally with `make docs-serve`.
## Contributing etiquette
- **Target the right branch** (the [PR template](./.github/PULL_REQUEST_TEMPLATE.md) is authoritative): enhancements go to `master`; bug fixes and documentation updates go to the current maintenance branches (`v3.6` for v3, `v2.11` for v2, security-fixes only). Forward-ports from the maintenance branches up to `master` are handled by maintainers.
- Keep pull requests small and focused; one logical change per PR.
- For anything beyond a bug fix, open an issue first and wait for a maintainer to confirm the direction before investing significant work.
- Follow the full guide in [`docs/content/contributing/submitting-pull-requests.md`](./docs/content/contributing/submitting-pull-requests.md).
## AI assistance disclosure
Traefik welcomes AI-assisted contributions, provided a few simple rules are followed:
- **Declare substantial AI assistance** with an `Assisted-by:` trailer at the bottom of the commit message whenever an agent produced a meaningful portion of the diff — for example `Assisted-by: Claude Opus 4.6`. Trivial edits such as a typo fix or a one-line rename do not need a trailer.
- **Keep issue and PR conversations human.** Do not let an agent post comments, review replies, or triage messages on your behalf. If an agent drafted a message for you, rewrite it in your own voice before sending — maintainers need to know they are talking to a person, not a bot.
- **Align with a maintainer before generating code for anything larger than a bug fix.** An agent can produce thousands of lines in minutes; maintainer review capacity cannot scale the same way. Open an issue, state the intended approach, and wait for confirmation before asking an agent to implement it.
## Things to avoid
- Do not hand-edit generated files — notably `**/zz_generated*.go`, everything under `pkg/provider/kubernetes/crd/generated/`, and `webui/static/`. Regenerate them via `make generate`, `make generate-crd`, or `make generate-webui` and commit the result.
- Do not skip `make lint` and `make validate-files` (or `make validate`) before pushing.
- Do not opportunistically reformat, rename, or refactor files you did not otherwise need to touch. Drive-by changes turn a reviewable diff into noise — scope every PR to one logical change.
- Do not include unrelated refactors, formatting-only changes to untouched files, or speculative abstractions in a feature PR.
+318
View File
@@ -1,3 +1,321 @@
## [v3.6.18](https://github.com/traefik/traefik/tree/v3.6.18) (2026-06-03)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.17...v3.6.18)
**Bug fixes:**
- **[accesslogs]** Escape double quotes in quoted log fields ([#13180](https://github.com/traefik/traefik/pull/13180) @KaanSimsek)
- **[k8s/gatewayapi]** Escape exact gRPC method matches ([#13201](https://github.com/traefik/traefik/pull/13201) @nickmnt)
- **[logs, middleware]** Allow query parameters to be dropped from RequestPath in access log ([#13091](https://github.com/traefik/traefik/pull/13091) @calinelson)
- **[k8s/gatewayapi]** Bump github.com/moby/spdystream to v0.5.1 ([#13252](https://github.com/traefik/traefik/pull/13252) @kevinpollet)
- **[file]** Improve file provider behavior regarding dangling symlinks ([#12449](https://github.com/traefik/traefik/pull/12449) @fh-yuxiao-zeng)
- **[server]** Bump github.com/bytedance/sonic to v1.15.1 ([#13254](https://github.com/traefik/traefik/pull/13254) @kevinpollet)
- **[middleware, authentication]** Add error on basic auth build if users is empty ([#13195](https://github.com/traefik/traefik/pull/13195) @rtribotte)
- **[k8s/ingress]** Avoid ingress path matcher injection and backport 11d251415 ([#13227](https://github.com/traefik/traefik/pull/13227) @rtribotte)
- **[server]** Move snicheck to ctx instead of simulated routing ([#13214](https://github.com/traefik/traefik/pull/13214) @juliens)
- **[middleware]** Reject requests with different paths after StripPrefix and StripPrefixRegex normalisation ([#13215](https://github.com/traefik/traefik/pull/13215) @rtribotte)
- **[server]** Bump golang.org/x/net to v0.55.0 ([#13251](https://github.com/traefik/traefik/pull/13251) @kevinpollet)
- **[k8s/gatewayapi]** Change default values and expose configuration for Kubernetes client QPS and Burst ([#13277](https://github.com/traefik/traefik/pull/13277) @kevinpollet)
- **[server]** Bump golang.org/x/crypto to v0.52.0 ([#13276](https://github.com/traefik/traefik/pull/13276) @rtribotte)
**Documentation:**
- **[file]** Replace generated File routing reference page ([#13170](https://github.com/traefik/traefik/pull/13170) @sheddy-traefik)
- **[middleware]** Remove whitespace in HTML tag ([#13160](https://github.com/traefik/traefik/pull/13160) @marbon87)
- **[k8s/crd]** Fix typo in accesslogs field name ([#13177](https://github.com/traefik/traefik/pull/13177) @PlayMTL)
- **[k8s/ingress-nginx]** Surface the Ingress status race condition during NGINX coexistence ([#13205](https://github.com/traefik/traefik/pull/13205) @emilevauge)
- **[k8s/ingress-nginx]** Capitalize NGINX in kubernetesIngressNGINX ([#13236](https://github.com/traefik/traefik/pull/13236) @smellems)
- Polish grammar in migration guides ([#13174](https://github.com/traefik/traefik/pull/13174) @quyentonndbs)
- Add @LBF38 as a current maintainer ([#13225](https://github.com/traefik/traefik/pull/13225) @emilevauge)
## [v2.11.47](https://github.com/traefik/traefik/tree/v2.11.47) (2026-06-03)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.46...v2.11.47)
**Bug fixes:**
- **[middleware, authentication]** Add error on basic auth build if users is empty ([#13195](https://github.com/traefik/traefik/pull/13195) @rtribotte)
- **[k8s/ingress]** Avoid ingress path matcher injection and backport 11d251415 ([#13227](https://github.com/traefik/traefik/pull/13227) @rtribotte)
- **[server]** Move snicheck to ctx instead of simulated routing ([#13214](https://github.com/traefik/traefik/pull/13214) @juliens)
- **[middleware]** Reject requests with different paths after StripPrefix and StripPrefixRegex normalisation ([#13215](https://github.com/traefik/traefik/pull/13215) @rtribotte)
- **[server]** Bump golang.org/x/net to v0.55.0 ([#13251](https://github.com/traefik/traefik/pull/13251) @kevinpollet)
- **[server]** Bump golang.org/x/crypto to v0.52.0 ([#13276](https://github.com/traefik/traefik/pull/13276) @rtribotte)
## [v3.6.17](https://github.com/traefik/traefik/tree/v3.6.17) (2026-05-11)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.16...v3.6.17)
**Bug fixes:**
- **[k8s/ingress, k8s/crd, k8s/gatewayapi]** Add CrossProviderNamespaces option ([#13094](https://github.com/traefik/traefik/pull/13094) @rtribotte)
- **[k8s/crd]** Fix cross-provider ref check for Kubernetes CRD provider ([#13121](https://github.com/traefik/traefik/pull/13121) @rtribotte)
## [v2.11.46](https://github.com/traefik/traefik/tree/v2.11.46) (2026-05-11)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.45...v2.11.46)
**Bug fixes:**
- **[k8s/ingress, k8s/crd, k8s/gatewayapi]** Add CrossProviderNamespaces option ([#13094](https://github.com/traefik/traefik/pull/13094) @rtribotte)
- **[k8s/crd]** Fix cross-provider ref check for Kubernetes CRD provider ([#13121](https://github.com/traefik/traefik/pull/13121) @rtribotte)
## [v3.6.16](https://github.com/traefik/traefik/tree/v3.6.16) (2026-05-05)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.15...v3.6.16)
**Bug fixes:**
- **[k8s/crd]** Remove cross-provider sanitization for Kubernetes service loading ([#13087](https://github.com/traefik/traefik/pull/13087) @rtribotte)
- **[k8s/ingress-nginx]** Fix typo in default CORS allowed headers ([#13088](https://github.com/traefik/traefik/pull/13088) @mliang2)
- **[logs, metrics, tracing]** Bump go.opentelemetry.io/otel ([#13100](https://github.com/traefik/traefik/pull/13100) @juliens)
- **[docker, ecs]** Migrate to github.com/moby/moby modules ([#12672](https://github.com/traefik/traefik/pull/12672) @thaJeztah)
- **[docker, ecs]** Migrate to github.com/moby/moby modules ([#13053](https://github.com/traefik/traefik/pull/13053) @mmatur)
**Documentation:**
- **[k8s/gatewayapi]** Update Helm chart values link for Kubernetes Gateway ([#13063](https://github.com/traefik/traefik/pull/13063) @0054)
## [v2.11.45](https://github.com/traefik/traefik/tree/v2.11.45) (2026-05-05)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.44...v2.11.45)
**Bug fixes:**
- **[k8s/crd]** Remove cross-provider sanitization for Kubernetes service loading ([#13087](https://github.com/traefik/traefik/pull/13087) @rtribotte)
- **[docker, ecs]** Migrate to github.com/moby/moby modules ([#13053](https://github.com/traefik/traefik/pull/13053) @mmatur)
## [v3.6.15](https://github.com/traefik/traefik/tree/v3.6.15) (2026-04-29)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.14...v3.6.15)
**Bug fixes:**
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.35.2 ([#13043](https://github.com/traefik/traefik/pull/13043) @ldez)
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.35.1 ([#13027](https://github.com/traefik/traefik/pull/13027) @ldez)
- **[middleware]** Add errorRequestHeaders option to Errors middleware ([#13034](https://github.com/traefik/traefik/pull/13034) @gndz07)
- **[k8s/ingress-nginx]** Do not require a port for ExternalName services ([#13033](https://github.com/traefik/traefik/pull/13033) @kevinpollet)
- **[server]** Bump github.com/vulcand/oxy to v2.1.0 ([#13046](https://github.com/traefik/traefik/pull/13046) @ldez)
**Misc:**
- Make FLAGS Make variable usable ([#13009](https://github.com/traefik/traefik/pull/13009) @twz123)
## [v2.11.44](https://github.com/traefik/traefik/tree/v2.11.44) (2026-04-29)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.43...v2.11.44)
**Bug fixes:**
- **[middleware]** Add errorRequestHeaders option to Errors middleware ([#13034](https://github.com/traefik/traefik/pull/13034) @gndz07)
- **[acme]** Bump github.com/go-acme/lego to v4.35.2 ([#13052](https://github.com/traefik/traefik/pull/13052) @mmatur)
**Misc:**
- Make FLAGS Make variable usable ([#13009](https://github.com/traefik/traefik/pull/13009) @twz123)
## [v3.6.14](https://github.com/traefik/traefik/tree/v3.6.14) (2026-04-22)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.13...v3.6.14)
**Bug fixes:**
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.34.0 ([#12993](https://github.com/traefik/traefik/pull/12993) @ldez)
- **[docker]** Downgrade log level for missing container on inspect ([#12900](https://github.com/traefik/traefik/pull/12900) @Otoru)
- **[sticky-session, k8s/crd]** Make SameSite cookie value case-insensitive ([#12922](https://github.com/traefik/traefik/pull/12922) @murataslan1)
- **[k8s/crd, k8s]** Honor allowCrossNamespace with chain middleware CRD ([#12976](https://github.com/traefik/traefik/pull/12976) @rtribotte)
- **[middleware]** Remove untrusted X headers with underscores ([#12961](https://github.com/traefik/traefik/pull/12961) @rtribotte)
- **[middleware]** Sanitize the request URL after stripping the prefix ([#12990](https://github.com/traefik/traefik/pull/12990) @kevinpollet)
- **[middleware]** Deprecate ForwardAuth.TrustForwardHeader option ([#13012](https://github.com/traefik/traefik/pull/13012) @kevinpollet)
- **[middleware, authentication]** Remove map lookup making the basic auth notFoundSecret empty ([#12960](https://github.com/traefik/traefik/pull/12960) @rtribotte)
- **[middleware, authentication]** Fix trustForwardHeader on forward auth middleware ([#12994](https://github.com/traefik/traefik/pull/12994) @juliens)
- **[middleware, authentication]** Cleanup and make ForwardAuth logs consistent ([#13013](https://github.com/traefik/traefik/pull/13013) @kevinpollet)
- **[webui]** Upgrade form-data to 2.5.4, 3.0.4, 4.0.4 ([#12958](https://github.com/traefik/traefik/pull/12958) @orbisai0security)
**Documentation:**
- **[k8s]** Fix yaml indentation ([#12957](https://github.com/traefik/traefik/pull/12957) @isayme)
- **[k8s]** Clarify install config watchNamespace watches only one namespace ([#12962](https://github.com/traefik/traefik/pull/12962) @parkerfath)
- **[k8s/crd]** Update ingressroute.md ([#12916](https://github.com/traefik/traefik/pull/12916) @Rajakavitha1)
- Reverse versions order in migration guide ([#12959](https://github.com/traefik/traefik/pull/12959) @nmengin)
- Update vulnerability submission guidelines ([#12968](https://github.com/traefik/traefik/pull/12968) @emilevauge)
## [v2.11.43](https://github.com/traefik/traefik/tree/v2.11.43) (2026-04-22)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.42...v2.11.43)
**Bug fixes:**
- **[middleware, authentication]** Remove map lookup making the basic auth notFoundSecret empty ([#12960](https://github.com/traefik/traefik/pull/12960) @rtribotte)
- **[middleware, authentication]** Fix trustForwardHeader on forward auth middleware ([#12994](https://github.com/traefik/traefik/pull/12994) @juliens)
- **[middleware, authentication]** Cleanup and make ForwardAuth logs consistent ([#13013](https://github.com/traefik/traefik/pull/13013) @kevinpollet)
- **[middleware]** Remove untrusted X headers with underscores ([#12961](https://github.com/traefik/traefik/pull/12961) @rtribotte)
- **[middleware]** Sanitize the request URL after stripping the prefix ([#12990](https://github.com/traefik/traefik/pull/12990) @kevinpollet)
- **[k8s/crd, k8s]** Honor allowCrossNamespace with chain middleware CRD ([#12976](https://github.com/traefik/traefik/pull/12976) @rtribotte)
## [v3.6.13](https://github.com/traefik/traefik/tree/v3.6.13) (2026-04-07)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.12...v3.6.13)
**Bug fixes:**
- **[middleware]** Bump github.com/klauspost/compress v1.18.4 and fix TestNegotiation ([#12937](https://github.com/traefik/traefik/pull/12937) @thaJeztah)
**Documentation:**
- **[docker]** Fix docker-compose.yaml location in Docker setup page ([#12860](https://github.com/traefik/traefik/pull/12860) @ScottA38)
- **[docker, consul, ecs, k8s]** Fix documentation on how to restrict the scope of service discovery ([#12645](https://github.com/traefik/traefik/pull/12645) @mloiseleur)
- **[k8s/ingress-nginx]** Add OVHcloud (OpenStack Octavia) to Cloud-Specific IP Management ([#12759](https://github.com/traefik/traefik/pull/12759) @antonin-a)
- **[k8s/ingress-nginx]** Clarify IngressClass selection logic ([#12926](https://github.com/traefik/traefik/pull/12926) @kevinpollet)
- Add missing redirects for Getting started ([#12886](https://github.com/traefik/traefik/pull/12886) @nmengin)
- Add redirects for deleted pages ([#12889](https://github.com/traefik/traefik/pull/12889) @sheddy-traefik)
- Fix default value of http.sanitizePath ([#12904](https://github.com/traefik/traefik/pull/12904) @iTob191)
## [v3.6.12](https://github.com/traefik/traefik/tree/v3.6.12) (2026-03-26)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.11...v3.6.12)
**Bug fixes:**
- **[k8s/ingress-nginx]** Fix auth-response-headers whitespace trimming in ingress-nginx provider ([#12856](https://github.com/traefik/traefik/pull/12856) @mmatur)
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.33.0 ([#12840](https://github.com/traefik/traefik/pull/12840) @ldez)
- **[server]** Fix comment and unnecessary allocation in withRoutingPath ([#12880](https://github.com/traefik/traefik/pull/12880) @boinger)
- **[server, tcp]** Fix postgres STARTTLS with TLS termination ([#12847](https://github.com/traefik/traefik/pull/12847) @mmatur)
- **[api]** Fix allow colons and tildes in api.basePath validation ([#12857](https://github.com/traefik/traefik/pull/12857) @mmatur)
- **[grpc]** Bump google.golang.org/grpc to v1.79.3 ([#12845](https://github.com/traefik/traefik/pull/12845) @mmatur)
- **[middleware, authentication]** Prevent duplicate user headers in basic and digest auth middleware ([#12851](https://github.com/traefik/traefik/pull/12851) @juliens)
- **[middleware]** Fix StripPrefix and StripPrefixRegex to slice the prefix using encoded prefix length ([#12863](https://github.com/traefik/traefik/pull/12863) @gndz07)
**Documentation:**
- **[acme]** Clarify CNAME explanation in ACME Documentation ([#12818](https://github.com/traefik/traefik/pull/12818) @sheddy-traefik)
- **[k8s/ingress-nginx]** Add ingress-nginx migration banner on documentation pages ([#12872](https://github.com/traefik/traefik/pull/12872) @gndz07)
- **[k8s/ingress-nginx]** Clarify that NGINX Ingress watchNamespace watches only one namespace ([#12873](https://github.com/traefik/traefik/pull/12873) @parkerfath)
- **[k8s/ingress]** Improve Kubernetes Ingress Routing Documentation ([#12876](https://github.com/traefik/traefik/pull/12876) @sheddy-traefik)
## [v3.6.11](https://github.com/traefik/traefik/tree/v3.6.11) (2026-03-19)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.10...v3.6.11)
**Bug fixes:**
- **[logs, otel]** Add OTel-conformant trace context attributes to access logs ([#12801](https://github.com/traefik/traefik/pull/12801) @mmatur)
- **[k8s/gatewayapi]** Fix incorrect hostname matching between listener and route ([#12599](https://github.com/traefik/traefik/pull/12599) @TheColorman)
- **[k8s/ingress]** Fix ingress router's rule ([#12808](https://github.com/traefik/traefik/pull/12808) @gndz07)
- **[webui]** Remove AGPL license in code ([#12799](https://github.com/traefik/traefik/pull/12799) @Desel72)
- **[k8s/ingress-nginx]** Fix proxy-ssl-verify annotation ([#12825](https://github.com/traefik/traefik/pull/12825) @LBF38)
- **[http]** Add maxResponseBodySize configuration on HTTP provider ([#12788](https://github.com/traefik/traefik/pull/12788) @gndz07)
- **[tls]** Support fragmented TLS client hello ([#12787](https://github.com/traefik/traefik/pull/12787) @rtribotte)
- **[middleware, authentication]** Make basic auth check timing constant ([#12803](https://github.com/traefik/traefik/pull/12803) @rtribotte)
**Documentation:**
- **[k8s]** Improve the multi tenant security note ([#12822](https://github.com/traefik/traefik/pull/12822) @nmengin)
- Fix unnecessary escaping of pipe in regexp examples ([#12784](https://github.com/traefik/traefik/pull/12784) @diegmonti)
- Add vulnerability submission quality guidelines ([#12807](https://github.com/traefik/traefik/pull/12807) @emilevauge)
- Fix start up message format ([#12806](https://github.com/traefik/traefik/pull/12806) @mloiseleur)
- Remove unsupported servers[n].address from TCP label examples ([#12817](https://github.com/traefik/traefik/pull/12817) @sheddy-traefik)
- Bump mkdocs-traefiklabs to use consent mode ([#12804](https://github.com/traefik/traefik/pull/12804) @darkweaver87)
## [v2.11.42](https://github.com/traefik/traefik/tree/v2.11.42) (2026-03-26)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.41...v2.11.42)
**Bug fixes:**
- **[grpc]** Bump google.golang.org/grpc to v1.79.3 ([#12845](https://github.com/traefik/traefik/pull/12845) @mmatur)
- **[middleware, authentication]** Prevent duplicate user headers in basic and digest auth middleware ([#12851](https://github.com/traefik/traefik/pull/12851) @juliens)
- **[middleware]** Fix StripPrefix and StripPrefixRegex to slice the prefix using encoded prefix length ([#12863](https://github.com/traefik/traefik/pull/12863) @gndz07)
## [v2.11.41](https://github.com/traefik/traefik/tree/v2.11.41) (2026-03-18)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.40...v2.11.41)
**Bug fixes:**
- **[http]** Add maxResponseBodySize configuration on HTTP provider ([#12788](https://github.com/traefik/traefik/pull/12788) @gndz07)
- **[tls]** Support fragmented TLS client hello ([#12787](https://github.com/traefik/traefik/pull/12787) @rtribotte)
- **[middleware, authentication]** Make basic auth check timing constant ([#12803](https://github.com/traefik/traefik/pull/12803) @rtribotte)
**Documentation:**
- Bump mkdocs-traefiklabs to use consent mode ([#12804](https://github.com/traefik/traefik/pull/12804) @darkweaver87)
## [v3.6.10](https://github.com/traefik/traefik/tree/v3.6.10) (2026-03-06)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.9...v3.6.10)
**Bug fixes:**
- **[docker]** Bump Docker and OpenTelemetry dependencies ([#12761](https://github.com/traefik/traefik/pull/12761) by [mmatur](https://github.com/mmatur))
- **[fastproxy]** Bump github.com/valyala/fasthttp to v1.69.0 ([#12763](https://github.com/traefik/traefik/pull/12763) by [kevinpollet](https://github.com/kevinpollet))
- **[healthcheck, grpc]** Remove path parsing with grpc healthcheck ([#12760](https://github.com/traefik/traefik/pull/12760) by [rtribotte](https://github.com/rtribotte))
- **[k8s/gatewayapi]** Fix Gateway API router's rules ([#12753](https://github.com/traefik/traefik/pull/12753) by [rtribotte](https://github.com/rtribotte))
- **[middleware]** Fix HasSecureHeadersDefined returning false when stsSeconds is 0 ([#12684](https://github.com/traefik/traefik/pull/12684) by [veeceey](https://github.com/veeceey))
- **[otel]** Bump go.opentelemetry.io/otel dependencies ([#12754](https://github.com/traefik/traefik/pull/12754) by [rtribotte](https://github.com/rtribotte))
- **[server]** Bump golang.org/x/net to v0.51.0 ([#12756](https://github.com/traefik/traefik/pull/12756) by [kevinpollet](https://github.com/kevinpollet))
- **[webui]** Fix priority display in dashboard and ACME bypass redirect ([#12740](https://github.com/traefik/traefik/pull/12740) by [mmatur](https://github.com/mmatur))
- **[webui]** Fix basePath validation for dashboard template ([#12729](https://github.com/traefik/traefik/pull/12729) by [gndz07](https://github.com/gndz07))
**Documentation:**
- **[middleware]** Correct documentation for Digest auth ([#12651](https://github.com/traefik/traefik/pull/12651) by [Zash](https://github.com/Zash))
- Add missing `.http` to TOML table names ([#12713](https://github.com/traefik/traefik/pull/12713) by [Darsstar](https://github.com/Darsstar))
- Fix incorrect TOML example in entrypoints docs ([#12711](https://github.com/traefik/traefik/pull/12711) by [mfmfuyu](https://github.com/mfmfuyu))
- Fix API basepath option documentation ([#12744](https://github.com/traefik/traefik/pull/12744) by [nmengin](https://github.com/nmengin))
## [v2.11.40](https://github.com/traefik/traefik/tree/v2.11.40) (2026-03-06)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.38...v2.11.40)
**Bug fixes:**
- **[docker]** Bump Docker and OpenTelemetry dependencies ([#12761](https://github.com/traefik/traefik/pull/12761) by [mmatur](https://github.com/mmatur))
- **[server]** Bump golang.org/x/net to v0.51.0 ([#12756](https://github.com/traefik/traefik/pull/12756) by [kevinpollet](https://github.com/kevinpollet))
## [v2.11.39](https://github.com/traefik/traefik/tree/v2.11.39) (2026-03-06)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.38...v2.11.39)
Release canceled.
## [v3.6.9](https://github.com/traefik/traefik/tree/v3.6.9) (2026-02-23)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.8...v3.6.9)
**Bug fixes:**
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.32.0 ([#12702](https://github.com/traefik/traefik/pull/12702) by [ldez](https://github.com/ldez))
- **[middleware]** Fix case sensitivity on x-forwarded headers for Connection ([#12690](https://github.com/traefik/traefik/pull/12690) by [LBF38](https://github.com/LBF38))
- **[middleware, authentication]** Handle empty/missing User-Agent header ([#12545](https://github.com/traefik/traefik/pull/12545) by [a-stangl](https://github.com/a-stangl))
- **[middleware, authentication]** Add maxResponseBodySize configuration to forwardAuth middleware ([#12694](https://github.com/traefik/traefik/pull/12694) by [gndz07](https://github.com/gndz07))
- **[server]** Fix TLS handshake error handling ([#12692](https://github.com/traefik/traefik/pull/12692) by [juliens](https://github.com/juliens))
**Documentation:**
- **[docker]** Update docker in-depth setup guide ([#12682](https://github.com/traefik/traefik/pull/12682) by [mdevino](https://github.com/mdevino))
- **[k8s]** Make labelSelector option casing more consistent ([#12658](https://github.com/traefik/traefik/pull/12658) by [holysoles](https://github.com/holysoles))
- **[k8s/ingress-nginx]** Add temporary note to advertise the incoming NGINX annotations ([#12699](https://github.com/traefik/traefik/pull/12699) by [nmengin](https://github.com/nmengin))
- Increased content width in documentation ([#12632](https://github.com/traefik/traefik/pull/12632) by [tobiasge](https://github.com/tobiasge))
- Correct encoded characters allowance in entrypoints.md ([#12679](https://github.com/traefik/traefik/pull/12679) by [Apflkuacha](https://github.com/Apflkuacha))
## [v2.11.38](https://github.com/traefik/traefik/tree/v2.11.38) (2026-02-23)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.37...v2.11.38)
**Bug fixes:**
- **[middleware]** Fix case sensitivity on x-forwarded headers for Connection ([#12690](https://github.com/traefik/traefik/pull/12690) by [LBF38](https://github.com/LBF38))
- **[middleware, authentication]** Add maxResponseBodySize configuration to forwardAuth middleware ([#12694](https://github.com/traefik/traefik/pull/12694) by [gndz07](https://github.com/gndz07))
- **[server]** Fix TLS handshake error handling ([#12692](https://github.com/traefik/traefik/pull/12692) by [juliens](https://github.com/juliens))
## [v3.6.8](https://github.com/traefik/traefik/tree/v3.6.8) (2026-02-11)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.7...v3.6.8)
**Bug fixes:**
- **[acme]** Remove invalid private key in log ([#12574](https://github.com/traefik/traefik/pull/12574) by [juliens](https://github.com/juliens))
- **[acme]** Alter TLS renewal period ([#12479](https://github.com/traefik/traefik/pull/12479) by [LtHummus](https://github.com/LtHummus))
- **[healthcheck]** Reject absolute URL in healthcheck path configuration ([#12653](https://github.com/traefik/traefik/pull/12653) by [rtribotte](https://github.com/rtribotte))
- **[http3]** Bump github.com/quic-go/quic-go to v0.59.0 ([#12553](https://github.com/traefik/traefik/pull/12553) by [jnoordsij](https://github.com/jnoordsij))
- **[metrics,tracing,accesslogs]** Fix ObservabilityConfig SetDefaults ([#12636](https://github.com/traefik/traefik/pull/12636) by [mmatur](https://github.com/mmatur))
- **[server]** Remove conn deadline after STARTTLS negociation ([#12639](https://github.com/traefik/traefik/pull/12639) by [rtribotte](https://github.com/rtribotte))
- **[tls]** Fix verifyServerCertMatchesURI function behavior ([#12575](https://github.com/traefik/traefik/pull/12575) by [kevinpollet](https://github.com/kevinpollet))
- **[tracing,otel]** Use ParentBased sampler to respect parent span sampling decision ([#12403](https://github.com/traefik/traefik/pull/12403) by [xe-leon](https://github.com/xe-leon))
- **[webui]** Use url.Parse to validate X-Forwarded-Prefix value ([#12643](https://github.com/traefik/traefik/pull/12643) by [kevinpollet](https://github.com/kevinpollet))
- **[healthcheck]** Validate healthcheck path configuration (#12642 by @rtribotte)
- **[tls, server]** Cap TLS record length to RFC 8446 limit in ClientHello peeking (#12638 by @mmatur)
- **[service]** Avoid recursion with services ([#12591](https://github.com/traefik/traefik/pull/12591) by [juliens](https://github.com/juliens))
- **[webui]** Bump dependencies of documentation and webui ([#12581](https://github.com/traefik/traefik/pull/12581) by [gndz07](https://github.com/gndz07))
**Documentation:**
- **[k8s]** Fix kubernetes.md with correct http redirections ([#12603](https://github.com/traefik/traefik/pull/12603) by [MartenM](https://github.com/MartenM))
- **[middleware,k8s/crd]** Fix the errors middleware&#39;s document for Kubernetes CRD ([#12600](https://github.com/traefik/traefik/pull/12600) by [yuito-it](https://github.com/yuito-it))
- **[tls]** Clarify SNI selection ([#12482](https://github.com/traefik/traefik/pull/12482) by [AnuragEkkati](https://github.com/AnuragEkkati))
- Fix typo on JWT documentation ([#12616](https://github.com/traefik/traefik/pull/12616) by [mdevino](https://github.com/mdevino))
- Add @gndz07 as a current maintainer ([#12594](https://github.com/traefik/traefik/pull/12594) by [emilevauge](https://github.com/emilevauge))
- Remove extraneous dots in migration guide ([#12571](https://github.com/traefik/traefik/pull/12571) by [dathbe](https://github.com/dathbe))
- Document Path matcher placeholder removal in v3 migration guide ([#12570](https://github.com/traefik/traefik/pull/12570) by [sheddy-traefik](https://github.com/sheddy-traefik))
- Improve Service Reference page ([#12541](https://github.com/traefik/traefik/pull/12541) by [sheddy-traefik](https://github.com/sheddy-traefik))
- Document negative priority support for routers ([#12505](https://github.com/traefik/traefik/pull/12505) by [understood-the-assignment](https://github.com/understood-the-assignment))
- Improve the structure of the routing reference pages ([#12429](https://github.com/traefik/traefik/pull/12429) by [sheddy-traefik](https://github.com/sheddy-traefik))
- Clean Up Menu Entries &amp; Update Expose Overview ([#12405](https://github.com/traefik/traefik/pull/12405) by [sheddy-traefik](https://github.com/sheddy-traefik))
- Split Expose User Guides &amp; Add Multi-Layer Routing Section ([#12238](https://github.com/traefik/traefik/pull/12238) by [sheddy-traefik](https://github.com/sheddy-traefik))
- Remove extra dots in migration guide ([#12573](https://github.com/traefik/traefik/pull/12573) by [rtribotte](https://github.com/rtribotte))
**Misc:**
- Merge v2.11 into v3.6 ([#12652](https://github.com/traefik/traefik/pull/12652) by [mmatur](https://github.com/mmatur))
- Merge v2.11 into v3.6 ([#12644](https://github.com/traefik/traefik/pull/12644) by [mmatur](https://github.com/mmatur))
- Merge branch v2.11 into v3.6 ([#12617](https://github.com/traefik/traefik/pull/12617) by [mmatur](https://github.com/mmatur))
- Merge v2.11 into v3.6 ([#12605](https://github.com/traefik/traefik/pull/12605) by [mmatur](https://github.com/mmatur))
- Merge v2.11 into v3.6 ([#12601](https://github.com/traefik/traefik/pull/12601) by [mmatur](https://github.com/mmatur))
- Merge branch v2.11 into v3.6 ([#12556](https://github.com/traefik/traefik/pull/12556) by [mmatur](https://github.com/mmatur))
## [v2.11.37](https://github.com/traefik/traefik/tree/v2.11.37) (2026-02-11)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.36...v2.11.37)
**Bug fixes:**
- **[healthcheck]** Validate healthcheck path configuration (#12642 by @rtribotte)
- **[tls, server]** Cap TLS record length to RFC 8446 limit in ClientHello peeking (#12638 by @mmatur)
## [v2.11.36](https://github.com/traefik/traefik/tree/v2.11.36) (2026-02-02)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.35...v2.11.36)
**Bug fixes:**
- **[service]** Avoid recursion with services ([#12591](https://github.com/traefik/traefik/pull/12591) by [juliens](https://github.com/juliens))
- **[webui]** Bump dependencies of documentation and webui ([#12581](https://github.com/traefik/traefik/pull/12581) by [gndz07](https://github.com/gndz07))
**Documentation:**
- Remove extra dots in migration guide ([#12573](https://github.com/traefik/traefik/pull/12573) by [rtribotte](https://github.com/rtribotte))
## [v3.6.7](https://github.com/traefik/traefik/tree/v3.6.7) (2026-01-14)
[All Commits](https://github.com/traefik/traefik/compare/v3.6.6...v3.6.7)
+1
View File
@@ -0,0 +1 @@
@AGENTS.md
+1 -1
View File
@@ -58,7 +58,7 @@ generate:
#? binary: Build the binary
binary: generate-webui dist
@echo SHA: $(VERSION) $(CODENAME) $(DATE)
CGO_ENABLED=0 GOGC=${GOGC} GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS[*]} -ldflags "-s -w \
CGO_ENABLED=0 GOGC=${GOGC} GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS} -ldflags "-s -w \
-X github.com/traefik/traefik/v3/pkg/version.Version=$(VERSION) \
-X github.com/traefik/traefik/v3/pkg/version.Codename=$(CODENAME) \
-X github.com/traefik/traefik/v3/pkg/version.BuildDate=$(DATE)" \
+1
View File
@@ -10,6 +10,7 @@ import (
// TraefikCmdConfiguration wraps the static configuration and extra parameters.
type TraefikCmdConfiguration struct {
static.Configuration `export:"true"`
// ConfigFile is the path to the configuration file.
ConfigFile string `description:"Configuration file to use. If specified all other flags are ignored." export:"true"`
}
+4 -4
View File
@@ -158,7 +158,7 @@ func (c Centrifuge) run(sc *types.Scope, rootPkg string, pkgName string) map[str
func (c Centrifuge) writeStruct(name string, obj *types.Struct, rootPkg string, elt *File) string {
b := strings.Builder{}
b.WriteString(fmt.Sprintf("type %s struct {\n", name))
fmt.Fprintf(&b, "type %s struct {\n", name)
for i := range obj.NumFields() {
field := obj.Field(i)
@@ -175,7 +175,7 @@ func (c Centrifuge) writeStruct(name string, obj *types.Struct, rootPkg string,
fType := c.TypeCleaner(field.Type(), rootPkg)
if field.Embedded() {
b.WriteString(fmt.Sprintf("\t%s\n", fType))
fmt.Fprintf(&b, "\t%s\n", fType)
continue
}
@@ -184,10 +184,10 @@ func (c Centrifuge) writeStruct(name string, obj *types.Struct, rootPkg string,
continue
}
b.WriteString(fmt.Sprintf("\t%s %s", field.Name(), fType))
fmt.Fprintf(&b, "\t%s %s", field.Name(), fType)
if ok {
b.WriteString(fmt.Sprintf(" `json:\"%s\"`", strings.Join(values, ",")))
fmt.Fprintf(&b, " `json:\"%s\"`", strings.Join(values, ","))
}
b.WriteString("\n")
+1 -1
View File
@@ -83,7 +83,7 @@ func run(dest string) error {
return err
}
return os.WriteFile(filepath.Join(dest, "marshaler.go"), []byte(fmt.Sprintf(marsh, destPkg)), 0o666)
return os.WriteFile(filepath.Join(dest, "marshaler.go"), fmt.Appendf(nil, marsh, destPkg), 0o666)
}
func cleanType(typ types.Type, base string) string {
+3 -3
View File
@@ -97,9 +97,9 @@ func runCmd(staticConfiguration *static.Configuration) error {
return fmt.Errorf("setting up logger: %w", err)
}
log.Warn().Msg("Traefik can reject some encoded characters in the request path." +
"When your backend is not fully compliant with [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986)," +
"it is recommended to set these options to `false` to avoid split-view situation." +
log.Warn().Msg("Traefik can reject some encoded characters in the request path. " +
"When your backend is not fully compliant with [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986), " +
"it is recommended to set these options to `false` to avoid split-view situation. " +
"Refer to the documentation for more details: https://doc.traefik.io/traefik/v3.6/migrate/v3/#encoded-characters-configuration-default-values")
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
+1 -1
View File
@@ -21,7 +21,7 @@ docs: docs-clean docs-image docs-lint docs-build docs-verify
# Writer Mode: build and serve docs on http://localhost:8000 with livereload
.PHONY: docs-serve
docs-serve: docs-image
docker run $(DOCKER_RUN_DOC_OPTS) $(TRAEFIK_DOCS_BUILD_IMAGE) mkdocs serve
docker run $(DOCKER_RUN_DOC_OPTS) $(TRAEFIK_DOCS_BUILD_IMAGE) mkdocs serve -a 0.0.0.0:8000
## Pull image for doc building
.PHONY: docs-pull-images
+41
View File
@@ -0,0 +1,41 @@
#migration-doc-banner {
display: block;
position: relative;
padding: 0.6em 1.2em;
border: 1px solid #00b3ce;
border-radius: 8px;
background-color: #00b3ce1a;
color: #00b3ce;
font-size: 0.85em;
margin-bottom: 1em;
}
#migration-doc-banner a {
color: #00b3ce;
font-weight: 600;
text-decoration: underline;
}
#migration-doc-banner p {
margin: 0;
}
#migration-doc-banner-close {
position: absolute;
top: 0.4em;
right: 0.6em;
background: none;
border: none;
color: #00b3ce;
font-size: 1.5em;
line-height: 1;
cursor: pointer;
padding: 0;
}
/* Breakpoint for the collapsed sidebar */
@media (min-width: 1220px) {
#migration-doc-banner {
margin-top: -24px;
}
}
@@ -0,0 +1,4 @@
/* Use a wider grid to accommodate table content and code blocks. */
.md-grid {
max-width: 1650px;
}
+38
View File
@@ -0,0 +1,38 @@
(function () {
var BANNER_ID = 'migration-doc-banner';
var SESSION_KEY = 'migration-doc-banner-dismissed';
function createBanner() {
if (document.getElementById(BANNER_ID)) return;
if (sessionStorage.getItem(SESSION_KEY)) return;
var banner = document.createElement('div');
banner.id = BANNER_ID;
banner.innerHTML =
'<p><strong>Moving from ingress-nginx?</strong></p>' +
'<p>No need to start over. Traefik supports your existing ingress-nginx annotations as-is &mdash; no rewrites, no downtime.</p>' +
'<p>See our <a href="/traefik/migrate/nginx-to-traefik/">migration guide</a> and <a href="/traefik/reference/routing-configuration/kubernetes/ingress-nginx/">annotation reference</a> to get started.</p>' +
'<button id="migration-doc-banner-close" aria-label="Dismiss banner">&times;</button>';
var target =
document.querySelector('.md-content__inner') ||
document.querySelector('.md-main__inner') ||
document.querySelector('article') ||
document.querySelector('main');
if (target) {
target.insertBefore(banner, target.firstChild);
}
document.getElementById('migration-doc-banner-close').addEventListener('click', function () {
banner.remove();
sessionStorage.setItem(SESSION_KEY, '1');
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', createBanner);
} else {
createBanner();
}
})();
@@ -49,7 +49,7 @@ As a maintainer, you are granted a vote for the following:
- [Proposals](https://github.com/traefik/contributors-guide/blob/master/proposals.md).
Maintainers are also added to the maintainer's Discord server where happens the [issue triage](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md)
and appear on the [Maintainers](maintainers.md) page.
and appear on the [Maintainers](./maintainers.md) page.
As a maintainer, you should:
+3 -1
View File
@@ -23,6 +23,8 @@ description: "Traefik Proxy is an open source software with a thriving community
* Simon Delicata [@sdelicata](https://github.com/sdelicata)
* Baptiste Mayelle [@youkoulayley](https://github.com/youkoulayley)
* Jesper Noordsij [@jnoordsij](https://github.com/jnoordsij)
* Gina Adzani [@gndz07](https://github.com/gndz07)
* Mathis Urien [@LBF38](https://github.com/LBF38)
## Past Maintainers
@@ -37,4 +39,4 @@ People who have had an incredibly positive impact on the project, and are now fo
## Maintainer's Guidelines
Please read the [maintainer's guidelines](maintainers-guidelines.md).
Please read the [maintainer's guidelines](./maintainers-guidelines.md).
@@ -8,7 +8,7 @@ description: "Looking to contribute to Traefik Proxy? This guide will show you t
This guide is for contributors who already have a pull request to submit.
If you are looking for information on setting up your developer environment
and creating code to contribute to Traefik Proxy or related projects,
see the [development guide](https://docs.traefik.io/contributing/building-testing/).
see the [development guide](./building-testing.md).
Looking for a way to contribute to Traefik Proxy?
Check out this list of [Priority Issues](https://github.com/traefik/traefik/labels/contributor%2Fwanted),
@@ -46,7 +46,7 @@ Read more about the [Triage process](https://github.com/traefik/contributors-gui
Merging a PR requires the following steps to be completed before it is merged automatically.
* Make sure your pull request adheres to our best practices. These include:
* [Following project conventions](https://github.com/traefik/traefik/blob/master/docs/content/contributing/maintainers-guidelines.md); including using the PR Template.
* [Following project conventions](./maintainers-guidelines.md); including using the PR Template.
* Make small pull requests.
* Solve only one problem at a time.
* Comment thoroughly.
@@ -15,9 +15,65 @@ You can subscribe by sending an email to security+subscribe@traefik.io or on [th
Reported vulnerabilities can be found on
[cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik).
CVEs are only created for vulnerabilities affecting **Generally Available (GA) versions** of Traefik.
Vulnerabilities discovered in non-GA versions (release candidates, betas, early access, or development branches)
will be fixed without creating a CVE.
## Report a Vulnerability
We want to keep Traefik safe for everyone.
If you've discovered a security vulnerability in Traefik,
we appreciate your help in disclosing it to us in a responsible manner,
by creating a [security advisory](https://github.com/traefik/traefik/security/advisories).
## Code of Conduct for Vulnerability Submissions
We are committed to handling every legitimate report responsibly,
and we expect submitters to engage with our security team in a respectful and collaborative manner.
The following behaviors are **not acceptable** and will not be tolerated:
- **Threats** to publicly disclose the vulnerability if it is not fixed within a timeframe you set unilaterally.
- **Ultimatums** or pressure tactics intended to force a faster response than our normal triage and remediation process allows.
- **Demands** for payment, bug bounties, or any form of compensation in exchange for not disclosing the issue
(Traefik does not operate a paid bug bounty program).
- **Aggressive, abusive, or disrespectful communication** with our security team.
Submitters who engage in any of the above may face the following consequences:
- The submitter **will not be credited** in the security advisory or any subsequent communication.
- The submitter's GitHub profile may be **reported to GitHub** for violation of platform terms of service.
- We may **decline to engage further** on the report, while still addressing the underlying issue if it is legitimate.
We take security seriously and act on legitimate reports as quickly as our resources allow.
Patience and constructive dialogue help us protect users effectively.
## Submission Quality Guidelines
We have been receiving an increasing number of low-quality vulnerability reports that are not actual security issues.
Many of these reports originate from AI/LLM tools and are submitted without any human validation or testing.
This wastes the time of our security team and delays the handling of legitimate vulnerabilities.
Before submitting a security advisory, you **must**:
- **Carefully test and validate** the vulnerability yourself before submitting.
You must be able to demonstrate a working proof of concept with clear reproduction steps.
- **Understand the impact** of the vulnerability and explain how it can be exploited in a realistic scenario.
- **Verify that the issue is not a false positive**.
Ensure the behavior you are reporting is actually a security concern and not expected behavior.
### Policy on AI-Generated Reports
Security reports that are **directly generated by AI/LLM tools without proper human validation** will be **closed immediately**.
Indicators of unvalidated AI-generated reports include (but are not limited to):
- No working proof of concept or reproduction steps.
- Generic or theoretical vulnerability descriptions with no evidence of actual testing.
- Misunderstanding of Traefik's architecture or threat model.
- Hallucinated code paths, configuration options, or behaviors that do not exist.
**Contributors who repeatedly submit low-quality or unvalidated reports may have their accounts blocked.**
We appreciate the work of security researchers who take the time to rigorously validate their findings.
Quality over quantity helps keep Traefik safe for everyone.
@@ -1,252 +1,29 @@
# Exposing Services with Traefik on Docker
# Exposing Services with Traefik on Docker - Advanced
This guide will help you expose your services securely through Traefik Proxy using Docker. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Docker before proceeding.
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for hierarchical routing with a complex authentication based routing example
## Prerequisites
- Completed the [Basic Guide](basic.md)
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the Traefik Docker Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service in `docker-compose.yml`:
```yaml
labels:
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
@@ -255,10 +32,10 @@ labels:
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply middlewares to whoami router
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
@@ -288,7 +65,7 @@ curl -k -I -H "Host: whoami.docker.localhost" https://localhost/
In the response headers, you should see security headers set by the middleware:
- `X-Frame-Options: DENY`
- `X-Frame-Options: DENY`
- `X-Content-Type-Options: nosniff`
- `X-XSS-Protection: 1; mode=block`
- `Strict-Transport-Security` with the appropriate settings
@@ -438,28 +215,191 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "Provider Requirement"
Multi-layer routing requires the File provider, as Docker labels do not support the `parentRefs` field. However, you can use **both Docker and File providers together** - Docker labels for service discovery and File configuration for multi-layer routing.
### Setup Multi-Layer Routing with Docker
To use multi-layer routing with Docker, you need to enable the File provider alongside the Docker provider.
Update your Traefik service in `docker-compose.yml`:
```yaml
services:
traefik:
image: "traefik:latest"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic" # Enable File provider
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./dynamic:/etc/traefik/dynamic:ro" # Mount directory for dynamic config
```
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent router authenticates requests, and child routers direct traffic based on user roles.
First, keep your Docker services defined with labels as usual:
```yaml
# In docker-compose.yml
services:
# ... traefik service from above ...
# Mock authentication service that adds X-User-Role header
auth-service:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=Auth Service
labels:
- "traefik.enable=true"
- "traefik.http.services.auth-service.loadbalancer.server.port=80"
# Admin backend service
admin-backend:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=Admin Backend
labels:
- "traefik.enable=true"
- "traefik.http.services.admin-backend.loadbalancer.server.port=80"
# User backend service
user-backend:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=User Backend
labels:
- "traefik.enable=true"
- "traefik.http.services.user-backend.loadbalancer.server.port=80"
```
Now create the multi-layer routing configuration in a file. Create `dynamic/mlr.yml`:
```yaml
http:
routers:
# Parent router with authentication middleware
api-parent:
rule: "Host(`api.docker.localhost`) && PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
# Note: No service and no TLS config - this is a parent router
# Child router for admin users
api-admin:
rule: "HeadersRegexp(`X-Auth-User`, `admin`)"
service: admin-backend@docker # Reference Docker service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
# Child router for regular users
api-user:
rule: "HeadersRegexp(`X-Auth-User`, `user`)"
service: user-backend@docker # Reference Docker service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
middlewares:
auth-middleware:
basicAuth:
users:
- "admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0"
- "user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI."
headerField: X-Auth-User
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
!!! important "Cross-Provider References"
Notice the `@docker` suffix on service names and the `@file` suffix in `parentRefs`. When using the File provider to orchestrate multi-layer routing with Docker services:
- Use `service-name@docker` to reference Docker services
- Use `parent-name@file` in `parentRefs` to reference the parent router in the File provider
The `@provider` suffix tells Traefik which provider namespace to look in for the resource.
Apply the changes:
```bash
docker compose up -d
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.docker.localhost/api`
2. **Parent router** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child router** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Docker service
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Docker
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Docker. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Docker, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../../reference/install-configuration/providers/docker.md) for more details about the Docker integration
+250
View File
@@ -0,0 +1,250 @@
# Exposing Services with Traefik on Docker - Basic
This guide will help you get started with exposing your services through Traefik Proxy using Docker. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
## Prerequisites
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the [Traefik Docker Setup guide](../../setup/docker.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Docker, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing
@@ -1,432 +1,25 @@
# Exposing Services with Traefik on Kubernetes
# Exposing Services with Traefik on Kubernetes - Advanced
This guide will help you expose your services securely through Traefik Proxy on Kubernetes. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding security middleware, and configuring sticky sessions. For routing, this guide gives you two options:
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Kubernetes before proceeding.
- [Gateway API](../reference/routing-configuration/kubernetes/gateway-api.md)
- [IngressRoute](../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
Feel free to choose the one that fits your needs best.
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management (IngressRoute)
- **cert-manager** for automated certificate management (Gateway API)
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for hierarchical routing with complex authentication scenarios (IngressRoute only)
## Prerequisites
- Completed the [Basic Guide](basic.md)
- A Kubernetes cluster with Traefik Proxy installed
- `kubectl` configured to interact with your cluster
- Traefik deployed using the Traefik Kubernetes Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://github.com/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create the deployment and service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
```
Save this as `whoami.yaml` and apply it:
```bash
kubectl apply -f whoami.yaml
```
Now, let's create routes using either Gateway API or IngressRoute.
### Using Gateway API
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # This Gateway is automatically created by Traefik
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Save this as `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### Using IngressRoute
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
!!! info
Make sure to remove the `ports.web.redirections` block from the `values.yaml` file if you followed the Kubernetes Setup Guide to install Traefik otherwise you will be redirected to the HTTPS entrypoint:
```yaml
redirections:
entryPoint:
to: websecure
```
You should see output similar to:
```bash
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on URL paths. This is useful for API versioning, frontend/backend separation, or organizing microservices.
First, deploy a second service to represent an API:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
```
Save this as `whoami-api.yaml` and apply it:
```bash
kubectl apply -f whoami-api.yaml
```
Now set up path-based routing:
### Gateway API with Path Rules
Update your existing `HTTPRoute` to include path-based routing:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with Path Rules
Update your existing IngressRoute to include path-based routing:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly:
```bash
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
```
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
```
Create a TLS secret in Kubernetes:
```bash
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
```
!!! important "Prerequisite for Gateway API with TLS"
Before using the Gateway API with TLS, you must define the `websecure` listener in your Traefik installation. This is typically done in your Helm values.
Example configuration in `values.yaml`:
```yaml
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
```
See the Traefik Kubernetes Setup Guide for complete installation details.
### Gateway API with TLS
Update your existing `HTTPRoute` to use the secured gateway listener:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # The HTTPS listener
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with TLS
Update your existing IngressRoute to use TLS:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # Changed from 'web' to 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # Added TLS configuration
```
Update the file `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify HTTPS Access
Now you can access your service securely. Since we're using a self-signed certificate, you'll need to skip certificate verification:
```bash
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
Your browser can also access https://whoami.docker.localhost/ (you'll need to accept the security warning for the self-signed certificate).
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
### Create Middlewares
@@ -469,37 +62,6 @@ kubectl apply -f middlewares.yaml
In Gateway API, you can apply middlewares using the `ExtensionRef` filter type. This is the preferred and standard way to use Traefik middlewares with Gateway API, as it integrates directly with the HTTPRoute specification.
First, make sure you have the same middlewares defined:
```yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secure-headers
namespace: default
spec:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ip-allowlist
namespace: default
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 10.0.0.0/8 # Typical cluster network range
- 192.168.0.0/16 # Common local network range
```
Now, update your `HTTPRoute` to reference these middlewares using the `ExtensionRef` filter:
```yaml
@@ -525,7 +87,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -543,7 +105,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -854,7 +416,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -876,7 +438,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@@ -986,29 +548,283 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Setup Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "IngressRoute Support"
Multi-layer routing is **natively supported** by Kubernetes IngressRoute (CRD) using the `spec.parentRefs` field. This feature is not available when using standard Kubernetes Ingress or Gateway API resources.
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent IngressRoute authenticates requests, and child IngressRoutes direct traffic based on user roles.
!!! important "Parent Router Requirements"
Parent routers in multi-layer routing must not have a service defined. The child routers will handle the service selection based on their matching rules. Make sure all child IngressRoutes reference the parent correctly using `parentRefs`.
First, deploy your backend services:
```yaml
# whoami-backends.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: admin-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: admin-backend
template:
metadata:
labels:
app: admin-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "Admin Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: admin-backend
namespace: default
spec:
selector:
app: admin-backend
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: user-backend
template:
metadata:
labels:
app: user-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "User Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: user-backend
namespace: default
spec:
selector:
app: user-backend
ports:
- port: 80
```
Apply the backend services:
```bash
kubectl apply -f whoami-backends.yaml
```
Now create the middleware and IngressRoutes for multi-layer routing:
```yaml
# mlr-ingressroute.yaml
apiVersion: v1
kind: Secret
metadata:
name: auth-secret
namespace: default
type: Opaque
stringData:
users: |
admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0
user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI.
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: default
spec:
basicAuth:
secret: auth-secret
headerField: X-Auth-User
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.docker.localhost`) && PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
# Note: No services and no TLS config - this is a parent IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-admin
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `admin`)
kind: Rule
services:
- name: admin-backend
port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-user
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `user`)
kind: Rule
services:
- name: user-backend
port: 80
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
Apply the multi-layer routing configuration:
```bash
kubectl apply -f mlr-ingressroute.yaml
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.docker.localhost/api`
2. **Parent IngressRoute** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child IngressRoute** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Kubernetes service
### Cross-Namespace Parent References
You can reference parent IngressRoutes in different namespaces by specifying the `namespace` field:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: app-namespace
spec:
parentRefs:
- name: api-parent
namespace: shared-namespace # Parent in different namespace
routes:
- match: Path(`/child`)
kind: Rule
services:
- name: child-service
port: 80
```
!!! important "Cross-Namespace Requirement"
To use cross-namespace parent references, you must enable the `allowCrossNamespace` option in your Traefik Helm values:
```yaml
providers:
kubernetesCRD:
allowCrossNamespace: true
```
### Multiple Parent References
Child IngressRoutes can reference multiple parent IngressRoutes:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: default
spec:
parentRefs:
- name: parent-one
- name: parent-two
routes:
- match: Path(`/api`)
kind: Rule
services:
- name: child-service
port: 80
```
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Kubernetes using both Gateway API and IngressRoute
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Automate certificate management with Let's Encrypt (IngressRoute) and cert-manager (Gateway API)
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing (IngressRoute only)
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Kubernetes. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Kubernetes. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Kubernetes, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Kubernetes Provider documentation](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) for more details about the Kubernetes integration.
- [Gateway API provider documentation](../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md) for more details about the Gateway API integration.
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Kubernetes Provider documentation](../../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) for more details about the Kubernetes integration
- [Gateway API provider documentation](../../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md) for more details about the Gateway API integration
+438
View File
@@ -0,0 +1,438 @@
# Exposing Services with Traefik on Kubernetes - Basic
This guide will help you get started with exposing your services through Traefik Proxy on Kubernetes. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
For routing, this guide gives you two options:
- [Gateway API](../../reference/routing-configuration/kubernetes/gateway-api.md)
- [IngressRoute](../../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
Feel free to choose the one that fits your needs best.
## Prerequisites
- A Kubernetes cluster with Traefik Proxy installed
- `kubectl` configured to interact with your cluster
- Traefik deployed using the [Traefik Kubernetes Setup guide](../../setup/kubernetes.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://github.com/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create the deployment and service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
```
Save this as `whoami.yaml` and apply it:
```bash
kubectl apply -f whoami.yaml
```
Now, let's create routes using either Gateway API or IngressRoute.
### Using Gateway API
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # This Gateway is automatically created by Traefik
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Save this as `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### Using IngressRoute
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
!!! info
Make sure to remove the `ports.web.redirections` block from the `values.yaml` file if you followed the Kubernetes Setup Guide to install Traefik otherwise you will be redirected to the HTTPS entrypoint:
```yaml
redirections:
entryPoint:
to: websecure
```
You should see output similar to:
```bash
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on URL paths. This is useful for API versioning, frontend/backend separation, or organizing microservices.
First, deploy a second service to represent an API:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
```
Save this as `whoami-api.yaml` and apply it:
```bash
kubectl apply -f whoami-api.yaml
```
Now set up path-based routing:
### Gateway API with Path Rules
Update your existing `HTTPRoute` to include path-based routing:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with Path Rules
Update your existing IngressRoute to include path-based routing:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly:
```bash
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
```
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
```
Create a TLS secret in Kubernetes:
```bash
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
```
!!! important "Prerequisite for Gateway API with TLS"
Before using the Gateway API with TLS, you must define the `websecure` listener in your Traefik installation. This is typically done in your Helm values.
Example configuration in `values.yaml`:
```yaml
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
```
See the Traefik Kubernetes Setup Guide for complete installation details.
### Gateway API with TLS
Update your existing `HTTPRoute` to use the secured gateway listener:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # The HTTPS listener
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with TLS
Update your existing IngressRoute to use TLS:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # Changed from 'web' to 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # Added TLS configuration
```
Update the file `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify HTTPS Access
Now you can access your service securely. Since we're using a self-signed certificate, you'll need to skip certificate verification:
```bash
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
Your browser can also access https://whoami.docker.localhost/ (you'll need to accept the security warning for the self-signed certificate).
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Kubernetes, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt (IngressRoute) or cert-manager (Gateway API)
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing with IngressRoute
+97 -3
View File
@@ -17,6 +17,100 @@ Following these guides, you'll learn how to:
For detailed steps tailored to your environment, follow the guide for your platform:
- [Kubernetes](./kubernetes.md)
- [Docker](./docker.md)
- [Docker Swarm](./swarm.md)
- [Kubernetes](./kubernetes/basic.md)
- [Docker](./docker/basic.md)
- [Docker Swarm](./swarm/basic.md)
## Advanced Use Cases
### Exposing gRPC Services
Traefik Proxy supports gRPC applications without requiring specific configuration. You can expose gRPC services using either HTTP (h2c) or HTTPS.
??? example "Using HTTP (h2c)"
For unencrypted gRPC communication, configure your service to use the `h2c://` protocol scheme:
```yaml
http:
routers:
grpc-router:
service: grpc-service
rule: Host(`grpc.example.com`)
services:
grpc-service:
loadBalancer:
servers:
- url: h2c://backend:8080
```
!!! note
For providers with labels (Docker, Kubernetes), specify the scheme using:
`traefik.http.services.<service-name>.loadbalancer.server.scheme=h2c`
??? example "Using HTTPS"
For encrypted gRPC communication, use standard HTTPS URLs. Traefik will use HTTP/2 over TLS to communicate with your gRPC backend:
```yaml
http:
routers:
grpc-router:
service: grpc-service
rule: Host(`grpc.example.com`)
tls: {}
services:
grpc-service:
loadBalancer:
servers:
- url: https://backend:8080
```
Traefik handles the protocol negotiation automatically. Configure TLS certificates for your backends using [ServersTransport](../reference/routing-configuration/http/load-balancing/serverstransport.md) if needed.
### Exposing WebSocket Services
Traefik Proxy supports WebSocket (WS) and WebSocket Secure (WSS) connections out of the box. No special configuration is required beyond standard HTTP routing.
??? example "Basic WebSocket"
Configure a router and service pointing to your WebSocket server. Traefik automatically detects and handles the WebSocket upgrade:
```yaml
http:
routers:
websocket-router:
rule: Host(`ws.example.com`)
service: websocket-service
services:
websocket-service:
loadBalancer:
servers:
- url: http://websocket-backend:8000
```
??? example "WebSocket Secure (WSS)"
For encrypted WebSocket connections, enable TLS on your router. Clients connect using `wss://` while you can choose whether backends use encrypted or unencrypted connections:
```yaml
http:
routers:
websocket-secure-router:
rule: Host(`wss.example.com`)
service: websocket-service
tls: {}
services:
websocket-service:
loadBalancer:
servers:
- url: http://websocket-backend:8000 # SSL termination at Traefik
# OR
# - url: https://websocket-backend:8443 # End-to-end encryption
```
Traefik preserves WebSocket headers including `Origin`, `Sec-WebSocket-Key`, and `Sec-WebSocket-Version`. Use the [Headers middleware](../reference/routing-configuration/http/middlewares/headers.md) if you need to modify headers for origin checking or other requirements.
@@ -1,186 +1,23 @@
# Exposing Services with Traefik on Docker Swarm
# Exposing Services with Traefik on Docker Swarm - Advanced
This guide will help you expose your services securely through Traefik Proxy using Docker Swarm. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Docker Swarm before proceeding.
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for complex authentication scenarios
## Prerequisites
- Completed the [Basic Guide](basic.md)
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the Traefik Docker Swarm Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service deployment section in `docker-compose.yml`:
@@ -189,7 +26,7 @@ deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
@@ -198,10 +35,10 @@ deploy:
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply the middlewares
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
@@ -332,7 +169,7 @@ deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Sticky Sessions Configuration
- "traefik.http.services.whoami.loadbalancer.sticky.cookie=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=sticky_cookie"
@@ -374,28 +211,195 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "Provider Requirement"
Multi-layer routing requires the File provider, as Docker Swarm labels do not support the `parentRefs` field. However, you can use **both Docker Swarm and File providers together** - Swarm labels for service discovery and File configuration for multi-layer routing.
### Setup Multi-Layer Routing with Docker Swarm
To use multi-layer routing with Docker Swarm, you need to enable the File provider alongside the Docker provider.
Update your Traefik service in `docker-compose.yml`:
```yaml
services:
traefik:
image: traefik:v3.4
command:
- "--api.dashboard=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik_proxy"
- "--providers.file.directory=/etc/traefik/dynamic" # Enable File provider
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
configs:
- source: mlr-config
target: /etc/traefik/dynamic/mlr.yml
networks:
- traefik_proxy
deploy:
placement:
constraints:
- node.role == manager
configs:
mlr-config:
file: ./dynamic/mlr.yml
networks:
traefik_proxy:
external: true
```
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent router authenticates requests, and child routers direct traffic based on user roles.
First, keep your Docker Swarm services defined with labels as usual:
```yaml
# In docker-compose.yml
services:
# ... traefik service from above ...
# Admin backend service
admin-backend:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=Admin Backend
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.services.admin-backend.loadbalancer.server.port=80"
# User backend service
user-backend:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=User Backend
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.services.user-backend.loadbalancer.server.port=80"
```
Now create the multi-layer routing configuration in a file. Create `dynamic/mlr.yml`:
```yaml
http:
routers:
# Parent router with authentication middleware
api-parent:
rule: "Host(`api.swarm.localhost`) && PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
# Note: No service and no TLS config - this is a parent router
# Child router for admin users
api-admin:
rule: "HeadersRegexp(`X-Auth-User`, `admin`)"
service: admin-backend@swarm # Reference Swarm service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
# Child router for regular users
api-user:
rule: "HeadersRegexp(`X-Auth-User`, `user`)"
service: user-backend@swarm # Reference Swarm service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
middlewares:
auth-middleware:
basicAuth:
users:
- "admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0"
- "user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI."
headerField: X-Auth-User
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
!!! important "Cross-Provider References"
Notice the `@swarm` suffix on service names and the `@file` suffix in `parentRefs`. When using the File provider to orchestrate multi-layer routing with Swarm services:
- Use `service-name@swarm` to reference Swarm services
- Use `parent-name@file` in `parentRefs` to reference the parent router in the File provider
The `@provider` suffix tells Traefik which provider namespace to look in for the resource.
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.swarm.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.swarm.localhost/api`
2. **Parent router** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child router** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Swarm service
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Docker Swarm
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker Swarm. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Docker Swarm. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Docker Swarm, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker Swarm provider documentation](../../reference/install-configuration/providers/swarm.md) for more details about the Docker Swarm integration
+191
View File
@@ -0,0 +1,191 @@
# Exposing Services with Traefik on Docker Swarm - Basic
This guide will help you get started with exposing your services through Traefik Proxy using Docker Swarm. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
## Prerequisites
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the [Traefik Docker Swarm Setup guide](../../setup/swarm.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Docker Swarm, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing
-60
View File
@@ -1,60 +0,0 @@
---
title: Concepts
description: Traefik - base concepts and main features
---
# Concepts
This page explains the base concepts of Traefik.
---
## Introduction
Traefik is based on the concept of EntryPoints, Routers, Middlewares and Services.
The main features include dynamic configuration, automatic service discovery, and support for multiple backends and protocols.
1. [EntryPoints](../routing/entrypoints.md "Link to docs about EntryPoints"): EntryPoints are the network entry points into Traefik. They define the port which will receive the packets, and whether to listen for TCP or UDP.
2. [Routers](../routing/routers/index.md "Link to docs about routers"): A router is in charge of connecting incoming requests to the services that can handle them.
3. [Middlewares](../middlewares/overview.md "Link to docs about middlewares"): Attached to the routers, middlewares can modify the requests or responses before they are sent to your service
4. [Services](../routing/services/index.md "Link to docs about services"): Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests.
## Edge Router
Traefik is an *Edge Router*; this means that it's the door to your platform, and that it intercepts and routes every incoming request:
it knows all the logic and every [rule](../routing/routers/index.md#rule "Link to docs about routing rules") that determine which services handle which requests (based on the *path*, the *host*, *headers*, etc.).
![The Door to Your Infrastructure](../assets/img/traefik-concepts-1.png "Picture explaining the infrastructure")
## Auto Service Discovery
Where traditionally edge routers (or reverse proxies) need a configuration file that contains every possible route to your services, Traefik gets them from the services themselves.
Deploying your services, you attach information that tells Traefik the characteristics of the requests the services can handle.
![Decentralized Configuration](../assets/img/traefik-concepts-2.png "Picture about Decentralized Configuration")
This means that when a service is deployed, Traefik detects it immediately and updates the routing rules in real time.
Similarly, when a service is removed from the infrastructure, the corresponding route is deleted accordingly.
You no longer need to create and synchronize configuration files cluttered with IP addresses or other rules.
!!! info "Many different rules"
In the example above, we used the request [path rule](../routing/routers/index.md#rule "Link to docs about routing rules") to determine which service was in charge.
Certainly, you can use many other different [rules](../routing/routers/index.md#rule "Link to docs about routing rules").
!!! info "Updating the requests"
In the [middleware](../middlewares/overview.md "Link to middleware documentation") section, you can learn about how to update the requests before forwarding them to the services.
!!! question "How does Traefik discover the services?"
Traefik is able to use your cluster API to discover the services and read the attached information.
In Traefik, these connectors are called [providers](../providers/overview.md "Link to overview about Traefik providers") because they *provide* the configuration to Traefik.
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -13,7 +13,7 @@ Configuration in Traefik can refer to two different things:
- The install (startup) configuration (formerly known as the _static configuration_)
- The routing configuration (formerly known as the _dynamic configuration_)
Elements in the _install configuration_ set up connections to [providers](../providers/overview.md) and define the [entrypoints](../routing/entrypoints.md) Traefik will listen to (these elements don't change often).
Elements in the _install configuration_ set up connections to [providers](../reference/install-configuration/providers/overview.md) and define the [entrypoints](../reference/install-configuration/entrypoints.md) Traefik will listen to (these elements don't change often).
The _routing configuration_ contains everything that defines how the requests are handled by your system.
This configuration can change and is seamlessly hot-reloaded, without any request interruption or connection loss.
@@ -24,13 +24,13 @@ This configuration can change and is seamlessly hot-reloaded, without any reques
## The Routing Configuration
Traefik gets its _routing configuration_ from [providers](../providers/overview.md): whether an orchestrator, a service registry, or a plain old configuration file.
Traefik gets its _routing configuration_ from [providers](../reference/install-configuration/providers/overview.md): whether an orchestrator, a service registry, or a plain old configuration file.
Since this configuration is specific to your infrastructure choices, we invite you to refer to the [dedicated section of this documentation](../routing/overview.md).
Since this configuration is specific to your infrastructure choices, we invite you to refer to the [dedicated section of this documentation](../reference/routing-configuration/dynamic-configuration-methods.md).
!!! info ""
In the [Quick Start example](../getting-started/docker.md), the whoami application routing configuration comes from docker in the form of a label attached to the whoami container.
In the [Quick Start example](./docker.md), the whoami application routing configuration comes from docker in the form of a label attached to the whoami container.
!!! info "HTTPS Certificates also belong to the routing configuration."
@@ -90,6 +90,6 @@ All available environment variables can be found in the [install configuration e
All the configuration options are documented in their related section.
You can browse the available features in the menu, the [providers](../providers/overview.md), or the [routing section](../routing/overview.md) to see them in action.
You can browse the available features in the menu, the [providers](../reference/install-configuration/providers/overview.md), or the [routing section](../reference/routing-configuration/dynamic-configuration-methods.md) to see them in action.
{% include-markdown "includes/traefik-for-business-applications.md" %}
+7 -7
View File
@@ -12,10 +12,10 @@ and while the documentation often demonstrates configuration options through fil
the core feature of Traefik is its dynamic configurability,
directly reacting to changes from providers over time.
Notably, a part of the configuration is [static](./configuration-overview.md#the-static-configuration),
Notably, the [install configuration](./configuration-overview.md#the-install-configuration) is static,
and can be provided by a file on startup, whereas various providers,
such as the file provider,
contribute dynamically all along the traefik instance lifetime to its [dynamic configuration](./configuration-overview.md#the-dynamic-configuration) changes.
contribute dynamically all along the traefik instance lifetime to its [routing configuration](./configuration-overview.md#the-routing-configuration) changes.
In addition, the configuration englobes concepts such as the EntryPoint which can be seen as a listener on the Transport Layer (TCP),
as apposed to the Router which is more about the Presentation (TLS) and Application layers (HTTP).
@@ -132,8 +132,8 @@ http:
## Why Is My TLS Certificate Not Reloaded When Its Contents Change?
With the file provider,
a configuration update is only triggered when one of the [watched](../providers/file.md#provider-configuration) configuration files is modified.
With the [file provider](../reference/install-configuration/providers/others/file.md),
a configuration update is only triggered when one of the watched configuration files is modified.
Which is why, when a certificate is defined by path,
and the actual contents of this certificate change,
@@ -156,14 +156,14 @@ By default, the following headers are automatically added when proxying requests
| Proxy Server's Hostname | `X-Forwarded-Server` |
For more details,
please check out the [forwarded header](../routing/entrypoints.md#forwarded-headers) documentation.
please check out the [forwarded header](../reference/install-configuration/entrypoints.md#opt-forwardedHeaders-connection) documentation.
## How Traefik is Storing and Serving TLS Certificates?
### Storing TLS Certificates
[TLS](../https/tls.md "Link to Traefik TLS docs") certificates are either provided directly by the [dynamic configuration](./configuration-overview.md#the-dynamic-configuration "Link to dynamic configuration overview") from [providers](../https/tls.md#user-defined "Link to the TLS configuration"),
or by [ACME resolvers](../https/acme.md#providers "Link to ACME resolvers"), which act themselves as providers internally.
TLS certificates are either provided directly by the [routing configuration](../reference/routing-configuration/dynamic-configuration-methods.md "Link to routing configuration overview"),
or by [Certificate resolvers](../reference/install-configuration/tls/certificate-resolvers/overview.md "Link to certificates resolvers").
For each TLS certificate, Traefik produces an identifier used as a key to store it.
This identifier is constructed as the alphabetically ordered concatenation of the SANs `DNSNames` and `IPAddresses` of the TLScertificate.
@@ -1,147 +0,0 @@
---
title: "Traefik Installation Documentation"
description: "There are several flavors to choose from when installing Traefik Proxy. Get started with Traefik Proxy, and read the technical documentation."
---
# Install Traefik
You can install Traefik with the following flavors:
* [Use the official Docker image](./#use-the-official-docker-image)
* [Use the Helm Chart](./#use-the-helm-chart)
* [Use the binary distribution](./#use-the-binary-distribution)
* [Compile your binary from the sources](./#compile-your-binary-from-the-sources)
## Use the Official Docker Image
Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with one sample configuration file:
* [YAML](https://raw.githubusercontent.com/traefik/traefik/v3.6/traefik.sample.yml)
* [TOML](https://raw.githubusercontent.com/traefik/traefik/v3.6/traefik.sample.toml)
```shell
docker run -d -p 8080:8080 -p 80:80 \
-v $PWD/traefik.yml:/etc/traefik/traefik.yml traefik:v3.6
```
For more details, go to the [Docker provider documentation](../providers/docker.md)
!!! tip
* Prefer a fixed version than the latest that could be an unexpected version.
ex: `traefik:v3.6`
* Docker images are based from the [Alpine Linux Official image](https://hub.docker.com/_/alpine).
* Any orchestrator using docker images can fetch the official Traefik docker image.
## Use the Helm Chart
Traefik can be installed in Kubernetes using the Helm chart from <https://github.com/traefik/traefik-helm-chart>.
Ensure that the following requirements are met:
* Kubernetes 1.22+
* Helm version 3.9+ is [installed](https://helm.sh/docs/intro/install/)
Add Traefik Labs chart repository to Helm:
```bash
helm repo add traefik https://traefik.github.io/charts
```
You can update the chart repository by running:
```bash
helm repo update
```
And install it with the Helm command line:
```bash
helm install traefik traefik/traefik
```
!!! tip "Helm Features"
All [Helm features](https://helm.sh/docs/intro/using_helm/) are supported.
Examples are provided [here](https://github.com/traefik/traefik-helm-chart/blob/master/EXAMPLES.md).
For instance, installing the chart in a dedicated namespace:
```bash tab="Install in a Dedicated Namespace"
kubectl create ns traefik-v2
# Install in the namespace "traefik-v2"
helm install --namespace=traefik-v2 \
traefik traefik/traefik
```
??? example "Installing with Custom Values"
You can customize the installation by specifying custom values,
as with [any helm chart](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing).
{: #helm-custom-values }
All parameters are documented in the default [`values.yaml`](https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml).
You can also set Traefik command line flags using `additionalArguments`.
Example of installation with logging set to `DEBUG`:
```bash tab="Using Helm CLI"
helm install --namespace=traefik-v2 \
--set="additionalArguments={--log.level=DEBUG}" \
traefik traefik/traefik
```
```yml tab="With a custom values file"
# File custom-values.yml
## Install with "helm install --values=./custom-values.yml traefik traefik/traefik
additionalArguments:
- "--log.level=DEBUG"
```
## Use the Binary Distribution
Grab the latest binary from the [releases](https://github.com/traefik/traefik/releases) page.
??? info "Check the integrity of the downloaded file"
```bash tab="Linux"
# Compare this value to the one found in traefik-${traefik_version}_checksums.txt
sha256sum ./traefik_${traefik_version}_linux_${arch}.tar.gz
```
```bash tab="macOS"
# Compare this value to the one found in traefik-${traefik_version}_checksums.txt
shasum -a256 ./traefik_${traefik_version}_darwin_amd64.tar.gz
```
```powershell tab="Windows PowerShell"
# Compare this value to the one found in traefik-${traefik_version}_checksums.txt
Get-FileHash ./traefik_${traefik_version}_windows_${arch}.zip -Algorithm SHA256
```
??? info "Extract the downloaded archive"
```bash tab="Linux"
tar -zxvf traefik_${traefik_version}_linux_${arch}.tar.gz
```
```bash tab="macOS"
tar -zxvf ./traefik_${traefik_version}_darwin_amd64.tar.gz
```
```powershell tab="Windows PowerShell"
Expand-Archive traefik_${traefik_version}_windows_${arch}.zip
```
And run it:
```bash
./traefik --help
```
## Compile your Binary from the Sources
All the details are available in the [Contributing Guide](../contributing/building-testing.md)
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,6 +0,0 @@
---
title: "Traefik Getting Started With Kubernetes"
description: "Get started with Traefik Proxy and Kubernetes."
---
--8<-- "content/getting-started/kubernetes.md"
@@ -1,6 +0,0 @@
---
title: "Traefik Getting Started Quickly"
description: "Get started with Traefik Proxy and Docker."
---
--8<-- "content/getting-started/docker.md"
File diff suppressed because it is too large Load Diff
-71
View File
@@ -1,71 +0,0 @@
---
title: "Traefik OCSP Documentation"
description: "Learn how to configure Traefik to use OCSP. Read the technical documentation."
---
# OCSP
Check certificate status and perform OCSP stapling.
{: .subtitle }
## Overview
### OCSP Stapling
When OCSP is enabled, Traefik checks the status of every certificate in the store that provides an OCSP responder URL,
including the default certificate, and staples the OCSP response to the TLS handshake.
The OCSP check is performed when the certificate is loaded,
and once every hour until it is successful at the halfway point before the update date.
### Caching
Traefik caches the OCSP response as long as the associated certificate is provided by the configuration.
When a certificate is no longer provided,
the OCSP response has a 24 hour TTL waiting to be provided again or eventually removed.
The OCSP response is cached in memory and is not persisted between Traefik restarts.
## Configuration
### General
Enabling OCSP is part of the [static configuration](../getting-started/configuration-overview.md#the-static-configuration).
It can be defined by using a file (YAML or TOML) or CLI arguments:
```yaml tab="File (YAML)"
## Static configuration
ocsp: {}
```
```toml tab="File (TOML)"
## Static configuration
[ocsp]
```
```bash tab="CLI"
## Static configuration
--ocsp=true
```
### Responder Overrides
The `responderOverrides` option defines the OCSP responder URLs to use instead of the one provided by the certificate.
This is useful when you want to use a different OCSP responder.
```yaml tab="File (YAML)"
## Static configuration
ocsp:
responderOverrides:
foo: bar
```
```toml tab="File (TOML)"
## Static configuration
[ocsp]
[ocsp.responderOverrides]
foo = "bar"
```
```bash tab="CLI"
## Static configuration
-ocsp.responderoverrides.foo=bar
```
-23
View File
@@ -1,23 +0,0 @@
---
title: "Traefik Proxy HTTPS & TLS Overview |Traefik Docs"
description: "Traefik supports HTTPS & TLS, which concerns roughly two parts of the configuration: routers, and the TLS connection. Read the documentation to learn more."
---
# HTTPS & TLS
Overview
{: .subtitle }
Traefik supports HTTPS & TLS, which concerns roughly two parts of the configuration:
routers, and the TLS connection (and its underlying certificates).
When a router has to handle HTTPS traffic,
it should be specified with a `tls` field of the router definition.
See the TLS section of the [routers documentation](../routing/routers/index.md#tls).
The next sections of this documentation explain how to configure the TLS connection itself.
That is to say, how to obtain [TLS certificates](./tls.md#certificates-definition):
either through a definition in the dynamic configuration, or through [Let's Encrypt](./acme.md) (ACME).
And how to configure [TLS options](./tls.md#tls-options), and [certificates stores](./tls.md#certificates-stores).
{% include-markdown "includes/traefik-for-business-applications.md" %}
-56
View File
@@ -1,56 +0,0 @@
---
title: "Traefik SPIFFE Documentation"
description: "Learn how to configure Traefik to use SPIFFE. Read the technical documentation."
---
# SPIFFE
Secure the backend connection with SPIFFE.
{: .subtitle }
[SPIFFE](https://spiffe.io/docs/latest/spiffe-about/overview/) (Secure Production Identity Framework For Everyone),
provides a secure identity in the form of a specially crafted X.509 certificate,
to every workload in an environment.
Traefik is able to connect to the Workload API to obtain an x509-SVID used to secure the connection with SPIFFE enabled backends.
## Configuration
### General
Enabling SPIFFE is part of the [static configuration](../getting-started/configuration-overview.md#the-static-configuration).
It can be defined by using a file (YAML or TOML) or CLI arguments.
### Workload API
The `workloadAPIAddr` configuration defines the address of the SPIFFE [Workload API](https://spiffe.io/docs/latest/spiffe-about/spiffe-concepts/#spiffe-workload-api).
!!! info "Enabling SPIFFE in ServersTransports"
Enabling SPIFFE does not imply that backend connections are going to use it automatically.
Each [ServersTransport](../routing/services/index.md#serverstransport_1) or [TCPServersTransport](../routing/services/index.md#serverstransport_2),
that is meant to be secured with SPIFFE,
must explicitly enable it (see [SPIFFE with ServersTransport](../routing/services/index.md#spiffe) or [SPIFFE with TCPServersTransport](../routing/services/index.md#spiffe_1)).
!!! warning "SPIFFE can cause Traefik to stall"
When using SPIFFE,
Traefik will wait for the first SVID to be delivered before starting.
If Traefik is hanging when waiting on SPIFFE SVID delivery,
please double check that it is correctly registered as workload in your SPIFFE infrastructure.
```yaml tab="File (YAML)"
## Static configuration
spiffe:
workloadAPIAddr: localhost
```
```toml tab="File (TOML)"
## Static configuration
[spiffe]
workloadAPIAddr: localhost
```
```bash tab="CLI"
## Static configuration
--spiffe.workloadAPIAddr=localhost
```
-207
View File
@@ -1,207 +0,0 @@
---
title: "Traefik Tailscale Documentation"
description: "Learn how to configure Traefik Proxy to resolve TLS certificates for your Tailscale services. Read the technical documentation."
---
# Tailscale
Provision TLS certificates for your internal Tailscale services.
{: .subtitle }
To protect a service with TLS, a certificate from a public Certificate Authority is needed.
In addition to its vpn role, Tailscale can also [provide certificates](https://tailscale.com/kb/1153/enabling-https/) for the machines in your Tailscale network.
## Certificate resolvers
To obtain a TLS certificate from the Tailscale daemon,
a Tailscale certificate resolver needs to be configured as below.
!!! info "Referencing a certificate resolver"
Defining a certificate resolver does not imply that routers are going to use it automatically.
Each router or entrypoint that is meant to use the resolver must explicitly [reference](../routing/routers/index.md#certresolver) it.
```yaml tab="File (YAML)"
certificatesResolvers:
myresolver:
tailscale: {}
```
```toml tab="File (TOML)"
[certificatesResolvers.myresolver.tailscale]
```
```bash tab="CLI"
--certificatesresolvers.myresolver.tailscale=true
```
## Domain Definition
A certificate resolver requests certificates for a set of domain names inferred from routers, according to the following:
- If the router has a [`tls.domains`](../routing/routers/index.md#domains) option set,
then the certificate resolver derives this router domain name from the `main` option of `tls.domains`.
- Otherwise, the certificate resolver derives the domain name from any `Host()` or `HostSNI()` matchers
in the [router's rule](../routing/routers/index.md#rule).
!!! info "Tailscale Domain Format"
The domain is only taken into account if it is a Tailscale-specific one,
i.e. of the form `machine-name.domains-alias.ts.net`.
## Configuration Example
!!! example "Enabling Tailscale certificate resolution"
```yaml tab="File (YAML)"
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
myresolver:
tailscale: {}
```
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[certificatesResolvers.myresolver.tailscale]
```
```bash tab="CLI"
--entrypoints.web.address=:80
--entrypoints.websecure.address=:443
# ...
--certificatesresolvers.myresolver.tailscale=true
```
!!! example "Domain from Router's Rule Example"
```yaml tab="Docker & Swarm"
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
- traefik.http.routers.blog.tls.certresolver=myresolver
```
```yaml tab="Docker (Swarm)"
## Dynamic configuration
deploy:
labels:
- traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
- traefik.http.routers.blog.tls.certresolver=myresolver
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: blogtls
spec:
entryPoints:
- websecure
routes:
- match: Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
kind: Rule
services:
- name: blog
port: 8080
tls:
certResolver: myresolver
```
```yaml tab="File (YAML)"
## Dynamic configuration
http:
routers:
blog:
rule: "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)"
tls:
certResolver: myresolver
```
```toml tab="File (TOML)"
## Dynamic configuration
[http.routers]
[http.routers.blog]
rule = "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)"
[http.routers.blog.tls]
certResolver = "myresolver"
```
!!! example "Domain from Router's tls.domain Example"
```yaml tab="Docker & Swarm"
## Dynamic configuration
labels:
- traefik.http.routers.blog.rule=Path(`/metrics`)
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net
```
```yaml tab="Docker (Swarm)"
## Dynamic configuration
deploy:
labels:
- traefik.http.routers.blog.rule=Path(`/metrics`)
- traefik.http.routers.blog.tls.certresolver=myresolver
- traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: blogtls
spec:
entryPoints:
- websecure
routes:
- match: Path(`/metrics`)
kind: Rule
services:
- name: blog
port: 8080
tls:
certResolver: myresolver
domains:
- main: monitoring.yak-bebop.ts.net
```
```yaml tab="File (YAML)"
## Dynamic configuration
http:
routers:
blog:
rule: "Path(`/metrics`)"
tls:
certResolver: myresolver
domains:
- main: "monitoring.yak-bebop.ts.net"
```
```toml tab="File (TOML)"
## Dynamic configuration
[http.routers]
[http.routers.blog]
rule = "Path(`/metrics`)"
[http.routers.blog.tls]
certResolver = "myresolver"
[[http.routers.blog.tls.domains]]
main = "monitoring.yak-bebop.ts.net"
```
## Automatic Renewals
Traefik automatically tracks the expiry date of each Tailscale certificate it fetches,
and starts to renew a certificate 14 days before its expiry to match Tailscale daemon renew policy.
-590
View File
@@ -1,590 +0,0 @@
---
title: "Traefik TLS Documentation"
description: "Learn how to configure the transport layer security (TLS) connection in Traefik Proxy. Read the technical documentation."
---
# TLS
Transport Layer Security
{: .subtitle }
## Certificates Definition
### Automated
See the [Let's Encrypt](./acme.md) page.
### User defined
To add / remove TLS certificates, even when Traefik is already running, their definition can be added to the [dynamic configuration](../getting-started/configuration-overview.md), in the `[[tls.certificates]]` section:
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
certificates:
- certFile: /path/to/domain.cert
keyFile: /path/to/domain.key
- certFile: /path/to/other-domain.cert
keyFile: /path/to/other-domain.key
```
```toml tab="File (TOML)"
# Dynamic configuration
[[tls.certificates]]
certFile = "/path/to/domain.cert"
keyFile = "/path/to/domain.key"
[[tls.certificates]]
certFile = "/path/to/other-domain.cert"
keyFile = "/path/to/other-domain.key"
```
!!! important "Restriction"
In the above example, we've used the [file provider](../providers/file.md) to handle these definitions.
It is the only available method to configure the certificates (as well as the options and the stores).
However, in [Kubernetes](../providers/kubernetes-crd.md), the certificates can and must be provided by [secrets](https://kubernetes.io/docs/concepts/configuration/secret/).
## Certificates Stores
In Traefik, certificates are grouped together in certificates stores, which are defined as such:
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
stores:
default: {}
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.stores]
[tls.stores.default]
```
!!! important "Restriction"
Any store definition other than the default one (named `default`) will be ignored,
and there is therefore only one globally available TLS store.
In the `tls.certificates` section, a list of stores can then be specified to indicate where the certificates should be stored:
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
certificates:
- certFile: /path/to/domain.cert
keyFile: /path/to/domain.key
stores:
- default
# Note that since no store is defined,
# the certificate below will be stored in the `default` store.
- certFile: /path/to/other-domain.cert
keyFile: /path/to/other-domain.key
```
```toml tab="File (TOML)"
# Dynamic configuration
[[tls.certificates]]
certFile = "/path/to/domain.cert"
keyFile = "/path/to/domain.key"
stores = ["default"]
[[tls.certificates]]
# Note that since no store is defined,
# the certificate below will be stored in the `default` store.
certFile = "/path/to/other-domain.cert"
keyFile = "/path/to/other-domain.key"
```
!!! important "Restriction"
The `stores` list will actually be ignored and automatically set to `["default"]`.
### Default Certificate
Traefik can use a default certificate for connections without a SNI, or without a matching domain.
This default certificate should be defined in a TLS store:
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
stores:
default:
defaultCertificate:
certFile: path/to/cert.crt
keyFile: path/to/cert.key
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.stores]
[tls.stores.default]
[tls.stores.default.defaultCertificate]
certFile = "path/to/cert.crt"
keyFile = "path/to/cert.key"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: default
spec:
defaultCertificate:
secretName: default-certificate
---
apiVersion: v1
kind: Secret
metadata:
name: default-certificate
namespace: default
type: Opaque
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
```
If no `defaultCertificate` is provided, Traefik will use the generated one.
### ACME Default Certificate
You can configure Traefik to use an ACME provider (like Let's Encrypt) to generate the default certificate.
The configuration to resolve the default certificate should be defined in a TLS store:
!!! important "Precedence with the `defaultGeneratedCert` option"
The `defaultGeneratedCert` definition takes precedence over the ACME default certificate configuration.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
stores:
default:
defaultGeneratedCert:
resolver: myresolver
domain:
main: example.org
sans:
- foo.example.org
- bar.example.org
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.stores]
[tls.stores.default.defaultGeneratedCert]
resolver = "myresolver"
[tls.stores.default.defaultGeneratedCert.domain]
main = "example.org"
sans = ["foo.example.org", "bar.example.org"]
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: default
spec:
defaultGeneratedCert:
resolver: myresolver
domain:
main: example.org
sans:
- foo.example.org
- bar.example.org
```
```yaml tab="Docker & Swarm"
## Dynamic configuration
labels:
- "traefik.tls.stores.default.defaultgeneratedcert.resolver=myresolver"
- "traefik.tls.stores.default.defaultgeneratedcert.domain.main=example.org"
- "traefik.tls.stores.default.defaultgeneratedcert.domain.sans=foo.example.org, bar.example.org"
```
## TLS Options
The TLS options allow one to configure some parameters of the TLS connection.
!!! important "'default' TLS Option"
The `default` option is special.
When no tls options are specified in a tls router, the `default` option is used.
When specifying the `default` option explicitly, make sure not to specify provider namespace as the `default` option does not have one.
Conversely, for cross-provider references, for example, when referencing the file provider from a docker label,
you must specify the provider namespace, for example:
`traefik.http.routers.myrouter.tls.options=myoptions@file`
!!! important "TLSOption in Kubernetes"
When using the [TLSOption resource](../routing/providers/kubernetes-crd.md#kind-tlsoption) in Kubernetes, one might setup a default set of options that,
if not explicitly overwritten, should apply to all ingresses.
To achieve that, you'll have to create a TLSOption resource with the name `default`.
There may exist only one TLSOption with the name `default` (across all namespaces) - otherwise they will be dropped.
To explicitly use a different TLSOption (and using the Kubernetes Ingress resources)
you'll have to add an annotation to the Ingress in the following form:
`traefik.ingress.kubernetes.io/router.tls.options: <resource-namespace>-<resource-name>@kubernetescrd`
### Minimum TLS Version
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
minVersion: VersionTLS12
mintls13:
minVersion: VersionTLS13
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
minVersion = "VersionTLS12"
[tls.options.mintls13]
minVersion = "VersionTLS13"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
minVersion: VersionTLS12
---
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: mintls13
namespace: default
spec:
minVersion: VersionTLS13
```
### Maximum TLS Version
We discourage the use of this setting to disable TLS1.3.
The recommended approach is to update the clients to support TLS1.3.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
maxVersion: VersionTLS13
maxtls12:
maxVersion: VersionTLS12
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
maxVersion = "VersionTLS13"
[tls.options.maxtls12]
maxVersion = "VersionTLS12"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
maxVersion: VersionTLS13
---
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: maxtls12
namespace: default
spec:
maxVersion: VersionTLS12
```
### Cipher Suites
See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
cipherSuites = [
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
```
!!! important "TLS 1.3"
Cipher suites defined for TLS 1.2 and below cannot be used in TLS 1.3, and vice versa. (<https://tools.ietf.org/html/rfc8446>)
With TLS 1.3, the cipher suites are not configurable (all supported cipher suites are safe in this case).
<https://golang.org/doc/go1.12#tls_1_3>
### Curve Preferences
This option allows to set the enabled elliptic curves for key exchange.
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
See [CurvePreferences](https://godoc.org/crypto/tls#Config.CurvePreferences) and [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
curvePreferences:
- CurveP521
- CurveP384
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
curvePreferences = ["CurveP521", "CurveP384"]
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
curvePreferences:
- CurveP521
- CurveP384
```
### Strict SNI Checking
With strict SNI checking enabled, Traefik won't allow connections from clients that do not specify a server_name extension
or don't match any of the configured certificates.
The default certificate is irrelevant on that matter.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
sniStrict: true
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
sniStrict = true
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
sniStrict: true
```
### ALPN Protocols
_Optional, Default="h2, http/1.1, acme-tls/1"_
This option allows to specify the list of supported application level protocols for the TLS handshake,
in order of preference.
If the client supports ALPN, the selected protocol will be one from this list,
and the connection will fail if there is no mutually supported protocol.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
alpnProtocols:
- http/1.1
- h2
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
alpnProtocols = ["http/1.1", "h2"]
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
alpnProtocols:
- http/1.1
- h2
```
### Client Authentication (mTLS)
Traefik supports mutual authentication, through the `clientAuth` section.
For authentication policies that require verification of the client certificate, the certificate authority for the certificates should be set in `clientAuth.caFiles`.
In Kubernetes environment, CA certificate can be set in `clientAuth.secretNames`. See [TLSOption resource](../routing/providers/kubernetes-crd.md#kind-tlsoption) for more details.
The `clientAuth.clientAuthType` option governs the behaviour as follows:
- `NoClientCert`: disregards any client certificate.
- `RequestClientCert`: asks for a certificate but proceeds anyway if none is provided.
- `RequireAnyClientCert`: requires a certificate but does not verify if it is signed by a CA listed in `clientAuth.caFiles` or in `clientAuth.secretNames`.
- `VerifyClientCertIfGiven`: if a certificate is provided, verifies if it is signed by a CA listed in `clientAuth.caFiles` or in `clientAuth.secretNames`. Otherwise proceeds without any certificate.
- `RequireAndVerifyClientCert`: requires a certificate, which must be signed by a CA listed in `clientAuth.caFiles` or in `clientAuth.secretNames`.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
clientAuth:
# in PEM format. each file can contain multiple CAs.
caFiles:
- tests/clientca1.crt
- tests/clientca2.crt
clientAuthType: RequireAndVerifyClientCert
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
[tls.options.default.clientAuth]
# in PEM format. each file can contain multiple CAs.
caFiles = ["tests/clientca1.crt", "tests/clientca2.crt"]
clientAuthType = "RequireAndVerifyClientCert"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
clientAuth:
# the CA certificate is extracted from key `tls.ca` or `ca.crt` of the given secrets.
secretNames:
- secretCA
clientAuthType: RequireAndVerifyClientCert
```
### Disable Session Tickets
_Optional, Default="false"_
When set to true, Traefik disables the use of session tickets, forcing every client to perform a full TLS handshake instead of resuming sessions.
```yaml tab="File (YAML)"
# Dynamic configuration
tls:
options:
default:
disableSessionTickets: true
```
```toml tab="File (TOML)"
# Dynamic configuration
[tls.options]
[tls.options.default]
disableSessionTickets = true
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
disableSessionTickets: true
```
{% include-markdown "includes/traefik-for-business-applications.md" %}
+1 -1
View File
@@ -11,7 +11,7 @@ Traefik is an [open-source](https://github.com/traefik/traefik) Application Prox
If you start with Traefik for service discovery and routing, you can seamlessly add [API management](https://traefik.io/solutions/api-management/), [API gateway](https://traefik.io/solutions/api-gateway/), [AI gateway](https://traefik.io/solutions/ai-gateway/), and [API mocking](https://traefik.io/solutions/api-mocking/) capabilities as needed.
For a detailed comparison of all Traefik products and their capabilities, see our [Product Features Comparison](./features/).
For a detailed comparison of all Traefik products and their capabilities, see our [Product Features Comparison](./features/index.md).
With 3.3 billion downloads and over 55k stars on GitHub, Traefik is used globally across hybrid cloud, multi-cloud, on prem, and bare metal environments running Kubernetes, Docker Swarm, AWS, [the list goes on](https://doc.traefik.io/traefik/reference/install-configuration/providers/overview/).
@@ -1,58 +0,0 @@
---
title: "Traefik AddPrefix Documentation"
description: "Learn how to implement the HTTP AddPrefix middleware in Traefik Proxy to updates request paths before being forwarded. Read the technical documentation."
---
# Add Prefix
Prefixing the Path
{: .subtitle }
The AddPrefix middleware updates the path of a request before forwarding it.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Prefixing with /foo
labels:
- "traefik.http.middlewares.add-foo.addprefix.prefix=/foo"
```
```yaml tab="Kubernetes"
# Prefixing with /foo
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: add-foo
spec:
addPrefix:
prefix: /foo
```
```yaml tab="Consul Catalog"
# Prefixing with /foo
- "traefik.http.middlewares.add-foo.addprefix.prefix=/foo"
```
```yaml tab="File (YAML)"
# Prefixing with /foo
http:
middlewares:
add-foo:
addPrefix:
prefix: "/foo"
```
```toml tab="File (TOML)"
# Prefixing with /foo
[http.middlewares]
[http.middlewares.add-foo.addPrefix]
prefix = "/foo"
```
## Configuration Options
### `prefix`
`prefix` is the string to add before the current path in the requested URL.
It should include a leading slash (`/`).
-343
View File
@@ -1,343 +0,0 @@
---
title: "Traefik BasicAuth Documentation"
description: "The HTTP basic authentication (BasicAuth) middleware in Traefik Proxy restricts access to your Services to known users. Read the technical documentation."
---
# BasicAuth
Adding Basic Authentication
{: .subtitle }
The BasicAuth middleware grants access to services to authorized users only.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Declaring the user list
#
# Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping.
# To create user:password pair, it's possible to use this command:
# echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
#
# Also note that dollar signs should NOT be doubled when they are not being evaluated (e.g. Ansible docker_container module).
labels:
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
```
```yaml tab="Kubernetes"
# Declaring the user list
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
basicAuth:
secret: secretName
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
```
```yaml tab="File (YAML)"
# Declaring the user list
http:
middlewares:
test-auth:
basicAuth:
users:
- "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
```
```toml tab="File (TOML)"
# Declaring the user list
[http.middlewares]
[http.middlewares.test-auth.basicAuth]
users = [
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
```
## Configuration Options
### General
Passwords must be hashed using MD5, SHA1, or BCrypt.
!!! tip
Use `htpasswd` to generate the passwords.
### `users`
The `users` option is an array of authorized users. Each user must be declared using the `name:hashed-password` format.
!!! note ""
- If both `users` and `usersFile` are provided, the two are merged. The contents of `usersFile` have precedence over the values in `users`.
- For security reasons, the field `users` doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
!!! note "Kubernetes kubernetes.io/basic-auth secret type"
Kubernetes supports a special `kubernetes.io/basic-auth` secret type.
This secret must contain two keys: `username` and `password`.
Please note that these keys are not hashed or encrypted in any way, and therefore is less secure than other methods.
You can find more information on the [Kubernetes Basic Authentication Secret Documentation](https://kubernetes.io/docs/concepts/configuration/secret/#basic-authentication-secret)
```yaml tab="Docker & Swarm"
# Declaring the user list
#
# Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping.
# To create a user:password pair, the following command can be used:
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
#
# Also note that dollar signs should NOT be doubled when they not evaluated (e.g. Ansible docker_container module).
labels:
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
```
```yaml tab="Kubernetes"
# Declaring the user list
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
basicAuth:
secret: authsecret
---
# Note: in a kubernetes secret the string (e.g. generated by htpasswd) must be base64-encoded first.
# To create an encoded user:password pair, the following command can be used:
# htpasswd -nb user password | openssl base64
apiVersion: v1
kind: Secret
metadata:
name: authsecret
namespace: default
data:
users: |2
dGVzdDokYXByMSRINnVza2trVyRJZ1hMUDZld1RyU3VCa1RycUU4d2ovCnRlc3QyOiRhcHIxJGQ5
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
---
# This is an alternate auth secret that demonstrates the basic-auth secret type.
# Note: the password is not hashed, and is merely base64 encoded.
apiVersion: v1
kind: Secret
metadata:
name: authsecret2
namespace: default
type: kubernetes.io/basic-auth
data:
username: dXNlcg== # username: user
password: cGFzc3dvcmQ= # password: password
```
```yaml tab="Consul Catalog"
# Declaring the user list
- "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
```
```yaml tab="File (YAML)"
# Declaring the user list
http:
middlewares:
test-auth:
basicAuth:
users:
- "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
```
```toml tab="File (TOML)"
# Declaring the user list
[http.middlewares]
[http.middlewares.test-auth.basicAuth]
users = [
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
```
### `usersFile`
The `usersFile` option is the path to an external file that contains the authorized users for the middleware.
The file content is a list of `name:hashed-password`.
!!! note ""
- If both `users` and `usersFile` are provided, the two are merged. The contents of `usersFile` have precedence over the values in `users`.
- Because it does not make much sense to refer to a file path on Kubernetes, the `usersFile` field doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
basicAuth:
secret: authsecret
---
apiVersion: v1
kind: Secret
metadata:
name: authsecret
namespace: default
data:
users: |2
dGVzdDokYXByMSRINnVza2trVyRJZ1hMUDZld1RyU3VCa1RycUU4d2ovCnRlc3QyOiRhcHIxJGQ5
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
basicAuth:
usersFile: "/path/to/my/usersfile"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.basicAuth]
usersFile = "/path/to/my/usersfile"
```
??? example "A file containing test/test and test2/test2"
```txt
test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0
```
### `realm`
You can customize the realm for the authentication with the `realm` option. The default value is `traefik`.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
basicAuth:
realm: MyRealm
```
```json tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
basicAuth:
realm: "MyRealm"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.basicAuth]
realm = "MyRealm"
```
### `headerField`
You can define a header field to store the authenticated user using the `headerField`option.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.my-auth.basicauth.headerField=X-WebAuth-User"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: my-auth
spec:
basicAuth:
# ...
headerField: X-WebAuth-User
```
```json tab="Consul Catalog"
- "traefik.http.middlewares.my-auth.basicauth.headerField=X-WebAuth-User"
```
```yaml tab="File (YAML)"
http:
middlewares:
my-auth:
basicAuth:
# ...
headerField: "X-WebAuth-User"
```
```toml tab="File (TOML)"
[http.middlewares.my-auth.basicAuth]
# ...
headerField = "X-WebAuth-User"
```
### `removeHeader`
Set the `removeHeader` option to `true` to remove the authorization header before forwarding the request to your service. (Default value is `false`.)
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.basicauth.removeheader=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
basicAuth:
removeHeader: true
```
```json tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.basicauth.removeheader=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
basicAuth:
removeHeader: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.basicAuth]
removeHeader = true
```
{% include-markdown "includes/traefik-for-business-applications.md" %}
-268
View File
@@ -1,268 +0,0 @@
---
title: "Traefik Buffering Documentation"
description: "The HTTP buffering middleware in Traefik Proxy limits the size of requests that can be forwarded to Services. Read the technical documentation."
---
# Buffering
How to Read the Request before Forwarding It
{: .subtitle }
The Buffering middleware limits the size of requests that can be forwarded to services.
With Buffering, Traefik reads the entire request into memory (possibly buffering large requests into disk), and rejects requests that are over a specified size limit.
This can help services avoid large amounts of data (`multipart/form-data` for example), and can minimize the time spent sending data to a service.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Sets the maximum request body to 2MB
labels:
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
```
```yaml tab="Kubernetes"
# Sets the maximum request body to 2MB
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: limit
spec:
buffering:
maxRequestBodyBytes: 2000000
```
```yaml tab="Consul Catalog"
# Sets the maximum request body to 2MB
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
```
```yaml tab="File (YAML)"
# Sets the maximum request body to 2MB
http:
middlewares:
limit:
buffering:
maxRequestBodyBytes: 2000000
```
```toml tab="File (TOML)"
# Sets the maximum request body to 2MB
[http.middlewares]
[http.middlewares.limit.buffering]
maxRequestBodyBytes = 2000000
```
## Configuration Options
### `maxRequestBodyBytes`
_Optional, Default=0_
The `maxRequestBodyBytes` option configures the maximum allowed body size for the request (in bytes).
If the request exceeds the allowed size, it is not forwarded to the service, and the client gets a `413` (Request Entity Too Large) response.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: limit
spec:
buffering:
maxRequestBodyBytes: 2000000
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
```
```yaml tab="File (YAML)"
http:
middlewares:
limit:
buffering:
maxRequestBodyBytes: 2000000
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.limit.buffering]
maxRequestBodyBytes = 2000000
```
### `memRequestBodyBytes`
_Optional, Default=1048576_
You can configure a threshold (in bytes) from which the request will be buffered on disk instead of in memory with the `memRequestBodyBytes` option.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: limit
spec:
buffering:
memRequestBodyBytes: 2000000
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000"
```
```yaml tab="File (YAML)"
http:
middlewares:
limit:
buffering:
memRequestBodyBytes: 2000000
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.limit.buffering]
memRequestBodyBytes = 2000000
```
### `maxResponseBodyBytes`
_Optional, Default=0_
The `maxResponseBodyBytes` option configures the maximum allowed response size from the service (in bytes).
If the response exceeds the allowed size, it is not forwarded to the client. The client gets a `500` (Internal Server Error) response instead.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: limit
spec:
buffering:
maxResponseBodyBytes: 2000000
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000"
```
```yaml tab="File (YAML)"
http:
middlewares:
limit:
buffering:
maxResponseBodyBytes: 2000000
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.limit.buffering]
maxResponseBodyBytes = 2000000
```
### `memResponseBodyBytes`
_Optional, Default=1048576_
You can configure a threshold (in bytes) from which the response will be buffered on disk instead of in memory with the `memResponseBodyBytes` option.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: limit
spec:
buffering:
memResponseBodyBytes: 2000000
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000"
```
```yaml tab="File (YAML)"
http:
middlewares:
limit:
buffering:
memResponseBodyBytes: 2000000
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.limit.buffering]
memResponseBodyBytes = 2000000
```
### `retryExpression`
_Optional, Default=""_
You can have the Buffering middleware replay the request using `retryExpression`.
??? example "Retries once in the case of a network error"
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: limit
spec:
buffering:
retryExpression: "IsNetworkError() && Attempts() < 2"
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2"
```
```yaml tab="File (YAML)"
http:
middlewares:
limit:
buffering:
retryExpression: "IsNetworkError() && Attempts() < 2"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.limit.buffering]
retryExpression = "IsNetworkError() && Attempts() < 2"
```
The retry expression is defined as a logical combination of the functions below with the operators AND (`&&`) and OR (`||`). At least one function is required:
- `Attempts()` number of attempts (the first one counts)
- `ResponseCode()` response code of the service
- `IsNetworkError()` whether the response code is related to networking error
### Content-Length
See [Best Practices: ContentLength](../../security/content-length.md)
-164
View File
@@ -1,164 +0,0 @@
---
title: "Traefik Command Line Documentation"
description: "The HTTP chain middleware lets you define reusable combinations of other middleware, to reuse the same groups. Read the technical documentation."
---
# Chain
When One Isn't Enough
{: .subtitle }
The Chain middleware enables you to define reusable combinations of other pieces of middleware.
It makes reusing the same groups easier.
## Configuration Example
Below is an example of a Chain containing `AllowList`, `BasicAuth`, and `RedirectScheme`.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.routers.router1.service=service1"
- "traefik.http.routers.router1.middlewares=secured"
- "traefik.http.routers.router1.rule=Host(`mydomain`)"
- "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users"
- "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
- "traefik.http.middlewares.https-only.redirectscheme.scheme=https"
- "traefik.http.middlewares.known-ips.ipallowlist.sourceRange=192.168.1.7,127.0.0.1/32"
- "traefik.http.services.service1.loadbalancer.server.port=80"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`mydomain`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: secured
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secured
spec:
chain:
middlewares:
- name: https-only
- name: known-ips
- name: auth-users
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-users
spec:
basicAuth:
users:
- test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: https-only
spec:
redirectScheme:
scheme: https
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: known-ips
spec:
ipAllowList:
sourceRange:
- 192.168.1.7
- 127.0.0.1/32
```
```yaml tab="Consul Catalog"
- "traefik.http.routers.router1.service=service1"
- "traefik.http.routers.router1.middlewares=secured"
- "traefik.http.routers.router1.rule=Host(`mydomain`)"
- "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users"
- "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
- "traefik.http.middlewares.https-only.redirectscheme.scheme=https"
- "traefik.http.middlewares.known-ips.ipallowlist.sourceRange=192.168.1.7,127.0.0.1/32"
- "traefik.http.services.service1.loadbalancer.server.port=80"
```
```yaml tab="File (YAML)"
# ...
http:
routers:
router1:
service: service1
middlewares:
- secured
rule: "Host(`mydomain`)"
middlewares:
secured:
chain:
middlewares:
- https-only
- known-ips
- auth-users
auth-users:
basicAuth:
users:
- "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
https-only:
redirectScheme:
scheme: https
known-ips:
ipAllowList:
sourceRange:
- "192.168.1.7"
- "127.0.0.1/32"
services:
service1:
loadBalancer:
servers:
- url: "http://127.0.0.1:80"
```
```toml tab="File (TOML)"
# ...
[http.routers]
[http.routers.router1]
service = "service1"
middlewares = ["secured"]
rule = "Host(`mydomain`)"
[http.middlewares]
[http.middlewares.secured.chain]
middlewares = ["https-only", "known-ips", "auth-users"]
[http.middlewares.auth-users.basicAuth]
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"]
[http.middlewares.https-only.redirectScheme]
scheme = "https"
[http.middlewares.known-ips.ipAllowList]
sourceRange = ["192.168.1.7", "127.0.0.1/32"]
[http.services]
[http.services.service1]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "http://127.0.0.1:80"
```
@@ -1,186 +0,0 @@
---
title: "Traefik CircuitBreaker Documentation"
description: "The HTTP circuit breaker in Traefik Proxy prevents stacking requests to unhealthy Services, resulting in cascading failures. Read the technical documentation."
---
# CircuitBreaker
Don't Waste Time Calling Unhealthy Services
{: .subtitle }
The circuit breaker protects your system from stacking requests to unhealthy services, resulting in cascading failures.
When your system is healthy, the circuit is closed (normal operations).
When your system becomes unhealthy, the circuit opens, and the requests are no longer forwarded, but instead are handled by a fallback mechanism.
To assess if your system is healthy, the circuit breaker constantly monitors the services.
!!! note ""
The CircuitBreaker only analyzes what happens _after_ its position within the middleware chain. What happens _before_ has no impact on its state.
!!! important
Each router gets its own instance of a given circuit breaker.
One circuit breaker instance can be open while the other remains closed: their state is not shared.
This is the expected behavior, we want you to be able to define what makes a service healthy without having to declare a circuit breaker for each route.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Latency Check
labels:
- "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100"
```
```yaml tab="Kubernetes"
# Latency Check
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: latency-check
spec:
circuitBreaker:
expression: LatencyAtQuantileMS(50.0) > 100
```
```yaml tab="Consul Catalog"
# Latency Check
- "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100"
```
```yaml tab="File (YAML)"
# Latency Check
http:
middlewares:
latency-check:
circuitBreaker:
expression: "LatencyAtQuantileMS(50.0) > 100"
```
```toml tab="File (TOML)"
# Latency Check
[http.middlewares]
[http.middlewares.latency-check.circuitBreaker]
expression = "LatencyAtQuantileMS(50.0) > 100"
```
## Possible States
There are three possible states for your circuit breaker:
- Closed (your service operates normally)
- Open (the fallback mechanism takes over your service)
- Recovering (the circuit breaker tries to resume normal operations by progressively sending requests to your service)
### Closed
While the circuit is closed, the circuit breaker only collects metrics to analyze the behavior of the requests.
At specified intervals (`checkPeriod`), the circuit breaker evaluates `expression` to decide if its state must change.
### Open
While open, the fallback mechanism takes over the normal service calls for a duration of `FallbackDuration`.
The fallback mechanism returns a `HTTP 503` (or `ResponseCode`) to the client.
After this duration, it enters the recovering state.
### Recovering
While recovering, the circuit breaker sends linearly increasing amounts of requests to your service (for `RecoveryDuration`).
If your service fails during recovery, the circuit breaker opens again.
If the service operates normally during the entire recovery duration, then the circuit breaker closes.
## Configuration Options
### Configuring the Trigger
You can specify an `expression` that, once matched, opens the circuit breaker and applies the fallback mechanism instead of calling your services.
The `expression` option can check three different metrics:
- The network error ratio (`NetworkErrorRatio`)
- The status code ratio (`ResponseCodeRatio`)
- The latency at a quantile in milliseconds (`LatencyAtQuantileMS`)
#### `NetworkErrorRatio`
If you want the circuit breaker to open at a 30% ratio of network errors, the `expression` is `NetworkErrorRatio() > 0.30`
#### `ResponseCodeRatio`
You can configure the circuit breaker to open based on the ratio of a given range of status codes.
The `ResponseCodeRatio` accepts four parameters, `from`, `to`, `dividedByFrom`, `dividedByTo`.
The operation that will be computed is sum(`to` -> `from`) / sum (`dividedByFrom` -> `dividedByTo`).
!!! note ""
If sum (`dividedByFrom` -> `dividedByTo`) equals 0, then `ResponseCodeRatio` returns 0.
`from`is inclusive, `to` is exclusive.
For example, the expression `ResponseCodeRatio(500, 600, 0, 600) > 0.25` will trigger the circuit breaker if 25% of the requests returned a 5XX status (amongst the request that returned a status code from 0 to 5XX).
#### `LatencyAtQuantileMS`
You can configure the circuit breaker to open when a given proportion of your requests become too slow.
For example, the expression `LatencyAtQuantileMS(50.0) > 100` opens the circuit breaker when the median latency (quantile 50) reaches 100ms.
!!! note ""
You must provide a floating point number (with the trailing .0) for the quantile value
#### Using Multiple Metrics
You can combine multiple metrics using operators in your `expression`.
Supported operators are:
- AND (`&&`)
- OR (`||`)
For example, `ResponseCodeRatio(500, 600, 0, 600) > 0.30 || NetworkErrorRatio() > 0.10` triggers the circuit breaker when 30% of the requests return a 5XX status code, or when the ratio of network errors reaches 10%.
#### Operators
Here is the list of supported operators:
- Greater than (`>`)
- Greater or equal than (`>=`)
- Lesser than (`<`)
- Lesser or equal than (`<=`)
- Equal (`==`)
- Not Equal (`!=`)
### Fallback mechanism
By default the fallback mechanism returns a `HTTP 503 Service Unavailable` to the client instead of calling the target service.
The response code can be configured.
### `CheckPeriod`
_Optional, Default="100ms"_
The interval between successive checks of the circuit breaker condition (when in standby state).
### `FallbackDuration`
_Optional, Default="10s"_
The duration for which the circuit breaker will wait before trying to recover (from a tripped state).
### `RecoveryDuration`
_Optional, Default="10s"_
The duration for which the circuit breaker will try to recover (as soon as it is in recovering state).
### `ResponseCode`
_Optional, Default="503"_
The status code that the circuit breaker will return while it is in the open state.
-306
View File
@@ -1,306 +0,0 @@
---
title: "Traefik Compress Documentation"
description: "Traefik Proxy's HTTP middleware lets you compress responses before sending them to the client. Read the technical documentation."
---
# Compress
Compress Allows Compressing Responses before Sending them to the Client
{: .subtitle }
The Compress middleware supports Gzip, Brotli and Zstandard compression.
The activation of compression, and the compression method choice rely (among other things) on the request's `Accept-Encoding` header.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Enable compression
labels:
- "traefik.http.middlewares.test-compress.compress=true"
```
```yaml tab="Kubernetes"
# Enable compression
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-compress
spec:
compress: {}
```
```yaml tab="Consul Catalog"
# Enable compression
- "traefik.http.middlewares.test-compress.compress=true"
```
```yaml tab="File (YAML)"
# Enable compression
http:
middlewares:
test-compress:
compress: {}
```
```toml tab="File (TOML)"
# Enable compression
[http.middlewares]
[http.middlewares.test-compress.compress]
```
!!! info
Responses are compressed when the following criteria are all met:
* The `Accept-Encoding` request header contains `gzip`, and/or `*`, and/or `br`, and/or `zstd` with or without [quality values](https://developer.mozilla.org/en-US/docs/Glossary/Quality_values).
If the `Accept-Encoding` request header is absent and no [defaultEncoding](#defaultencoding) is configured, the response won't be encoded.
If it is present, but its value is the empty string, then compression is disabled.
* The response is not already compressed, i.e. the `Content-Encoding` response header is not already set.
* The response`Content-Type` header is not one among the [excludedContentTypes options](#excludedcontenttypes), or is one among the [includedContentTypes options](#includedcontenttypes).
* The response body is larger than the [configured minimum amount of bytes](#minresponsebodybytes) (default is `1024`).
## Configuration Options
### `excludedContentTypes`
_Optional, Default=""_
`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests and responses before compressing.
The responses with content types defined in `excludedContentTypes` are not compressed.
Content types are compared in a case-insensitive, whitespace-ignored manner.
!!! info
The `excludedContentTypes` and `includedContentTypes` options are mutually exclusive.
!!! info "In the case of gzip"
If the `Content-Type` header is not defined, or empty, the compress middleware will automatically [detect](https://mimesniff.spec.whatwg.org/) a content type.
It will also set the `Content-Type` header according to the detected MIME type.
!!! info "gRPC"
Note that `application/grpc` is never compressed.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-compress
spec:
compress:
excludedContentTypes:
- text/event-stream
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-compress:
compress:
excludedContentTypes:
- text/event-stream
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-compress.compress]
excludedContentTypes = ["text/event-stream"]
```
### `includedContentTypes`
_Optional, Default=""_
`includedContentTypes` specifies a list of content types to compare the `Content-Type` header of the responses before compressing.
The responses with content types defined in `includedContentTypes` are compressed.
Content types are compared in a case-insensitive, whitespace-ignored manner.
!!! info
The `excludedContentTypes` and `includedContentTypes` options are mutually exclusive.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-compress.compress.includedcontenttypes=application/json,text/html,text/plain"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-compress
spec:
compress:
includedContentTypes:
- application/json
- text/html
- text/plain
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-compress.compress.includedcontenttypes=application/json,text/html,text/plain"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-compress:
compress:
includedContentTypes:
- application/json
- text/html
- text/plain
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-compress.compress]
includedContentTypes = ["application/json","text/html","text/plain"]
```
### `minResponseBodyBytes`
_Optional, Default=1024_
`minResponseBodyBytes` specifies the minimum amount of bytes a response body must have to be compressed.
Responses smaller than the specified values will not be compressed.
!!! tip "Streaming"
When data is sent to the client on flush, the `minResponseBodyBytes` configuration is ignored and the data is compressed.
This is particularly the case when data is streamed to the client when using `Transfer-encoding: chunked` response.
When chunked data is sent to the client on flush, it will be compressed by default even if the received data has not reached
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-compress.compress.minresponsebodybytes=1200"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-compress
spec:
compress:
minResponseBodyBytes: 1200
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-compress.compress.minresponsebodybytes=1200"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-compress:
compress:
minResponseBodyBytes: 1200
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-compress.compress]
minResponseBodyBytes = 1200
```
### `defaultEncoding`
_Optional, Default=""_
`defaultEncoding` specifies the default encoding if the `Accept-Encoding` header is not in the request or contains a wildcard (`*`).
There is no fallback on the `defaultEncoding` when the header value is empty or unsupported.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-compress.compress.defaultEncoding=gzip"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-compress
spec:
compress:
defaultEncoding: gzip
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-compress.compress.defaultEncoding=gzip"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-compress:
compress:
defaultEncoding: gzip
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-compress.compress]
defaultEncoding = "gzip"
```
### `encodings`
_Optional, Default="gzip, br, zstd"_
`encodings` specifies the list of supported compression encodings.
At least one encoding value must be specified, and valid entries are `gzip` (Gzip), `br` (Brotli), and `zstd` (Zstandard).
The order of the list also sets the priority, the top entry has the highest priority.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-compress.compress.encodings=zstd,br"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-compress
spec:
compress:
encodings:
- zstd
- br
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-compress.compress.encodings=zstd,br"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-compress:
compress:
encodings:
- zstd
- br
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-compress.compress]
encodings = ["zstd","br"]
```
@@ -1,67 +0,0 @@
---
title: "Traefik ContentType Documentation"
description: "Traefik Proxy's HTTP middleware automatically sets the `Content-Type` header value when it is not set by the backend. Read the technical documentation."
---
# ContentType
Handling Content-Type auto-detection
{: .subtitle }
The Content-Type middleware sets the `Content-Type` header value to the media type detected from the response content,
when it is not set by the backend.
!!! info
The scope of the Content-Type middleware is the MIME type detection done by the core of Traefik (the server part).
Therefore, it has no effect against any other `Content-Type` header modifications (e.g.: in another middleware such as compress).
## Configuration Examples
```yaml tab="Docker & Swarm"
# Enable auto-detection
labels:
- "traefik.http.middlewares.autodetect.contenttype=true"
```
```yaml tab="Kubernetes"
# Enable auto-detection
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: autodetect
spec:
contentType: {}
```
```yaml tab="Consul Catalog"
# Enable auto-detection
- "traefik.http.middlewares.autodetect.contenttype=true"
```
```yaml tab="File (YAML)"
# Enable auto-detection
http:
middlewares:
autodetect:
contentType: {}
```
```toml tab="File (TOML)"
# Enable auto-detection
[http.middlewares]
[http.middlewares.autodetect.contentType]
```
## Configuration Options
### `autoDetect`
!!! warning
`autoDetect` option is deprecated and should not be used.
Moreover, it is redundant with an empty ContentType middleware declaration.
`autoDetect` specifies whether to let the `Content-Type` header,
if it has not been set by the backend,
be automatically set to a value derived from the contents of the response.
-296
View File
@@ -1,296 +0,0 @@
---
title: "Traefik DigestAuth Documentation"
description: "Traefik Proxy's HTTP DigestAuth middleware restricts access to your services to known users. Read the technical documentation."
---
# DigestAuth
Adding Digest Authentication
{: .subtitle }
The DigestAuth middleware grants access to services to authorized users only.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Declaring the user list
labels:
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
```yaml tab="Kubernetes"
# Declaring the user list
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
digestAuth:
secret: userssecret
```
```yaml tab="Consul Catalog"
# Declaring the user list
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
```yaml tab="File (YAML)"
# Declaring the user list
http:
middlewares:
test-auth:
digestAuth:
users:
- "test:traefik:a2688e031edb4be6a3797f3882655c05"
- "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
```toml tab="File (TOML)"
# Declaring the user list
[http.middlewares]
[http.middlewares.test-auth.digestAuth]
users = [
"test:traefik:a2688e031edb4be6a3797f3882655c05",
"test2:traefik:518845800f9e2bfb1f1f740ec24f074e",
]
```
## Configuration Options
!!! tip
Use `htdigest` to generate passwords.
### `users`
The `users` option is an array of authorized users. Each user will be declared using the `name:realm:encoded-password` format.
!!! note ""
- If both `users` and `usersFile` are provided, the two are merged. The contents of `usersFile` have precedence over the values in `users`.
- For security reasons, the field `users` doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
digestAuth:
secret: authsecret
---
apiVersion: v1
kind: Secret
metadata:
name: authsecret
namespace: default
data:
users: |2
dGVzdDp0cmFlZmlrOmEyNjg4ZTAzMWVkYjRiZTZhMzc5N2YzODgyNjU1YzA1CnRlc3QyOnRyYWVmaWs6NTE4ODQ1ODAwZjllMmJmYjFmMWY3NDBlYzI0ZjA3NGUKCg==
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
digestAuth:
users:
- "test:traefik:a2688e031edb4be6a3797f3882655c05"
- "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.digestAuth]
users = [
"test:traefik:a2688e031edb4be6a3797f3882655c05",
"test2:traefik:518845800f9e2bfb1f1f740ec24f074e",
]
```
### `usersFile`
The `usersFile` option is the path to an external file that contains the authorized users for the middleware.
The file content is a list of `name:realm:encoded-password`.
!!! note ""
- If both `users` and `usersFile` are provided, the two are merged. The contents of `usersFile` have precedence over the values in `users`.
- Because it does not make much sense to refer to a file path on Kubernetes, the `usersFile` field doesn't exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
digestAuth:
secret: authsecret
---
apiVersion: v1
kind: Secret
metadata:
name: authsecret
namespace: default
data:
users: |2
dGVzdDokYXByMSRINnVza2trVyRJZ1hMUDZld1RyU3VCa1RycUU4d2ovCnRlc3QyOiRhcHIxJGQ5
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
digestAuth:
usersFile: "/path/to/my/usersfile"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.digestAuth]
usersFile = "/path/to/my/usersfile"
```
??? example "A file containing test/test and test2/test2"
```txt
test:traefik:a2688e031edb4be6a3797f3882655c05
test2:traefik:518845800f9e2bfb1f1f740ec24f074e
```
### `realm`
You can customize the realm for the authentication with the `realm` option. The default value is `traefik`.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
digestAuth:
realm: MyRealm
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
digestAuth:
realm: "MyRealm"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.digestAuth]
realm = "MyRealm"
```
### `headerField`
You can customize the header field for the authenticated user using the `headerField`option.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: my-auth
spec:
digestAuth:
# ...
headerField: X-WebAuth-User
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
```
```yaml tab="File (YAML)"
http:
middlewares:
my-auth:
digestAuth:
# ...
headerField: "X-WebAuth-User"
```
```toml tab="File (TOML)"
[http.middlewares.my-auth.digestAuth]
# ...
headerField = "X-WebAuth-User"
```
### `removeHeader`
Set the `removeHeader` option to `true` to remove the authorization header before forwarding the request to your service. (Default value is `false`.)
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.digestauth.removeheader=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
digestAuth:
removeHeader: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.digestauth.removeheader=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
digestAuth:
removeHeader: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.digestAuth]
removeHeader = true
```
-141
View File
@@ -1,141 +0,0 @@
---
title: "Traefik Errors Documentation"
description: "In Traefik Proxy, the Errors middleware returns custom pages according to configured ranges of HTTP Status codes. Read the technical documentation."
---
# Errors
It Has Never Been Easier to Say That Something Went Wrong
{: .subtitle }
The Errors middleware returns a custom page in lieu of the default, according to configured ranges of HTTP Status codes.
!!! important
The error page itself is _not_ hosted by Traefik.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Dynamic Custom Error Page for 5XX Status Code
labels:
- "traefik.http.middlewares.test-errors.errors.status=500,501,503,505-599"
- "traefik.http.middlewares.test-errors.errors.service=serviceError"
- "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-errors
spec:
errors:
status:
- "500"
- "501"
- "503"
- "505-599"
query: /{status}.html
service:
name: whoami
port: 80
```
```yaml tab="Consul Catalog"
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
- "traefik.http.middlewares.test-errors.errors.status=500,501,503,505-599"
- "traefik.http.middlewares.test-errors.errors.service=serviceError"
- "traefik.http.middlewares.test-errors.errors.query=/{status}.html"
```
```yaml tab="File (YAML)"
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
http:
middlewares:
test-errors:
errors:
status:
- "500"
- "501"
- "503"
- "505-599"
service: serviceError
query: "/{status}.html"
services:
# ... definition of error-handler-service and my-service
```
```toml tab="File (TOML)"
# Dynamic Custom Error Page for 5XX Status Code excluding 502 and 504
[http.middlewares]
[http.middlewares.test-errors.errors]
status = ["500","501","503","505-599"]
service = "serviceError"
query = "/{status}.html"
[http.services]
# ... definition of error-handler-service and my-service
```
!!! note ""
In this example, the error page URL is based on the status code (`query=/{status}.html`).
## Configuration Options
### `status`
The `status` option defines which status or range of statuses should result in an error page.
The status code ranges are inclusive (`505-599` will trigger with every code between `505` and `599`, `505` and `599` included).
!!! note ""
You can define either a status code as a number (`500`),
as multiple comma-separated numbers (`500,502`),
as ranges by separating two codes with a dash (`505-599`),
or a combination of the two (`404,418,505-599`).
The comma-separated syntax is only available for label-based providers.
The examples above demonstrate which syntax is appropriate for each provider.
### `statusRewrites`
An optional mapping of status codes to be rewritten. For example, if a service returns a 418, you might want to rewrite it to a 404.
You can map individual status codes or even ranges to a different status code. The syntax for ranges follows the same rules as the `status` option.
Here is an example:
```yml
statusRewrites:
"500-503": 500
"418": 404
```
### `service`
The service that will serve the new requested error page.
!!! note ""
In Kubernetes, you need to reference a Kubernetes Service instead of a Traefik service.
!!! info "Host Header"
By default, the client `Host` header value is forwarded to the configured error [service](#service).
To forward the `Host` value corresponding to the configured error service URL, the [passHostHeader](../../../routing/services/#pass-host-header) option must be set to `false`.
### `query`
The URL for the error page (hosted by [`service`](#service))).
There are multiple variables that can be placed in the `query` option to insert values in the URL.
The table below lists all the available variables and their associated values.
| Variable | Value |
|--------------------|--------------------------------------------------------------------------------------------|
| `{status}` | The response status code. It may be rewritten when using the `statusRewrites` option. |
| `{originalStatus}` | The original response status code, if it has been modified by the `statusRewrites` option. |
| `{url}` | The [escaped](https://pkg.go.dev/net/url#QueryEscape) request URL. |
@@ -1,788 +0,0 @@
---
title: "Traefik ForwardAuth Documentation"
description: "In Traefik Proxy, the HTTP ForwardAuth middleware delegates authentication to an external Service. Read the technical documentation."
---
# ForwardAuth
Using an External Service to Forward Authentication
{: .subtitle }
The ForwardAuth middleware delegates authentication to an external service.
If the service answers with a 2XX code, access is granted, and the original request is performed.
Otherwise, the response from the authentication server is returned.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Forward authentication to example.com
labels:
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
```
```yaml tab="Kubernetes"
# Forward authentication to example.com
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
```
```yaml tab="Consul Catalog"
# Forward authentication to example.com
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
```
```yaml tab="File (YAML)"
# Forward authentication to example.com
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
```
```toml tab="File (TOML)"
# Forward authentication to example.com
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
```
## Forward-Request Headers
The following request properties are provided to the forward-auth target endpoint as `X-Forwarded-` headers.
| Property | Forward-Request Header |
|-------------------|------------------------|
| HTTP Method | `X-Forwarded-Method` |
| Protocol | `X-Forwarded-Proto` |
| Host | `X-Forwarded-Host` |
| Request URI | `X-Forwarded-Uri` |
| Source IP-Address | `X-Forwarded-For` |
## Configuration Options
### `address`
The `address` option defines the authentication server address.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
```
### `trustForwardHeader`
Set the `trustForwardHeader` option to `true` to trust all `X-Forwarded-*` headers.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
trustForwardHeader: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
trustForwardHeader: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
trustForwardHeader = true
```
### `authResponseHeaders`
The `authResponseHeaders` option is the list of headers to copy from the authentication server response and set on
forwarded request, replacing any existing conflicting headers.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
authResponseHeaders:
- X-Auth-User
- X-Secret
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
authResponseHeaders:
- "X-Auth-User"
- "X-Secret"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
authResponseHeaders = ["X-Auth-User", "X-Secret"]
```
### `authResponseHeadersRegex`
The `authResponseHeadersRegex` option is the regex to match headers to copy from the authentication server response and
set on forwarded request, after stripping all headers that match the regex.
It allows partial matching of the regular expression against the header key.
The start of string (`^`) and end of string (`$`) anchors should be used to ensure a full match against the header key.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
authResponseHeadersRegex: ^X-
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
authResponseHeadersRegex: "^X-"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
authResponseHeadersRegex = "^X-"
```
!!! tip
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
When defining a regular expression within YAML, any escaped character needs to be escaped twice: `example\.com` needs to be written as `example\\.com`.
### `authRequestHeaders`
The `authRequestHeaders` option is the list of the headers to copy from the request to the authentication server.
It allows filtering headers that should not be passed to the authentication server.
If not set or empty then all request headers are passed.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
authRequestHeaders:
- "Accept"
- "X-CustomHeader"
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
authRequestHeaders:
- "Accept"
- "X-CustomHeader"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
authRequestHeaders = "Accept,X-CustomHeader"
```
### `addAuthCookiesToResponse`
The `addAuthCookiesToResponse` option is the list of cookies to copy from the authentication server to the response,
replacing any existing conflicting cookie from the forwarded response.
!!! info
Please note that all backend cookies matching the configured list will not be added to the response.
```yaml tab="Docker"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.addAuthCookiesToResponse=Session-Cookie,State-Cookie"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
addAuthCookiesToResponse:
- Session-Cookie
- State-Cookie
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.addAuthCookiesToResponse=Session-Cookie,State-Cookie"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
addAuthCookiesToResponse:
- "Session-Cookie"
- "State-Cookie"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
addAuthCookiesToResponse = ["Session-Cookie", "State-Cookie"]
```
### `forwardBody`
_Optional, Default=false_
Set the `forwardBody` option to `true` to send Body.
!!! info
As body is read inside Traefik before forwarding, this breaks streaming.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.forwardBody=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
forwardBody: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.forwardBody=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
forwardBody: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
forwardBody = true
```
### `maxBodySize`
_Optional, Default=-1_
Set the `maxBodySize` to limit the body size in bytes.
If body is bigger than this, it returns a 401 (unauthorized).
Default is `-1`, which means no limit.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.maxBodySize=1000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
forwardBody: true
maxBodySize: 1000
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.maxBodySize=1000"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
maxBodySize: 1000
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
forwardBody = true
maxBodySize = 1000
```
### `tls`
_Optional_
Defines the TLS configuration used for the secure connection to the authentication server.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secured connection to the authentication server,
it defaults to the system bundle.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
tls:
caSecret: mycasercret
---
apiVersion: v1
kind: Secret
metadata:
name: mycasercret
namespace: default
data:
# Must contain a certificate under either a `tls.ca` or a `ca.crt` key.
tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
tls:
ca: "path/to/local.crt"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
[http.middlewares.test-auth.forwardAuth.tls]
ca = "path/to/local.crt"
```
#### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the authentication server.
When using this option, setting the `key` option is required.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
tls:
certSecret: mytlscert
---
apiVersion: v1
kind: Secret
metadata:
name: mytlscert
namespace: default
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
tls:
cert: "path/to/foo.cert"
key: "path/to/foo.key"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
[http.middlewares.test-auth.forwardAuth.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
!!! info
For security reasons, the field does not exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
#### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the authentication server.
When using this option, setting the `cert` option is required.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
tls:
certSecret: mytlscert
---
apiVersion: v1
kind: Secret
metadata:
name: mytlscert
namespace: default
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
tls:
cert: "path/to/foo.cert"
key: "path/to/foo.key"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
[http.middlewares.test-auth.forwardAuth.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
!!! info
For security reasons, the field does not exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to the authentication server accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
address: https://example.com/auth
tls:
insecureSkipVerify: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-auth.forwardAuth]
address = "https://example.com/auth"
[http.middlewares.test-auth.forwardAuth.tls]
insecureSkipVerify: true
```
### `headerField`
_Optional_
You can define a header field to store the authenticated user using the `headerField`option.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.headerField=X-WebAuth-User"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
# ...
headerField: X-WebAuth-User
```
```json tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.headerField=X-WebAuth-User"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
# ...
headerField: "X-WebAuth-User"
```
```toml tab="File (TOML)"
[http.middlewares.test-auth.forwardAuth]
# ...
headerField = "X-WebAuth-User"
```
### `preserveLocationHeader`
_Optional, Default=false_
`preserveLocationHeader` defines whether to forward the `Location` header to the client as is or prefix it with the domain name of the authentication server.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.preserveLocationHeader=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
# ...
preserveLocationHeader: true
```
```json tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.preserveLocationHeader=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
# ...
preserveLocationHeader: true
```
```toml tab="File (TOML)"
[http.middlewares.test-auth.forwardAuth]
# ...
preserveLocationHeader = true
```
### `preserveRequestMethod`
_Optional, Default=false_
`preserveRequestMethod` defines whether to preserve the original request method while forwarding the request to the authentication server. By default, when this option is set to `false`, incoming requests are always forwarded as `GET` requests to the authentication server.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-auth.forwardauth.preserveRequestMethod=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-auth
spec:
forwardAuth:
# ...
preserveRequestMethod: true
```
```json tab="Consul Catalog"
- "traefik.http.middlewares.test-auth.forwardauth.preserveRequestMethod=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-auth:
forwardAuth:
# ...
preserveRequestMethod: true
```
```toml tab="File (TOML)"
[http.middlewares.test-auth.forwardAuth]
# ...
preserveRequestMethod = true
```
{% include-markdown "includes/traefik-for-business-applications.md" %}
-66
View File
@@ -1,66 +0,0 @@
---
title: "Traefik GrpcWeb Documentation"
description: "In Traefik Proxy's HTTP middleware, GrpcWeb converts a gRPC Web requests to HTTP/2 gRPC requests. Read the technical documentation."
---
# GrpcWeb
Converting gRPC Web requests to HTTP/2 gRPC requests.
{: .subtitle }
The GrpcWeb middleware converts gRPC Web requests to HTTP/2 gRPC requests before forwarding them to the backends.
!!! tip
Please note, that Traefik needs to communicate using gRPC with the backends (h2c or HTTP/2 over TLS).
Check out the [gRPC](../../user-guides/grpc.md) user guide for more details.
## Configuration Examples
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-grpcweb.grpcweb.allowOrigins=*"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-grpcweb
spec:
grpcWeb:
allowOrigins:
- "*"
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-grpcweb.grpcWeb.allowOrigins=*"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-grpcweb:
grpcWeb:
allowOrigins:
- "*"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-grpcweb.grpcWeb]
allowOrigins = ["*"]
```
## Configuration Options
### `allowOrigins`
The `allowOrigins` contains the list of allowed origins.
A wildcard origin `*` can also be configured to match all requests.
More information including how to use the settings can be found at:
- [Mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)
- [w3](https://fetch.spec.whatwg.org/#http-access-control-allow-origin)
- [IETF](https://tools.ietf.org/html/rfc6454#section-7.1)
-425
View File
@@ -1,425 +0,0 @@
---
title: "Traefik Headers Documentation"
description: "In Traefik Proxy, the HTTP headers middleware manages the headers of requests and responses. Read the technical documentation."
---
# Headers
Managing Request/Response headers
{: .subtitle }
The Headers middleware manages the headers of requests and responses.
A set of forwarded headers are automatically added by default. See the [FAQ](../../getting-started/faq.md#what-are-the-forwarded-headers-when-proxying-http-requests) for more information.
## Configuration Examples
### Adding Headers to the Request and the Response
The following example adds the `X-Script-Name` header to the proxied request and the `X-Custom-Response-Header` header to the response
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.testHeader.headers.customrequestheaders.X-Script-Name=test"
- "traefik.http.middlewares.testHeader.headers.customresponseheaders.X-Custom-Response-Header=value"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-header
spec:
headers:
customRequestHeaders:
X-Script-Name: "test"
customResponseHeaders:
X-Custom-Response-Header: "value"
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
- "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value"
```
```yaml tab="File (YAML)"
http:
middlewares:
testHeader:
headers:
customRequestHeaders:
X-Script-Name: "test"
customResponseHeaders:
X-Custom-Response-Header: "value"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.testHeader.headers]
[http.middlewares.testHeader.headers.customRequestHeaders]
X-Script-Name = "test"
[http.middlewares.testHeader.headers.customResponseHeaders]
X-Custom-Response-Header = "value"
```
### Adding and Removing Headers
In the following example, requests are proxied with an extra `X-Script-Name` header while their `X-Custom-Request-Header` header gets stripped,
and responses are stripped of their `X-Custom-Response-Header` header.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Custom-Request-Header="
- "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header="
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-header
spec:
headers:
customRequestHeaders:
X-Script-Name: "test" # Adds
X-Custom-Request-Header: "" # Removes
customResponseHeaders:
X-Custom-Response-Header: "" # Removes
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Custom-Request-Header="
- "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header="
```
```yaml tab="File (YAML)"
http:
middlewares:
testHeader:
headers:
customRequestHeaders:
X-Script-Name: "test" # Adds
X-Custom-Request-Header: "" # Removes
customResponseHeaders:
X-Custom-Response-Header: "" # Removes
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.testHeader.headers]
[http.middlewares.testHeader.headers.customRequestHeaders]
X-Script-Name = "test" # Adds
X-Custom-Request-Header = "" # Removes
[http.middlewares.testHeader.headers.customResponseHeaders]
X-Custom-Response-Header = "" # Removes
```
### Using Security Headers
Security-related headers (HSTS headers, Browser XSS filter, etc) can be managed similarly to custom headers as shown above.
This functionality makes it possible to easily use security features by adding headers.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.testHeader.headers.framedeny=true"
- "traefik.http.middlewares.testHeader.headers.browserxssfilter=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-header
spec:
headers:
frameDeny: true
browserXssFilter: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.testheader.headers.framedeny=true"
- "traefik.http.middlewares.testheader.headers.browserxssfilter=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
testHeader:
headers:
frameDeny: true
browserXssFilter: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.testHeader.headers]
frameDeny = true
browserXssFilter = true
```
### CORS Headers
CORS (Cross-Origin Resource Sharing) headers can be added and configured in a manner similar to the custom headers above.
This functionality allows for more advanced security features to quickly be set.
If CORS headers are set, then the middleware does not pass preflight requests to any service,
instead the response will be generated and sent back to the client directly.
Please note that the example below is by no means authoritative or exhaustive,
and should not be used as is for production.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
- "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=*"
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org"
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-header
spec:
headers:
accessControlAllowMethods:
- "GET"
- "OPTIONS"
- "PUT"
accessControlAllowHeaders:
- "*"
accessControlAllowOriginList:
- "https://foo.bar.org"
- "https://example.org"
accessControlMaxAge: 100
addVaryHeader: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
- "traefik.http.middlewares.testheader.headers.accesscontrolallowheaders=*"
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org"
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
testHeader:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlAllowHeaders: "*"
accessControlAllowOriginList:
- https://foo.bar.org
- https://example.org
accessControlMaxAge: 100
addVaryHeader: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.testHeader.headers]
accessControlAllowMethods = ["GET", "OPTIONS", "PUT"]
accessControlAllowHeaders = [ "*" ]
accessControlAllowOriginList = ["https://foo.bar.org","https://example.org"]
accessControlMaxAge = 100
addVaryHeader = true
```
## Configuration Options
### General
!!! warning
Custom headers will overwrite existing headers if they have identical names.
!!! note ""
The detailed documentation for security headers can be found in [unrolled/secure](https://github.com/unrolled/secure#available-options).
### `customRequestHeaders`
The `customRequestHeaders` option lists the header names and values to apply to the request.
### `customResponseHeaders`
The `customResponseHeaders` option lists the header names and values to apply to the response.
### `accessControlAllowCredentials`
The `accessControlAllowCredentials` indicates whether the request can include user credentials.
### `accessControlAllowHeaders`
The `accessControlAllowHeaders` indicates which header field names can be used as part of the request.
### `accessControlAllowMethods`
The `accessControlAllowMethods` indicates which methods can be used during requests.
### `accessControlAllowOriginList`
The `accessControlAllowOriginList` indicates whether a resource can be shared by returning different values.
A wildcard origin `*` can also be configured, and matches all requests.
If this value is set by a backend service, it will be overwritten by Traefik.
This value can contain a list of allowed origins.
More information including how to use the settings can be found at:
- [Mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)
- [w3](https://fetch.spec.whatwg.org/#http-access-control-allow-origin)
- [IETF](https://tools.ietf.org/html/rfc6454#section-7.1)
Traefik no longer supports the `null` value, as it is [no longer recommended as a return value](https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null).
### `accessControlAllowOriginListRegex`
The `accessControlAllowOriginListRegex` option is the counterpart of the `accessControlAllowOriginList` option with regular expressions instead of origin values.
It allows all origins that contain any match of a regular expression in the `accessControlAllowOriginList`.
!!! tip
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
When defining a regular expression within YAML, any escaped character needs to be escaped twice: `example\.com` needs to be written as `example\\.com`.
### `accessControlExposeHeaders`
The `accessControlExposeHeaders` indicates which headers are safe to expose to the api of a CORS API specification.
### `accessControlMaxAge`
The `accessControlMaxAge` indicates how many seconds a preflight request can be cached for.
### `addVaryHeader`
The `addVaryHeader` is used in conjunction with `accessControlAllowOriginList` to determine whether the `Vary` header should be added or modified to demonstrate that server responses can differ based on the value of the origin header.
### `allowedHosts`
The `allowedHosts` option lists fully qualified domain names that are allowed.
### `hostsProxyHeaders`
The `hostsProxyHeaders` option is a set of header keys that may hold a proxied hostname value for the request.
### `sslRedirect`
!!! warning
Deprecated in favor of [EntryPoint redirection](../../routing/entrypoints.md#redirection) or the [RedirectScheme middleware](./redirectscheme.md).
The `sslRedirect` only allow HTTPS requests when set to `true`.
### `sslTemporaryRedirect`
!!! warning
Deprecated in favor of [EntryPoint redirection](../../routing/entrypoints.md#redirection) or the [RedirectScheme middleware](./redirectscheme.md).
Set `sslTemporaryRedirect` to `true` to force an SSL redirection using a 302 (instead of a 301).
### `sslHost`
!!! warning
Deprecated in favor of the [RedirectRegex middleware](./redirectregex.md).
The `sslHost` option is the host name that is used to redirect HTTP requests to HTTPS.
### `sslProxyHeaders`
The `sslProxyHeaders` option is set of header keys with associated values that would indicate a valid HTTPS request.
It can be useful when using other proxies (example: `"X-Forwarded-Proto": "https"`).
### `sslForceHost`
!!! warning
Deprecated in favor of the [RedirectRegex middleware](./redirectregex.md).
Set `sslForceHost` to `true` and set `sslHost` to force requests to use `SSLHost` regardless of whether they already use SSL.
### `stsSeconds`
The `stsSeconds` is the max-age of the `Strict-Transport-Security` header.
If set to `0`, the header is not set.
### `stsIncludeSubdomains`
If the `stsIncludeSubdomains` is set to `true`, the `includeSubDomains` directive is appended to the `Strict-Transport-Security` header.
### `stsPreload`
Set `stsPreload` to `true` to have the `preload` flag appended to the `Strict-Transport-Security` header.
### `forceSTSHeader`
Set `forceSTSHeader` to `true` to add the STS header even when the connection is HTTP.
### `frameDeny`
Set `frameDeny` to `true` to add the `X-Frame-Options` header with the value of `DENY`.
### `customFrameOptionsValue`
The `customFrameOptionsValue` allows the `X-Frame-Options` header value to be set with a custom value.
This overrides the `FrameDeny` option.
### `contentTypeNosniff`
Set `contentTypeNosniff` to true to add the `X-Content-Type-Options` header with the value `nosniff`.
### `browserXssFilter`
Set `browserXssFilter` to true to add the `X-XSS-Protection` header with the value `1; mode=block`.
### `customBrowserXSSValue`
The `customBrowserXssValue` option allows the `X-XSS-Protection` header value to be set with a custom value.
This overrides the `BrowserXssFilter` option.
### `contentSecurityPolicy`
The `contentSecurityPolicy` option allows the `Content-Security-Policy` header value to be set with a custom value.
### `contentSecurityPolicyReportOnly`
The `contentSecurityPolicyReportOnly` option allows the `Content-Security-Policy-Report-Only` header value to be set with a custom value.
### `publicKey`
The `publicKey` implements HPKP to prevent MITM attacks with forged certificates.
### `referrerPolicy`
The `referrerPolicy` allows sites to control whether browsers forward the `Referer` header to other sites.
### `featurePolicy`
!!! warning
Deprecated in favor of [`permissionsPolicy`](#permissionsPolicy)
The `featurePolicy` allows sites to control browser features.
### `permissionsPolicy`
The `permissionsPolicy` allows sites to control browser features.
### `isDevelopment`
Set `isDevelopment` to `true` when developing to mitigate the unwanted effects of the `AllowedHosts`, SSL, and STS options.
Usually testing takes place using HTTP, not HTTPS, and on `localhost`, not your production domain.
If you would like your development environment to mimic production with complete Host blocking, SSL redirects, and STS headers, leave this as `false`.
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,357 +0,0 @@
---
title: "Traefik InFlightReq Documentation"
description: "Traefik Proxy's HTTP middleware lets you limit the number of simultaneous in-flight requests. Read the technical documentation."
---
# InFlightReq
Limiting the Number of Simultaneous In-Flight Requests
{: .subtitle }
To proactively prevent services from being overwhelmed with high load, the number of allowed simultaneous in-flight requests can be limited.
## Configuration Examples
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
amount: 10
```
```yaml tab="Consul Catalog"
# Limiting to 10 simultaneous connections
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
```
```yaml tab="File (YAML)"
# Limiting to 10 simultaneous connections
http:
middlewares:
test-inflightreq:
inFlightReq:
amount: 10
```
```toml tab="File (TOML)"
# Limiting to 10 simultaneous connections
[http.middlewares]
[http.middlewares.test-inflightreq.inFlightReq]
amount = 10
```
## Configuration Options
### `amount`
The `amount` option defines the maximum amount of allowed simultaneous in-flight request.
The middleware responds with `HTTP 429 Too Many Requests` if there are already `amount` requests in progress (based on the same `sourceCriterion` strategy).
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
amount: 10
```
```yaml tab="Consul Catalog"
# Limiting to 10 simultaneous connections
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
```
```yaml tab="File (YAML)"
# Limiting to 10 simultaneous connections
http:
middlewares:
test-inflightreq:
inFlightReq:
amount: 10
```
```toml tab="File (TOML)"
# Limiting to 10 simultaneous connections
[http.middlewares]
[http.middlewares.test-inflightreq.inFlightReq]
amount = 10
```
### `sourceCriterion`
The `sourceCriterion` option defines what criterion is used to group requests as originating from a common source.
If several strategies are defined at the same time, an error will be raised.
If none are set, the default is to use the `requestHost`.
#### `sourceCriterion.ipStrategy`
The `ipStrategy` option defines three parameters that configures how Traefik determines the client IP: `depth`, `excludedIPs` and `ipv6Subnet`.
!!! important "As a middleware, InFlightReq happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through the middleware. Therefore, during InFlightReq, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be used and/or relied upon."
##### `ipStrategy.depth`
The `depth` option tells Traefik to use the `X-Forwarded-For` header and select the IP located at the `depth` position (starting from the right).
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP is empty.
- `depth` is ignored if its value is less than or equal to 0.
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
!!! example "Example of Depth & `X-Forwarded-For`"
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used as the criterion is `"12.0.0.1"` (`depth=2`).
| `X-Forwarded-For` | `depth` | clientIP |
|-----------------------------------------|---------|--------------|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
sourceCriterion:
ipStrategy:
depth: 2
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-inflightreq:
inFlightReq:
sourceCriterion:
ipStrategy:
depth: 2
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-inflightreq.inflightreq]
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion.ipStrategy]
depth = 2
```
##### `ipStrategy.excludedIPs`
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
!!! important "If `depth` is specified, `excludedIPs` is ignored."
!!! example "Example of ExcludedIPs & `X-Forwarded-For`"
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|-----------------------------------------|-----------------------|--------------|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
sourceCriterion:
ipStrategy:
excludedIPs:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-inflightreq:
inFlightReq:
sourceCriterion:
ipStrategy:
excludedIPs:
- "127.0.0.1/32"
- "192.168.1.7"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-inflightreq.inflightreq]
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion.ipStrategy]
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
```
##### `ipStrategy.ipv6Subnet`
This strategy applies to `Depth` and `RemoteAddr` strategy only.
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
!!! example "Example of ipv6Subnet"
If `ipv6Subnet` is provided, the IP is transformed in the following way.
| `IP` | `ipv6Subnet` | clientIP |
|---------------------------|--------------|-----------------------|
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.ipv6Subnet=64"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
sourceCriterion:
ipStrategy:
ipv6Subnet: 64
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.ipv6Subnet=64"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-inflightreq:
inFlightReq:
sourceCriterion:
ipStrategy:
ipv6Subnet: 64
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-inflightreq.inflightreq]
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion.ipStrategy]
ipv6Subnet = 64
```
#### `sourceCriterion.requestHeaderName`
Name of the header used to group incoming requests.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
sourceCriterion:
requestHeaderName: username
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-inflightreq:
inFlightReq:
sourceCriterion:
requestHeaderName: username
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-inflightreq.inflightreq]
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion]
requestHeaderName = "username"
```
#### `sourceCriterion.requestHost`
Whether to consider the request host as the source.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-inflightreq
spec:
inFlightReq:
sourceCriterion:
requestHost: true
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-inflightreq:
inFlightReq:
sourceCriterion:
requestHost: true
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-inflightreq.inflightreq]
[http.middlewares.test-inflightreq.inFlightReq.sourceCriterion]
requestHost = true
```
@@ -1,308 +0,0 @@
---
title: "Traefik HTTP Middlewares IPAllowList"
description: "Learn how to use IPAllowList in HTTP middleware for limiting clients to specific IPs in Traefik Proxy. Read the technical documentation."
---
# IPAllowList
Limiting Clients to Specific IPs
{: .subtitle }
IPAllowList limits allowed requests based on the client IP.
## Configuration Examples
```yaml tab="Docker"
# Accepts request from defined IP
labels:
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipallowlist
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
# Accepts request from defined IP
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="File (YAML)"
# Accepts request from defined IP
http:
middlewares:
test-ipallowlist:
ipAllowList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
```
```toml tab="File (TOML)"
# Accepts request from defined IP
[http.middlewares]
[http.middlewares.test-ipallowlist.ipAllowList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
```
## Configuration Options
### `sourceRange`
_Required_
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
### `ipStrategy`
The `ipStrategy` option defines two parameters that set how Traefik determines the client IP: `depth`, and `excludedIPs`.
If no strategy is set, the default behavior is to match `sourceRange` against the Remote address found in the request.
!!! important "As a middleware, whitelisting happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through whitelisting. Therefore, during whitelisting, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be matched against `sourceRange`."
#### `ipStrategy.depth`
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
- `depth` is ignored if its value is less than or equal to 0.
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
!!! example "Examples of Depth & `X-Forwarded-For`"
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used is `"12.0.0.1"` (`depth=2`).
| `X-Forwarded-For` | `depth` | clientIP |
|-----------------------------------------|---------|--------------|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
```yaml tab="Docker"
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
labels:
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2"
```
```yaml tab="Kubernetes"
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipallowlist
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.7
ipStrategy:
depth: 2
```
```yaml tab="Consul Catalog"
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2"
```
```yaml tab="File (YAML)"
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
http:
middlewares:
test-ipallowlist:
ipAllowList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
ipStrategy:
depth: 2
```
```toml tab="File (TOML)"
# Allowlisting Based on `X-Forwarded-For` with `depth=2`
[http.middlewares]
[http.middlewares.test-ipallowlist.ipAllowList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
depth = 2
```
#### `ipStrategy.excludedIPs`
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
!!! important "If `depth` is specified, `excludedIPs` is ignored."
!!! example "Example of ExcludedIPs & `X-Forwarded-For`"
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|-----------------------------------------|-----------------------|--------------|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
```yaml tab="Docker"
# Exclude from `X-Forwarded-For`
labels:
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
# Exclude from `X-Forwarded-For`
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipallowlist
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.0/24
ipStrategy:
excludedIPs:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
# Exclude from `X-Forwarded-For`
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="File (YAML)"
# Exclude from `X-Forwarded-For`
http:
middlewares:
test-ipallowlist:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.0/24
ipStrategy:
excludedIPs:
- 127.0.0.1/32
- 192.168.1.7
```
```toml tab="File (TOML)"
# Exclude from `X-Forwarded-For`
[http.middlewares]
[http.middlewares.test-ipallowlist.ipAllowList]
sourceRange = ["127.0.0.1/32", "192.168.1.0/24"]
[http.middlewares.test-ipallowlist.ipAllowList.ipStrategy]
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
```
#### `ipStrategy.ipv6Subnet`
This strategy applies to `Depth` and `RemoteAddr` strategy only.
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
!!! example "Example of ipv6Subnet"
If `ipv6Subnet` is provided, the IP is transformed in the following way.
| `IP` | `ipv6Subnet` | clientIP |
|---------------------------|--------------|-----------------------|
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcecriterion.ipstrategy.ipv6Subnet=64"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipallowlist
spec:
ipallowlist:
sourceCriterion:
ipStrategy:
ipv6Subnet: 64
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcecriterion.ipstrategy.ipv6Subnet=64"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-ipallowlist:
ipallowlist:
sourceCriterion:
ipStrategy:
ipv6Subnet: 64
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-ipallowlist.ipallowlist]
[http.middlewares.test-ipallowlist.ipallowlist.sourceCriterion.ipStrategy]
ipv6Subnet = 64
```
### `rejectStatusCode`
The `rejectStatusCode` option sets HTTP status code for refused requests. If not set, the default is 403 (Forbidden).
```yaml tab="Docker & Swarm"
# Reject requests with a 404 rather than a 403
labels:
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.rejectstatuscode=404"
```
```yaml tab="Kubernetes"
# Reject requests with a 404 rather than a 403
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipallowlist
spec:
ipAllowList:
rejectStatusCode: 404
```
```yaml tab="Consul Catalog"
# Reject requests with a 404 rather than a 403
- "traefik.http.middlewares.test-ipallowlist.ipallowlist.rejectstatuscode=404"
```
```yaml tab="File (YAML)"
# Reject requests with a 404 rather than a 403
http:
middlewares:
test-ipallowlist:
ipAllowList:
rejectStatusCode: 404
```
```toml tab="File (TOML)"
# Reject requests with a 404 rather than a 403
[http.middlewares]
[http.middlewares.test-ipallowlist.ipAllowList]
rejectStatusCode = 404
```
@@ -1,270 +0,0 @@
---
title: "Traefik HTTP Middlewares IPWhiteList"
description: "Learn how to use IPWhiteList in HTTP middleware for limiting clients to specific IPs in Traefik Proxy. Read the technical documentation."
---
# IPWhiteList
Limiting Clients to Specific IPs
{: .subtitle }
IPWhiteList limits allowed requests based on the client IP.
!!! warning
This middleware is deprecated, please use the [IPAllowList](./ipallowlist.md) middleware instead.
## Configuration Examples
```yaml tab="Docker"
# Accepts request from defined IP
labels:
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipwhitelist
spec:
ipWhiteList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
# Accepts request from defined IP
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="File (YAML)"
# Accepts request from defined IP
http:
middlewares:
test-ipwhitelist:
ipWhiteList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
```
```toml tab="File (TOML)"
# Accepts request from defined IP
[http.middlewares]
[http.middlewares.test-ipwhitelist.ipWhiteList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
```
## Configuration Options
### `sourceRange`
_Required_
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
### `ipStrategy`
The `ipStrategy` option defines two parameters that set how Traefik determines the client IP: `depth`, and `excludedIPs`.
If no strategy is set, the default behavior is to match `sourceRange` against the Remote address found in the request.
!!! important "As a middleware, whitelisting happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through whitelisting. Therefore, during whitelisting, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be matched against `sourceRange`."
#### `ipStrategy.depth`
The `depth` option tells Traefik to use the `X-Forwarded-For` header and take the IP located at the `depth` position (starting from the right).
- If `depth` is greater than the total number of IPs in `X-Forwarded-For`, then the client IP will be empty.
- `depth` is ignored if its value is less than or equal to 0.
If `ipStrategy.ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
See [ipStrategy.ipv6Subnet](#ipstrategyipv6subnet) for more details.
!!! example "Examples of Depth & `X-Forwarded-For`"
If `depth` is set to 2, and the request `X-Forwarded-For` header is `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` then the "real" client IP is `"10.0.0.1"` (at depth 4) but the IP used for the whitelisting is `"12.0.0.1"` (`depth=2`).
| `X-Forwarded-For` | `depth` | clientIP |
|-----------------------------------------|---------|--------------|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `1` | `"13.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `3` | `"11.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `5` | `""` |
```yaml tab="Docker"
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
labels:
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.depth=2"
```
```yaml tab="Kubernetes"
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipwhitelist
spec:
ipWhiteList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.7
ipStrategy:
depth: 2
```
```yaml tab="Consul Catalog"
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.depth=2"
```
```yaml tab="File (YAML)"
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
http:
middlewares:
test-ipwhitelist:
ipWhiteList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
ipStrategy:
depth: 2
```
```toml tab="File (TOML)"
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
[http.middlewares]
[http.middlewares.test-ipwhitelist.ipWhiteList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
[http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy]
depth = 2
```
#### `ipStrategy.excludedIPs`
`excludedIPs` configures Traefik to scan the `X-Forwarded-For` header and select the first IP not in the list.
!!! important "If `depth` is specified, `excludedIPs` is ignored."
!!! example "Example of ExcludedIPs & `X-Forwarded-For`"
| `X-Forwarded-For` | `excludedIPs` | clientIP |
|-----------------------------------------|-----------------------|--------------|
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"12.0.0.1,13.0.0.1"` | `"11.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"10.0.0.1,13.0.0.1"` | `"12.0.0.1"` |
| `"10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1"` | `"15.0.0.1,16.0.0.1"` | `"13.0.0.1"` |
| `"10.0.0.1,11.0.0.1"` | `"10.0.0.1,11.0.0.1"` | `""` |
```yaml tab="Docker"
# Exclude from `X-Forwarded-For`
labels:
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
# Exclude from `X-Forwarded-For`
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipwhitelist
spec:
ipWhiteList:
ipStrategy:
sourceRange:
- 127.0.0.1/32
- 192.168.1.0/24
excludedIPs:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
# Exclude from `X-Forwarded-For`
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourceRange=127.0.0.1/32, 192.168.1.0/24"
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="File (YAML)"
# Exclude from `X-Forwarded-For`
http:
middlewares:
test-ipwhitelist:
ipWhiteList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.0/24
ipStrategy:
excludedIPs:
- 127.0.0.1/32
- 192.168.1.7
```
```toml tab="File (TOML)"
# Exclude from `X-Forwarded-For`
[http.middlewares]
[http.middlewares.test-ipwhitelist.ipWhiteList]
sourceRange = ["127.0.0.1/32", "192.168.1.0/24"]
[http.middlewares.test-ipwhitelist.ipWhiteList.ipStrategy]
excludedIPs = ["127.0.0.1/32", "192.168.1.7"]
```
#### `ipStrategy.ipv6Subnet`
This strategy applies to `Depth` and `RemoteAddr` strategy only.
If `ipv6Subnet` is provided and the selected IP is IPv6, the IP is transformed into the first IP of the subnet it belongs to.
This is useful for grouping IPv6 addresses into subnets to prevent bypassing this middleware by obtaining a new IPv6.
- `ipv6Subnet` is ignored if its value is outside of 0-128 interval
!!! example "Example of ipv6Subnet"
If `ipv6Subnet` is provided, the IP is transformed in the following way.
| `IP` | `ipv6Subnet` | clientIP |
|---------------------------|--------------|-----------------------|
| `"::abcd:1111:2222:3333"` | `64` | `"::0:0:0:0"` |
| `"::abcd:1111:2222:3333"` | `80` | `"::abcd:0:0:0:0"` |
| `"::abcd:1111:2222:3333"` | `96` | `"::abcd:1111:0:0:0"` |
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-ipWhiteList.ipWhiteList.sourcecriterion.ipstrategy.ipv6Subnet=64"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-ipWhiteList
spec:
ipWhiteList:
sourceCriterion:
ipStrategy:
ipv6Subnet: 64
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-ipWhiteList.ipWhiteList.sourcecriterion.ipstrategy.ipv6Subnet=64"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-ipWhiteList:
ipWhiteList:
sourceCriterion:
ipStrategy:
ipv6Subnet: 64
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-ipWhiteList.ipWhiteList]
[http.middlewares.test-ipWhiteList.ipWhiteList.sourceCriterion.ipStrategy]
ipv6Subnet = 64
```
-130
View File
@@ -1,130 +0,0 @@
---
title: "Traefik Proxy HTTP Middleware Overview"
description: "Read the official Traefik Proxy documentation for an overview of the available HTTP middleware."
---
# HTTP Middlewares
Controlling connections
{: .subtitle }
## Configuration Example
```yaml tab="Docker & Swarm"
# As a Docker Label
whoami:
# A container that exposes an API to show its IP address
image: traefik/whoami
labels:
# Create a middleware named `foo-add-prefix`
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
# Apply the middleware named `foo-add-prefix` to the router named `router1`
- "traefik.http.routers.router1.middlewares=foo-add-prefix@docker"
```
```yaml tab="IngressRoute"
# As a Kubernetes Traefik IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: stripprefix
spec:
stripPrefix:
prefixes:
- /stripit
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute
spec:
# more fields...
routes:
# more fields...
middlewares:
- name: stripprefix
```
```yaml tab="Consul Catalog"
# Create a middleware named `foo-add-prefix`
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
# Apply the middleware named `foo-add-prefix` to the router named `router1`
- "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog"
```
```toml tab="File (TOML)"
# As TOML Configuration File
[http.routers]
[http.routers.router1]
service = "service1"
middlewares = ["foo-add-prefix"]
rule = "Host(`example.com`)"
[http.middlewares]
[http.middlewares.foo-add-prefix.addPrefix]
prefix = "/foo"
[http.services]
[http.services.service1]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "http://127.0.0.1:80"
```
```yaml tab="File (YAML)"
# As YAML Configuration File
http:
routers:
router1:
service: service1
middlewares:
- "foo-add-prefix"
rule: "Host(`example.com`)"
middlewares:
foo-add-prefix:
addPrefix:
prefix: "/foo"
services:
service1:
loadBalancer:
servers:
- url: "http://127.0.0.1:80"
```
## Available HTTP Middlewares
| Middleware | Purpose | Area |
|-------------------------------------------|---------------------------------------------------|-----------------------------|
| [AddPrefix](addprefix.md) | Adds a Path Prefix | Path Modifier |
| [BasicAuth](basicauth.md) | Adds Basic Authentication | Security, Authentication |
| [Buffering](buffering.md) | Buffers the request/response | Request Lifecycle |
| [Chain](chain.md) | Combines multiple pieces of middleware | Misc |
| [CircuitBreaker](circuitbreaker.md) | Prevents calling unhealthy services | Request Lifecycle |
| [Compress](compress.md) | Compresses the response | Content Modifier |
| [ContentType](contenttype.md) | Handles Content-Type auto-detection | Misc |
| [DigestAuth](digestauth.md) | Adds Digest Authentication | Security, Authentication |
| [Errors](errorpages.md) | Defines custom error pages | Request Lifecycle |
| [ForwardAuth](forwardauth.md) | Delegates Authentication | Security, Authentication |
| [Headers](headers.md) | Adds / Updates headers | Security |
| [IPAllowList](ipallowlist.md) | Limits the allowed client IPs | Security, Request lifecycle |
| [InFlightReq](inflightreq.md) | Limits the number of simultaneous connections | Security, Request lifecycle |
| [PassTLSClientCert](passtlsclientcert.md) | Adds Client Certificates in a Header | Security |
| [RateLimit](ratelimit.md) | Limits the call frequency | Security, Request lifecycle |
| [RedirectScheme](redirectscheme.md) | Redirects based on scheme | Request lifecycle |
| [RedirectRegex](redirectregex.md) | Redirects based on regex | Request lifecycle |
| [ReplacePath](replacepath.md) | Changes the path of the request | Path Modifier |
| [ReplacePathRegex](replacepathregex.md) | Changes the path of the request | Path Modifier |
| [Retry](retry.md) | Automatically retries in case of error | Request lifecycle |
| [StripPrefix](stripprefix.md) | Changes the path of the request | Path Modifier |
| [StripPrefixRegex](stripprefixregex.md) | Changes the path of the request | Path Modifier |
## Community Middlewares
Please take a look at the community-contributed plugins in the [plugin catalog](https://plugins.traefik.io/plugins).
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,660 +0,0 @@
---
title: "Traefik PassTLSClientCert Documentation"
description: "In Traefik Proxy's HTTP middleware, the PassTLSClientCert adds selected data from passed client TLS certificates to headers. Read the technical documentation."
---
# PassTLSClientCert
Adding Client Certificates in a Header
{: .subtitle }
<!--
TODO: add schema
-->
PassTLSClientCert adds the selected data from the passed client TLS certificate to a header.
## Configuration Examples
Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
```yaml tab="Docker & Swarm"
# Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
labels:
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-passtlsclientcert
spec:
passTLSClientCert:
pem: true
```
```yaml tab="Consul Catalog"
# Pass the pem in the `X-Forwarded-Tls-Client-Cert` header
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
```
```yaml tab="File (YAML)"
# Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
http:
middlewares:
test-passtlsclientcert:
passTLSClientCert:
pem: true
```
```toml tab="File (TOML)"
# Pass the pem in the `X-Forwarded-Tls-Client-Cert` header.
[http.middlewares]
[http.middlewares.test-passtlsclientcert.passTLSClientCert]
pem = true
```
??? example "Pass the pem in the `X-Forwarded-Tls-Client-Cert` header"
```yaml tab="Docker & Swarm"
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
labels:
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.serialnumber=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organizationalunit=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
```
```yaml tab="Kubernetes"
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-passtlsclientcert
spec:
passTLSClientCert:
info:
notAfter: true
notBefore: true
sans: true
subject:
country: true
province: true
locality: true
organization: true
organizationalUnit: true
commonName: true
serialNumber: true
domainComponent: true
issuer:
country: true
province: true
locality: true
organization: true
commonName: true
serialNumber: true
domainComponent: true
```
```yaml tab="Consul Catalog"
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organizationalunit=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
```
```yaml tab="File (YAML)"
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
http:
middlewares:
test-passtlsclientcert:
passTLSClientCert:
info:
notAfter: true
notBefore: true
sans: true
subject:
country: true
province: true
locality: true
organization: true
organizationalUnit: true
commonName: true
serialNumber: true
domainComponent: true
issuer:
country: true
province: true
locality: true
organization: true
commonName: true
serialNumber: true
domainComponent: true
```
```toml tab="File (TOML)"
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
[http.middlewares]
[http.middlewares.test-passtlsclientcert.passTLSClientCert]
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info]
notAfter = true
notBefore = true
sans = true
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info.subject]
country = true
province = true
locality = true
organization = true
organizationalUnit = true
commonName = true
serialNumber = true
domainComponent = true
[http.middlewares.test-passtlsclientcert.passTLSClientCert.info.issuer]
country = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
domainComponent = true
```
## Configuration Options
### General
PassTLSClientCert can add two headers to the request:
- `X-Forwarded-Tls-Client-Cert` that contains the pem.
- `X-Forwarded-Tls-Client-Cert-Info` that contains all the selected certificate information in an escaped string.
!!! info
* `X-Forwarded-Tls-Client-Cert-Info` header value is a string that has been escaped in order to be a valid URL query.
* These options only work accordingly to the [MutualTLS configuration](../../https/tls.md#client-authentication-mtls).
That is to say, only the certificates that match the `clientAuth.clientAuthType` policy are passed.
The following example shows a complete certificate and explains each of the middleware options.
??? example "A complete client TLS certificate"
```
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=Simple Signing CA, CN=Simple Signing CA 2, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Signing State, ST=Signing State 2/emailAddress=simple@signing.com/emailAddress=simple2@signing.com
Validity
Not Before: Dec 6 11:10:16 2018 GMT
Not After : Dec 5 11:10:16 2020 GMT
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.example.org, CN=*.example.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@example.org/emailAddress=cert@sexample.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:de:77:fa:8d:03:70:30:39:dd:51:1b:cc:60:db:
a9:5a:13:b1:af:fe:2c:c6:38:9b:88:0a:0f:8e:d9:
1b:a1:1d:af:0d:66:e4:13:5b:bc:5d:36:92:d7:5e:
d0:fa:88:29:d3:78:e1:81:de:98:b2:a9:22:3f:bf:
8a:af:12:92:63:d4:a9:c3:f2:e4:7e:d2:dc:a2:c5:
39:1c:7a:eb:d7:12:70:63:2e:41:47:e0:f0:08:e8:
dc:be:09:01:ec:28:09:af:35:d7:79:9c:50:35:d1:
6b:e5:87:7b:34:f6:d2:31:65:1d:18:42:69:6c:04:
11:83:fe:44:ae:90:92:2d:0b:75:39:57:62:e6:17:
2f:47:2b:c7:53:dd:10:2d:c9:e3:06:13:d2:b9:ba:
63:2e:3c:7d:83:6b:d6:89:c9:cc:9d:4d:bf:9f:e8:
a3:7b:da:c8:99:2b:ba:66:d6:8e:f8:41:41:a0:c9:
d0:5e:c8:11:a4:55:4a:93:83:87:63:04:63:41:9c:
fb:68:04:67:c2:71:2f:f2:65:1d:02:5d:15:db:2c:
d9:04:69:85:c2:7d:0d:ea:3b:ac:85:f8:d4:8f:0f:
c5:70:b2:45:e1:ec:b2:54:0b:e9:f7:82:b4:9b:1b:
2d:b9:25:d4:ab:ca:8f:5b:44:3e:15:dd:b8:7f:b7:
ee:f9
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Basic Constraints:
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Key Identifier:
94:BA:73:78:A2:87:FB:58:28:28:CF:98:3B:C2:45:70:16:6E:29:2F
X509v3 Authority Key Identifier:
keyid:1E:52:A2:E8:54:D5:37:EB:D5:A8:1D:E4:C2:04:1D:37:E2:F7:70:03
X509v3 Subject Alternative Name:
DNS:*.example.org, DNS:*.example.net, DNS:*.example.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@example.org, email:test@example.net
Signature Algorithm: sha1WithRSAEncryption
76:6b:05:b0:0e:34:11:b1:83:99:91:dc:ae:1b:e2:08:15:8b:
16:b2:9b:27:1c:02:ac:b5:df:1b:d0:d0:75:a4:2b:2c:5c:65:
ed:99:ab:f7:cd:fe:38:3f:c3:9a:22:31:1b:ac:8c:1c:c2:f9:
5d:d4:75:7a:2e:72:c7:85:a9:04:af:9f:2a:cc:d3:96:75:f0:
8e:c7:c6:76:48:ac:45:a4:b9:02:1e:2f:c0:15:c4:07:08:92:
cb:27:50:67:a1:c8:05:c5:3a:b3:a6:48:be:eb:d5:59:ab:a2:
1b:95:30:71:13:5b:0a:9a:73:3b:60:cc:10:d0:6a:c7:e5:d7:
8b:2f:f9:2e:98:f2:ff:81:14:24:09:e3:4b:55:57:09:1a:22:
74:f1:f6:40:13:31:43:89:71:0a:96:1a:05:82:1f:83:3a:87:
9b:17:25:ef:5a:55:f2:2d:cd:0d:4d:e4:81:58:b6:e3:8d:09:
62:9a:0c:bd:e4:e5:5c:f0:95:da:cb:c7:34:2c:34:5f:6d:fc:
60:7b:12:5b:86:fd:df:21:89:3b:48:08:30:bf:67:ff:8c:e6:
9b:53:cc:87:36:47:70:40:3b:d9:90:2a:d2:d2:82:c6:9c:f5:
d1:d8:e0:e6:fd:aa:2f:95:7e:39:ac:fc:4e:d4:ce:65:b3:ec:
c6:98:8a:31
-----BEGIN CERTIFICATE-----
MIIGWjCCBUKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCCAYQxEzARBgoJkiaJk/Is
ZAEZFgNvcmcxFjAUBgoJkiaJk/IsZAEZFgZjaGVlc2UxDzANBgNVBAoMBkNoZWVz
ZTERMA8GA1UECgwIQ2hlZXNlIDIxHzAdBgNVBAsMFlNpbXBsZSBTaWduaW5nIFNl
Y3Rpb24xITAfBgNVBAsMGFNpbXBsZSBTaWduaW5nIFNlY3Rpb24gMjEaMBgGA1UE
AwwRU2ltcGxlIFNpZ25pbmcgQ0ExHDAaBgNVBAMME1NpbXBsZSBTaWduaW5nIENB
IDIxCzAJBgNVBAYTAkZSMQswCQYDVQQGEwJVUzERMA8GA1UEBwwIVE9VTE9VU0Ux
DTALBgNVBAcMBExZT04xFjAUBgNVBAgMDVNpZ25pbmcgU3RhdGUxGDAWBgNVBAgM
D1NpZ25pbmcgU3RhdGUgMjEhMB8GCSqGSIb3DQEJARYSc2ltcGxlQHNpZ25pbmcu
Y29tMSIwIAYJKoZIhvcNAQkBFhNzaW1wbGUyQHNpZ25pbmcuY29tMB4XDTE4MTIw
NjExMTAxNloXDTIwMTIwNTExMTAxNlowggF2MRMwEQYKCZImiZPyLGQBGRYDb3Jn
MRYwFAYKCZImiZPyLGQBGRYGY2hlZXNlMQ8wDQYDVQQKDAZDaGVlc2UxETAPBgNV
BAoMCENoZWVzZSAyMR8wHQYDVQQLDBZTaW1wbGUgU2lnbmluZyBTZWN0aW9uMSEw
HwYDVQQLDBhTaW1wbGUgU2lnbmluZyBTZWN0aW9uIDIxFTATBgNVBAMMDCouY2hl
ZXNlLm9yZzEVMBMGA1UEAwwMKi5jaGVlc2UuY29tMQswCQYDVQQGEwJGUjELMAkG
A1UEBhMCVVMxETAPBgNVBAcMCFRPVUxPVVNFMQ0wCwYDVQQHDARMWU9OMRkwFwYD
VQQIDBBDaGVlc2Ugb3JnIHN0YXRlMRkwFwYDVQQIDBBDaGVlc2UgY29tIHN0YXRl
MR4wHAYJKoZIhvcNAQkBFg9jZXJ0QGNoZWVzZS5vcmcxHzAdBgkqhkiG9w0BCQEW
EGNlcnRAc2NoZWVzZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDed/qNA3AwOd1RG8xg26laE7Gv/izGOJuICg+O2RuhHa8NZuQTW7xdNpLXXtD6
iCnTeOGB3piyqSI/v4qvEpJj1KnD8uR+0tyixTkceuvXEnBjLkFH4PAI6Ny+CQHs
KAmvNdd5nFA10Wvlh3s09tIxZR0YQmlsBBGD/kSukJItC3U5V2LmFy9HK8dT3RAt
yeMGE9K5umMuPH2Da9aJycydTb+f6KN72siZK7pm1o74QUGgydBeyBGkVUqTg4dj
BGNBnPtoBGfCcS/yZR0CXRXbLNkEaYXCfQ3qO6yF+NSPD8VwskXh7LJUC+n3grSb
Gy25JdSryo9bRD4V3bh/t+75AgMBAAGjgeAwgd0wDgYDVR0PAQH/BAQDAgWgMAkG
A1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW
BBSUunN4oof7WCgoz5g7wkVwFm4pLzAfBgNVHSMEGDAWgBQeUqLoVNU369WoHeTC
BB034vdwAzBhBgNVHREEWjBYggwqLmNoZWVzZS5vcmeCDCouY2hlZXNlLm5ldIIM
Ki5jaGVlc2UuY29thwQKAAEAhwQKAAECgQ90ZXN0QGNoZWVzZS5vcmeBD3Rlc3RA
Y2hlZXNlLm5ldDANBgkqhkiG9w0BAQUFAAOCAQEAdmsFsA40EbGDmZHcrhviCBWL
FrKbJxwCrLXfG9DQdaQrLFxl7Zmr983+OD/DmiIxG6yMHML5XdR1ei5yx4WpBK+f
KszTlnXwjsfGdkisRaS5Ah4vwBXEBwiSyydQZ6HIBcU6s6ZIvuvVWauiG5UwcRNb
CppzO2DMENBqx+XXiy/5Lpjy/4EUJAnjS1VXCRoidPH2QBMxQ4lxCpYaBYIfgzqH
mxcl71pV8i3NDU3kgVi2440JYpoMveTlXPCV2svHNCw0X238YHsSW4b93yGJO0gI
ML9n/4zmm1PMhzZHcEA72ZAq0tKCxpz10djg5v2qL5V+Oaz8TtTOZbPsxpiKMQ==
-----END CERTIFICATE-----
```
### `pem`
The `pem` option sets the `X-Forwarded-Tls-Client-Cert` header with the certificate.
In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` delimiters:
??? example "The data used by the pem option"
```
-----BEGIN CERTIFICATE-----
MIIGWjCCBUKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCCAYQxEzARBgoJkiaJk/Is
ZAEZFgNvcmcxFjAUBgoJkiaJk/IsZAEZFgZjaGVlc2UxDzANBgNVBAoMBkNoZWVz
ZTERMA8GA1UECgwIQ2hlZXNlIDIxHzAdBgNVBAsMFlNpbXBsZSBTaWduaW5nIFNl
Y3Rpb24xITAfBgNVBAsMGFNpbXBsZSBTaWduaW5nIFNlY3Rpb24gMjEaMBgGA1UE
AwwRU2ltcGxlIFNpZ25pbmcgQ0ExHDAaBgNVBAMME1NpbXBsZSBTaWduaW5nIENB
IDIxCzAJBgNVBAYTAkZSMQswCQYDVQQGEwJVUzERMA8GA1UEBwwIVE9VTE9VU0Ux
DTALBgNVBAcMBExZT04xFjAUBgNVBAgMDVNpZ25pbmcgU3RhdGUxGDAWBgNVBAgM
D1NpZ25pbmcgU3RhdGUgMjEhMB8GCSqGSIb3DQEJARYSc2ltcGxlQHNpZ25pbmcu
Y29tMSIwIAYJKoZIhvcNAQkBFhNzaW1wbGUyQHNpZ25pbmcuY29tMB4XDTE4MTIw
NjExMTAxNloXDTIwMTIwNTExMTAxNlowggF2MRMwEQYKCZImiZPyLGQBGRYDb3Jn
MRYwFAYKCZImiZPyLGQBGRYGY2hlZXNlMQ8wDQYDVQQKDAZDaGVlc2UxETAPBgNV
BAoMCENoZWVzZSAyMR8wHQYDVQQLDBZTaW1wbGUgU2lnbmluZyBTZWN0aW9uMSEw
HwYDVQQLDBhTaW1wbGUgU2lnbmluZyBTZWN0aW9uIDIxFTATBgNVBAMMDCouY2hl
ZXNlLm9yZzEVMBMGA1UEAwwMKi5jaGVlc2UuY29tMQswCQYDVQQGEwJGUjELMAkG
A1UEBhMCVVMxETAPBgNVBAcMCFRPVUxPVVNFMQ0wCwYDVQQHDARMWU9OMRkwFwYD
VQQIDBBDaGVlc2Ugb3JnIHN0YXRlMRkwFwYDVQQIDBBDaGVlc2UgY29tIHN0YXRl
MR4wHAYJKoZIhvcNAQkBFg9jZXJ0QGNoZWVzZS5vcmcxHzAdBgkqhkiG9w0BCQEW
EGNlcnRAc2NoZWVzZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDed/qNA3AwOd1RG8xg26laE7Gv/izGOJuICg+O2RuhHa8NZuQTW7xdNpLXXtD6
iCnTeOGB3piyqSI/v4qvEpJj1KnD8uR+0tyixTkceuvXEnBjLkFH4PAI6Ny+CQHs
KAmvNdd5nFA10Wvlh3s09tIxZR0YQmlsBBGD/kSukJItC3U5V2LmFy9HK8dT3RAt
yeMGE9K5umMuPH2Da9aJycydTb+f6KN72siZK7pm1o74QUGgydBeyBGkVUqTg4dj
BGNBnPtoBGfCcS/yZR0CXRXbLNkEaYXCfQ3qO6yF+NSPD8VwskXh7LJUC+n3grSb
Gy25JdSryo9bRD4V3bh/t+75AgMBAAGjgeAwgd0wDgYDVR0PAQH/BAQDAgWgMAkG
A1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW
BBSUunN4oof7WCgoz5g7wkVwFm4pLzAfBgNVHSMEGDAWgBQeUqLoVNU369WoHeTC
BB034vdwAzBhBgNVHREEWjBYggwqLmNoZWVzZS5vcmeCDCouY2hlZXNlLm5ldIIM
Ki5jaGVlc2UuY29thwQKAAEAhwQKAAECgQ90ZXN0QGNoZWVzZS5vcmeBD3Rlc3RA
Y2hlZXNlLm5ldDANBgkqhkiG9w0BAQUFAAOCAQEAdmsFsA40EbGDmZHcrhviCBWL
FrKbJxwCrLXfG9DQdaQrLFxl7Zmr983+OD/DmiIxG6yMHML5XdR1ei5yx4WpBK+f
KszTlnXwjsfGdkisRaS5Ah4vwBXEBwiSyydQZ6HIBcU6s6ZIvuvVWauiG5UwcRNb
CppzO2DMENBqx+XXiy/5Lpjy/4EUJAnjS1VXCRoidPH2QBMxQ4lxCpYaBYIfgzqH
mxcl71pV8i3NDU3kgVi2440JYpoMveTlXPCV2svHNCw0X238YHsSW4b93yGJO0gI
ML9n/4zmm1PMhzZHcEA72ZAq0tKCxpz10djg5v2qL5V+Oaz8TtTOZbPsxpiKMQ==
-----END CERTIFICATE-----
```
!!! info "Extracted data"
The delimiters and `\n` will be removed.
If there are more than one certificate, they are separated by a "`,`".
!!! warning "`X-Forwarded-Tls-Client-Cert` value could exceed the web server header size limit"
The header size limit of web servers is commonly between 4kb and 8kb.
If that turns out to be a problem, and if reconfiguring the server to allow larger headers is not an option,
one can alleviate the problem by selecting only the interesting parts of the cert,
through the use of the `info` options described below. (And by setting `pem` to false).
### `info`
The `info` option selects the specific client certificate details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
The value of the header is an escaped concatenation of all the selected certificate details.
But in the following, unless specified otherwise, all the header values examples are shown unescaped, for readability.
The following example shows such a concatenation, when all the available fields are selected:
```text
Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=*.example.com";Issuer="DC=org,DC=cheese,C=FR,C=US,ST=Signing State,ST=Signing State 2,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=Simple Signing CA 2";NB="1544094616";NA="1607166616";SAN="*.example.org,*.example.net,*.example.com,test@example.org,test@example.net,10.0.1.0,10.0.1.2"
```
!!! info "Multiple certificates"
If there are more than one certificate, they are separated by a `,`.
#### `info.serialNumber`
Set the `info.serialNumber` option to `true` to add the `Serial Number` of the certificate.
The data is taken from the following certificate part:
```text
Serial Number:
6a:2f:20:f8:ce:8d:48:52:ba:d9:bb:be:60:ec:bf:79
```
And it is formatted as follows in the header (decimal representation):
```text
SerialNumber="141142874255168551917600297745052909433"
```
#### `info.notAfter`
Set the `info.notAfter` option to `true` to add the `Not After` information from the `Validity` part.
The data is taken from the following certificate part:
```text
Validity
Not After : Dec 5 11:10:16 2020 GMT
```
And it is formatted as follows in the header:
```text
NA="1607166616"
```
#### `info.notBefore`
Set the `info.notBefore` option to `true` to add the `Not Before` information from the `Validity` part.
The data is taken from the following certificate part:
```text
Validity
Not Before: Dec 6 11:10:16 2018 GMT
```
And it is formatted as follows in the header:
```text
NB="1544094616"
```
#### `info.sans`
Set the `info.sans` option to `true` to add the `Subject Alternative Name` information from the `Subject Alternative Name` part.
The data is taken from the following certificate part:
```text
X509v3 Subject Alternative Name:
DNS:*.example.org, DNS:*.example.net, DNS:*.example.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@example.org, email:test@example.net
```
And it is formatted as follows in the header:
```text
SAN="*.example.org,*.example.net,*.example.com,test@example.org,test@example.net,10.0.1.0,10.0.1.2"
```
!!! info "Multiple values"
The SANs are separated by a `,`.
#### `info.subject`
The `info.subject` selects the specific client certificate subject details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
The data is taken from the following certificate part:
```text
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.example.org, CN=*.example.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@example.org/emailAddress=cert@sexample.com
```
##### `info.subject.country`
Set the `info.subject.country` option to `true` to add the `country` information into the subject.
The data is taken from the subject part with the `C` key.
And it is formatted as follows in the header:
```text
C=FR,C=US
```
##### `info.subject.province`
Set the `info.subject.province` option to `true` to add the `province` information into the subject.
The data is taken from the subject part with the `ST` key.
And it is formatted as follows in the header:
```text
ST=Cheese org state,ST=Cheese com state
```
##### `info.subject.locality`
Set the `info.subject.locality` option to `true` to add the `locality` information into the subject.
The data is taken from the subject part with the `L` key.
And it is formatted as follows in the header:
```text
L=TOULOUSE,L=LYON
```
##### `info.subject.organization`
Set the `info.subject.organization` option to `true` to add the `organization` information into the subject.
The data is taken from the subject part with the `O` key.
And it is formatted as follows in the header:
```text
O=Cheese,O=Cheese 2
```
##### `info.subject.organizationalUnit`
Set the `info.subject.organizationalUnit` option to `true` to add the `organizationalUnit` information into the subject.
The data is taken from the subject part with the `OU` key.
And it is formatted as follows in the header:
```text
OU=Cheese Section,OU=Cheese Section 2
```
##### `info.subject.commonName`
Set the `info.subject.commonName` option to `true` to add the `commonName` information into the subject.
The data is taken from the subject part with the `CN` key.
And it is formatted as follows in the header:
```text
CN=*.example.com
```
##### `info.subject.serialNumber`
Set the `info.subject.serialNumber` option to `true` to add the `serialNumber` information into the subject.
The data is taken from the subject part with the `SN` key.
And it is formatted as follows in the header:
```text
SN=1234567890
```
##### `info.subject.domainComponent`
Set the `info.subject.domainComponent` option to `true` to add the `domainComponent` information into the subject.
The data is taken from the subject part with the `DC` key.
And it is formatted as follows in the header:
```text
DC=org,DC=cheese
```
#### `info.issuer`
The `info.issuer` selects the specific client certificate issuer details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
The data is taken from the following certificate part:
```text
Issuer: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=Simple Signing CA, CN=Simple Signing CA 2, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Signing State, ST=Signing State 2/emailAddress=simple@signing.com/emailAddress=simple2@signing.com
```
##### `info.issuer.country`
Set the `info.issuer.country` option to `true` to add the `country` information into the issuer.
The data is taken from the issuer part with the `C` key.
And it is formatted as follows in the header:
```text
C=FR,C=US
```
##### `info.issuer.province`
Set the `info.issuer.province` option to `true` to add the `province` information into the issuer.
The data is taken from the issuer part with the `ST` key.
And it is formatted as follows in the header:
```text
ST=Signing State,ST=Signing State 2
```
##### `info.issuer.locality`
Set the `info.issuer.locality` option to `true` to add the `locality` information into the issuer.
The data is taken from the issuer part with the `L` key.
And it is formatted as follows in the header:
```text
L=TOULOUSE,L=LYON
```
##### `info.issuer.organization`
Set the `info.issuer.organization` option to `true` to add the `organization` information into the issuer.
The data is taken from the issuer part with the `O` key.
And it is formatted as follows in the header:
```text
O=Cheese,O=Cheese 2
```
##### `info.issuer.commonName`
Set the `info.issuer.commonName` option to `true` to add the `commonName` information into the issuer.
The data is taken from the issuer part with the `CN` key.
And it is formatted as follows in the header:
```text
CN=Simple Signing CA 2
```
##### `info.issuer.serialNumber`
Set the `info.issuer.serialNumber` option to `true` to add the `serialNumber` information into the issuer.
The data is taken from the issuer part with the `SN` key.
And it is formatted as follows in the header:
```text
SN=1234567890
```
##### `info.issuer.domainComponent`
Set the `info.issuer.domainComponent` option to `true` to add the `domainComponent` information into the issuer.
The data is taken from the issuer part with the `DC` key.
And it is formatted as follows in the header:
```text
DC=org,DC=cheese
```
File diff suppressed because it is too large Load Diff
@@ -1,88 +0,0 @@
---
title: "Traefik RedirectRegex Documentation"
description: "In Traefik Proxy's HTTP middleware, RedirectRegex redirecting clients to different locations. Read the technical documentation."
---
# RedirectRegex
Redirecting the Client to a Different Location
{: .subtitle }
<!--
TODO: add schema
-->
The RedirectRegex redirects a request using regex matching and replacement.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Redirect with domain replacement
# Note: all dollar signs need to be doubled for escaping.
labels:
- "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^http://localhost/(.*)"
- "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}"
```
```yaml tab="Kubernetes"
# Redirect with domain replacement
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-redirectregex
spec:
redirectRegex:
regex: ^http://localhost/(.*)
replacement: http://mydomain/${1}
```
```yaml tab="Consul Catalog"
# Redirect with domain replacement
# Note: all dollar signs need to be doubled for escaping.
- "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^http://localhost/(.*)"
- "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}"
```
```yaml tab="File (YAML)"
# Redirect with domain replacement
http:
middlewares:
test-redirectregex:
redirectRegex:
regex: "^http://localhost/(.*)"
replacement: "http://mydomain/${1}"
```
```toml tab="File (TOML)"
# Redirect with domain replacement
[http.middlewares]
[http.middlewares.test-redirectregex.redirectRegex]
regex = "^http://localhost/(.*)"
replacement = "http://mydomain/${1}"
```
## Configuration Options
### `permanent`
Set the `permanent` option to `true` to apply a permanent redirection.
### `regex`
The `regex` option is the regular expression to match and capture elements from the request URL.
!!! tip
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
When defining a regular expression within YAML, any escaped character needs to be escaped twice: `example\.com` needs to be written as `example\\.com`.
### `replacement`
The `replacement` option defines how to modify the URL to have the new target URL.
!!! warning
Care should be taken when defining replacement expand variables: `$1x` is equivalent to `${1x}`, not `${1}x` (see [Regexp.Expand](https://golang.org/pkg/regexp/#Regexp.Expand)), so use `${1}` syntax.
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,213 +0,0 @@
---
title: "Traefik RedirectScheme Documentation"
description: "In Traefik Proxy's HTTP middleware, RedirectScheme redirects clients to different schemes/ports. Read the technical documentation."
---
# RedirectScheme
Redirecting the Client to a Different Scheme/Port
{: .subtitle }
<!--
TODO: add schema
-->
The RedirectScheme middleware redirects the request if the request scheme is different from the configured scheme.
!!! warning "When behind another reverse-proxy"
When there is at least one other reverse-proxy between the client and Traefik,
the other reverse-proxy (i.e. the last hop) needs to be a [trusted](../../routing/entrypoints.md#forwarded-headers) one.
Otherwise, Traefik would clean up the `X-Forwarded` headers coming from this last hop,
and as the RedirectScheme middleware relies on them to determine the scheme used,
it would not function as intended.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Redirect to https
labels:
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
```
```yaml tab="Kubernetes"
# Redirect to https
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-redirectscheme
spec:
redirectScheme:
scheme: https
permanent: true
```
```yaml tab="Consul Catalog"
# Redirect to https
labels:
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
```
```yaml tab="File (YAML)"
# Redirect to https
http:
middlewares:
test-redirectscheme:
redirectScheme:
scheme: https
permanent: true
```
```toml tab="File (TOML)"
# Redirect to https
[http.middlewares]
[http.middlewares.test-redirectscheme.redirectScheme]
scheme = "https"
permanent = true
```
## Configuration Options
### `permanent`
Set the `permanent` option to `true` to apply a permanent redirection.
```yaml tab="Docker & Swarm"
# Redirect to https
labels:
# ...
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
```
```yaml tab="Kubernetes"
# Redirect to https
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-redirectscheme
spec:
redirectScheme:
# ...
permanent: true
```
```yaml tab="Consul Catalog"
# Redirect to https
labels:
# ...
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
```
```yaml tab="File (YAML)"
# Redirect to https
http:
middlewares:
test-redirectscheme:
redirectScheme:
# ...
permanent: true
```
```toml tab="File (TOML)"
# Redirect to https
[http.middlewares]
[http.middlewares.test-redirectscheme.redirectScheme]
# ...
permanent = true
```
### `scheme`
The `scheme` option defines the scheme of the new URL.
```yaml tab="Docker & Swarm"
# Redirect to https
labels:
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
```
```yaml tab="Kubernetes"
# Redirect to https
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-redirectscheme
spec:
redirectScheme:
scheme: https
```
```yaml tab="Consul Catalog"
# Redirect to https
labels:
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
```
```yaml tab="File (YAML)"
# Redirect to https
http:
middlewares:
test-redirectscheme:
redirectScheme:
scheme: https
```
```toml tab="File (TOML)"
# Redirect to https
[http.middlewares]
[http.middlewares.test-redirectscheme.redirectScheme]
scheme = "https"
```
### `port`
The `port` option defines the port of the new URL.
```yaml tab="Docker & Swarm"
# Redirect to https
labels:
# ...
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443"
```
```yaml tab="Kubernetes"
# Redirect to https
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-redirectscheme
spec:
redirectScheme:
# ...
port: "443"
```
```yaml tab="Consul Catalog"
# Redirect to https
labels:
# ...
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443"
```
```yaml tab="File (YAML)"
# Redirect to https
http:
middlewares:
test-redirectscheme:
redirectScheme:
# ...
port: "443"
```
```toml tab="File (TOML)"
# Redirect to https
[http.middlewares]
[http.middlewares.test-redirectscheme.redirectScheme]
# ...
port = 443
```
!!! info "Port in this configuration is a string, not a numeric value."
@@ -1,68 +0,0 @@
---
title: "Traefik ReplacePath Documentation"
description: "In Traefik Proxy's HTTP middleware, ReplacePath updates paths before forwarding requests. Read the technical documentation."
---
# ReplacePath
Updating the Path Before Forwarding the Request
{: .subtitle }
<!--
TODO: add schema
-->
Replace the path of the request URL.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Replace the path with /foo
labels:
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
```
```yaml tab="Kubernetes"
# Replace the path with /foo
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-replacepath
spec:
replacePath:
path: /foo
```
```yaml tab="Consul Catalog"
# Replace the path with /foo
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
```
```yaml tab="File (YAML)"
# Replace the path with /foo
http:
middlewares:
test-replacepath:
replacePath:
path: "/foo"
```
```toml tab="File (TOML)"
# Replace the path with /foo
[http.middlewares]
[http.middlewares.test-replacepath.replacePath]
path = "/foo"
```
## Configuration Options
### General
The ReplacePath middleware will:
- replace the actual path with the specified one.
- store the original path in a `X-Replaced-Path` header.
### `path`
The `path` option defines the path to use as replacement in the request URL.
@@ -1,87 +0,0 @@
---
title: "Traefik ReplacePathRegex Documentation"
description: "In Traefik Proxy's HTTP middleware, ReplacePathRegex updates paths before forwarding requests, using a regex. Read the technical documentation."
---
# ReplacePathRegex
Updating the Path Before Forwarding the Request (Using a Regex)
{: .subtitle }
<!--
TODO: add schema
-->
The ReplaceRegex replaces the path of a URL using regex matching and replacement.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Replace path with regex
labels:
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$$1"
```
```yaml tab="Kubernetes"
# Replace path with regex
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-replacepathregex
spec:
replacePathRegex:
regex: ^/foo/(.*)
replacement: /bar/$1
```
```yaml tab="Consul Catalog"
# Replace path with regex
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1"
```
```yaml tab="File (YAML)"
# Replace path with regex
http:
middlewares:
test-replacepathregex:
replacePathRegex:
regex: "^/foo/(.*)"
replacement: "/bar/$1"
```
```toml tab="File (TOML)"
# Replace path with regex
[http.middlewares]
[http.middlewares.test-replacepathregex.replacePathRegex]
regex = "^/foo/(.*)"
replacement = "/bar/$1"
```
## Configuration Options
### General
The ReplacePathRegex middleware will:
- replace the matching path with the specified one.
- store the original path in a `X-Replaced-Path` header.
!!! tip
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
When defining a regular expression within YAML, any escaped character needs to be escaped twice: `example\.com` needs to be written as `example\\.com`.
### `regex`
The `regex` option is the regular expression to match and capture the path from the request URL.
### `replacement`
The `replacement` option defines the replacement path format, which can include captured variables.
!!! warning
Care should be taken when defining replacement expand variables: `$1x` is equivalent to `${1x}`, not `${1}x` (see [Regexp.Expand](https://golang.org/pkg/regexp/#Regexp.Expand)), so use `${1}` syntax.
-80
View File
@@ -1,80 +0,0 @@
---
title: "Traefik HTTP Retry Documentation"
description: "Configure Traefik Proxy's HTTP Retry middleware, so you can retry requests to a backend server until it succeeds. Read the technical documentation."
---
# Retry
Retrying until it Succeeds
{: .subtitle }
<!--
TODO: add schema
-->
The Retry middleware reissues requests a given number of times when it cannot contact the backend service.
This applies at the transport level (TCP).
If the service does not respond to the initial connection attempt, the middleware retries.
However, once the service responds, regardless of the HTTP status code, the middleware considers it operational and stops retrying.
This means that the retry mechanism does not handle HTTP errors; it only retries when there is no response at the TCP level.
The Retry middleware has an optional configuration to enable an exponential backoff.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Retry 4 times with exponential backoff
labels:
- "traefik.http.middlewares.test-retry.retry.attempts=4"
- "traefik.http.middlewares.test-retry.retry.initialinterval=100ms"
```
```yaml tab="Kubernetes"
# Retry 4 times with exponential backoff
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-retry
spec:
retry:
attempts: 4
initialInterval: 100ms
```
```yaml tab="Consul Catalog"
# Retry 4 times with exponential backoff
- "traefik.http.middlewares.test-retry.retry.attempts=4"
- "traefik.http.middlewares.test-retry.retry.initialinterval=100ms"
```
```yaml tab="File (YAML)"
# Retry 4 times with exponential backoff
http:
middlewares:
test-retry:
retry:
attempts: 4
initialInterval: 100ms
```
```toml tab="File (TOML)"
# Retry 4 times with exponential backoff
[http.middlewares]
[http.middlewares.test-retry.retry]
attempts = 4
initialInterval = "100ms"
```
## Configuration Options
### `attempts`
_mandatory_
The `attempts` option defines how many times the request should be retried.
### `initialInterval`
The `initialInterval` option defines the first wait time in the exponential backoff series. The maximum interval is
calculated as twice the `initialInterval`. If unspecified, requests will be retried immediately.
The value of initialInterval should be provided in seconds or as a valid duration format, see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
@@ -1,149 +0,0 @@
---
title: "Traefik StripPrefix Documentation"
description: "In Traefik Proxy's HTTP middleware, StripPrefix removes prefixes from paths before forwarding requests. Read the technical documentation."
---
# StripPrefix
Removing Prefixes From the Path Before Forwarding the Request
{: .subtitle }
<!--
TODO: add schema
-->
Remove the specified prefixes from the URL path.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Strip prefix /foobar and /fiibar
labels:
- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar"
```
```yaml tab="Kubernetes"
# Strip prefix /foobar and /fiibar
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-stripprefix
spec:
stripPrefix:
prefixes:
- /foobar
- /fiibar
```
```yaml tab="Consul Catalog"
# Strip prefix /foobar and /fiibar
- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar"
```
```yaml tab="File (YAML)"
# Strip prefix /foobar and /fiibar
http:
middlewares:
test-stripprefix:
stripPrefix:
prefixes:
- "/foobar"
- "/fiibar"
```
```toml tab="File (TOML)"
# Strip prefix /foobar and /fiibar
[http.middlewares]
[http.middlewares.test-stripprefix.stripPrefix]
prefixes = ["/foobar", "/fiibar"]
```
## Configuration Options
### General
The StripPrefix middleware strips the matching path prefix and stores it in a `X-Forwarded-Prefix` header.
!!! tip
Use a `StripPrefix` middleware if your backend listens on the root path (`/`) but should be exposed on a specific prefix.
### `prefixes`
The `prefixes` option defines the prefixes to strip from the request URL.
For instance, `/products` also matches `/products/shoes` and `/products/shirts`.
If your backend is serving assets (e.g., images or JavaScript files), it can use the `X-Forwarded-Prefix` header to properly construct relative URLs.
Using the previous example, the backend should return `/products/shoes/image.png` (and not `/image.png`, which Traefik would likely not be able to associate with the same backend).
### `forceSlash`
_Optional, Default=true_
!!! warning
`forceSlash` option is deprecated and should not be used.
The `forceSlash` option ensures the resulting stripped path is not the empty string, by replacing it with `/` when necessary.
??? info "Behavior examples"
- `forceSlash=true`
| Path | Prefix to strip | Result |
|------------|-----------------|--------|
| `/` | `/` | `/` |
| `/foo` | `/foo` | `/` |
| `/foo/` | `/foo` | `/` |
| `/foo/` | `/foo/` | `/` |
| `/bar` | `/foo` | `/bar` |
| `/foo/bar` | `/foo` | `/bar` |
- `forceSlash=false`
| Path | Prefix to strip | Result |
|------------|-----------------|--------|
| `/` | `/` | empty |
| `/foo` | `/foo` | empty |
| `/foo/` | `/foo` | `/` |
| `/foo/` | `/foo/` | empty |
| `/bar` | `/foo` | `/bar` |
| `/foo/bar` | `/foo` | `/bar` |
```yaml tab="Docker"
labels:
- "traefik.http.middlewares.example.stripprefix.prefixes=/foobar"
- "traefik.http.middlewares.example.stripprefix.forceSlash=false"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: example
spec:
stripPrefix:
prefixes:
- "/foobar"
forceSlash: false
```
```yaml tab="File (YAML)"
http:
middlewares:
example:
stripPrefix:
prefixes:
- "/foobar"
forceSlash: false
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.example.stripPrefix]
prefixes = ["/foobar"]
forceSlash = false
```
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,73 +0,0 @@
---
title: "Traefik StripPrefixRegex Documentation"
description: "In Traefik Proxy's HTTP middleware, StripPrefixRegex removes prefixes from paths before forwarding requests, using regex. Read the technical documentation."
---
# StripPrefixRegex
Removing Prefixes From the Path Before Forwarding the Request (Using a Regex)
{: .subtitle }
Remove the matching prefixes from the URL path.
## Configuration Examples
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: test-stripprefixregex
spec:
stripPrefixRegex:
regex:
- "/foo/[a-z0-9]+/[0-9]+/"
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/"
```
```yaml tab="File (YAML)"
http:
middlewares:
test-stripprefixregex:
stripPrefixRegex:
regex:
- "/foo/[a-z0-9]+/[0-9]+/"
```
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.test-stripprefixregex.stripPrefixRegex]
regex = ["/foo/[a-z0-9]+/[0-9]+/"]
```
## Configuration Options
### General
The StripPrefixRegex middleware strips the matching path prefix and stores it in a `X-Forwarded-Prefix` header.
!!! tip
Use a `stripPrefixRegex` middleware if your backend listens on the root path (`/`) but should be exposed on a specific prefix.
### `regex`
The `regex` option is the regular expression to match the path prefix from the request URL.
For instance, `/products` also matches `/products/shoes` and `/products/shirts`.
If your backend is serving assets (e.g., images or JavaScript files), it can use the `X-Forwarded-Prefix` header to properly construct relative URLs.
Using the previous example, the backend should return `/products/shoes/image.png` (and not `/images.png`, which Traefik would likely not be able to associate with the same backend).
!!! tip
Regular expressions and replacements can be tested using online tools such as [Go Playground](https://play.golang.org/p/mWU9p-wk2ru) or the [Regex101](https://regex101.com/r/58sIgx/2).
When defining a regular expression within YAML, any escaped character needs to be escaped twice: `example\.com` needs to be written as `example\\.com`.
-115
View File
@@ -1,115 +0,0 @@
---
title: "Traefik Proxy Middleware Overview"
description: "There are several available middleware in Traefik Proxy used to modify requests or headers, take charge of redirections, add authentication, and so on."
---
# Middlewares
Tweaking the Request
{: .subtitle }
Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your [service](../routing/services/index.md) (or before the answer from the services are sent to the clients).
There are several available middleware in Traefik, some can modify the request, the headers, some are in charge of redirections, some add authentication, and so on.
Middlewares that use the same protocol can be combined into chains to fit every scenario.
!!! warning "Provider Namespace"
Be aware of the concept of Providers Namespace described in the [Configuration Discovery](../providers/overview.md#provider-namespace) section.
It also applies to Middlewares.
## Configuration Example
```yaml tab="Docker & Swarm"
# As a Docker Label
whoami:
# A container that exposes an API to show its IP address
image: traefik/whoami
labels:
# Create a middleware named `foo-add-prefix`
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
# Apply the middleware named `foo-add-prefix` to the router named `router1`
- "traefik.http.routers.router1.middlewares=foo-add-prefix@docker"
```
```yaml tab="IngressRoute"
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: stripprefix
spec:
stripPrefix:
prefixes:
- /stripit
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute
spec:
# more fields...
routes:
# more fields...
middlewares:
- name: stripprefix
```
```yaml tab="Consul Catalog"
# Create a middleware named `foo-add-prefix`
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
# Apply the middleware named `foo-add-prefix` to the router named `router1`
- "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog"
```
```yaml tab="File (YAML)"
# As YAML Configuration File
http:
routers:
router1:
service: myService
middlewares:
- "foo-add-prefix"
rule: "Host(`example.com`)"
middlewares:
foo-add-prefix:
addPrefix:
prefix: "/foo"
services:
service1:
loadBalancer:
servers:
- url: "http://127.0.0.1:80"
```
```toml tab="File (TOML)"
# As TOML Configuration File
[http.routers]
[http.routers.router1]
service = "myService"
middlewares = ["foo-add-prefix"]
rule = "Host(`example.com`)"
[http.middlewares]
[http.middlewares.foo-add-prefix.addPrefix]
prefix = "/foo"
[http.services]
[http.services.service1]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "http://127.0.0.1:80"
```
## Available Middlewares
A list of HTTP middlewares can be found [here](http/overview.md).
A list of TCP middlewares can be found [here](tcp/overview.md).
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,51 +0,0 @@
# InFlightConn
Limiting the Number of Simultaneous connections.
{: .subtitle }
To proactively prevent services from being overwhelmed with high load, the number of allowed simultaneous connections by IP can be limited.
## Configuration Examples
```yaml tab="Docker & Swarm"
labels:
- "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: MiddlewareTCP
metadata:
name: test-inflightconn
spec:
inFlightConn:
amount: 10
```
```yaml tab="Consul Catalog"
# Limiting to 10 simultaneous connections
- "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10"
```
```yaml tab="File (YAML)"
# Limiting to 10 simultaneous connections.
tcp:
middlewares:
test-inflightconn:
inFlightConn:
amount: 10
```
```toml tab="File (TOML)"
# Limiting to 10 simultaneous connections
[tcp.middlewares]
[tcp.middlewares.test-inflightconn.inFlightConn]
amount = 10
```
## Configuration Options
### `amount`
The `amount` option defines the maximum amount of allowed simultaneous connections.
The middleware closes the connection if there are already `amount` connections opened.
@@ -1,60 +0,0 @@
---
title: "Traefik TCP Middlewares IPAllowList"
description: "Learn how to use IPAllowList in TCP middleware for limiting clients to specific IPs in Traefik Proxy. Read the technical documentation."
---
# IPAllowList
Limiting Clients to Specific IPs
{: .subtitle }
IPAllowList limits allowed requests based on the client IP.
## Configuration Examples
```yaml tab="Docker & Swarm"
# Accepts connections from defined IP
labels:
- "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: MiddlewareTCP
metadata:
name: test-ipallowlist
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
# Accepts request from defined IP
- "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```toml tab="File (TOML)"
# Accepts request from defined IP
[tcp.middlewares]
[tcp.middlewares.test-ipallowlist.ipAllowList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
```
```yaml tab="File (YAML)"
# Accepts request from defined IP
tcp:
middlewares:
test-ipallowlist:
ipAllowList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
```
## Configuration Options
### `sourceRange`
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
@@ -1,64 +0,0 @@
---
title: "Traefik TCP Middlewares IPWhiteList"
description: "Learn how to use IPWhiteList in TCP middleware for limiting clients to specific IPs in Traefik Proxy. Read the technical documentation."
---
# IPWhiteList
Limiting Clients to Specific IPs
{: .subtitle }
IPWhiteList accepts / refuses connections based on the client IP.
!!! warning
This middleware is deprecated, please use the [IPAllowList](./ipallowlist.md) middleware instead.
## Configuration Examples
```yaml tab="Docker"
# Accepts connections from defined IP
labels:
- "traefik.tcp.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: MiddlewareTCP
metadata:
name: test-ipwhitelist
spec:
ipWhiteList:
sourceRange:
- 127.0.0.1/32
- 192.168.1.7
```
```yaml tab="Consul Catalog"
# Accepts request from defined IP
- "traefik.tcp.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
```
```toml tab="File (TOML)"
# Accepts request from defined IP
[tcp.middlewares]
[tcp.middlewares.test-ipwhitelist.ipWhiteList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
```
```yaml tab="File (YAML)"
# Accepts request from defined IP
tcp:
middlewares:
test-ipwhitelist:
ipWhiteList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
```
## Configuration Options
### `sourceRange`
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
-109
View File
@@ -1,109 +0,0 @@
---
title: "Traefik Proxy TCP Middleware Overview"
description: "Read the official Traefik Proxy documentation for an overview of the available TCP middleware."
---
# TCP Middlewares
Controlling connections
{: .subtitle }
## Configuration Example
```yaml tab="Docker & Swarm"
# As a Docker Label
whoami:
# A container that exposes an API to show its IP address
image: traefik/whoami
labels:
# Create a middleware named `foo-ip-allowlist`
- "traefik.tcp.middlewares.foo-ip-allowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
# Apply the middleware named `foo-ip-allowlist` to the router named `router1`
- "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@docker"
```
```yaml tab="IngressRoute"
# As a Kubernetes Traefik IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: MiddlewareTCP
metadata:
name: foo-ip-allowlist
spec:
ipAllowList:
sourcerange:
- 127.0.0.1/32
- 192.168.1.7
---
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: ingressroute
spec:
# more fields...
routes:
# more fields...
middlewares:
- name: foo-ip-allowlist
```
```yaml tab="Consul Catalog"
# Create a middleware named `foo-ip-allowlist`
- "traefik.tcp.middlewares.foo-ip-allowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7"
# Apply the middleware named `foo-ip-allowlist` to the router named `router1`
- "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@consulcatalog"
```
```toml tab="File (TOML)"
# As TOML Configuration File
[tcp.routers]
[tcp.routers.router1]
service = "myService"
middlewares = ["foo-ip-allowlist"]
rule = "Host(`example.com`)"
[tcp.middlewares]
[tcp.middlewares.foo-ip-allowlist.ipAllowList]
sourceRange = ["127.0.0.1/32", "192.168.1.7"]
[tcp.services]
[tcp.services.service1]
[tcp.services.service1.loadBalancer]
[[tcp.services.service1.loadBalancer.servers]]
address = "10.0.0.10:4000"
[[tcp.services.service1.loadBalancer.servers]]
address = "10.0.0.11:4000"
```
```yaml tab="File (YAML)"
# As YAML Configuration File
tcp:
routers:
router1:
service: myService
middlewares:
- "foo-ip-allowlist"
rule: "Host(`example.com`)"
middlewares:
foo-ip-allowlist:
ipAllowList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
services:
service1:
loadBalancer:
servers:
- address: "10.0.0.10:4000"
- address: "10.0.0.11:4000"
```
## Available TCP Middlewares
| Middleware | Purpose | Area |
|-------------------------------------------|---------------------------------------------------|-----------------------------|
| [InFlightConn](inflightconn.md) | Limits the number of simultaneous connections. | Security, Request lifecycle |
| [IPAllowList](ipallowlist.md) | Limit the allowed client IPs. | Security, Request lifecycle |
+63 -10
View File
@@ -154,6 +154,10 @@ Final: DNS → LoadBalancer → Traefik → Your Services
```
Install Traefik with the Kubernetes Ingress NGINX provider enabled. Both controllers will serve the same Ingress resources simultaneously.
!!! warning "Read the status race condition note first"
Running both controllers against the same Ingresses creates contention on the `status.loadBalancer.ingress[]` field. Before installing, review the [Ingress Status Race Condition](#status-race) section in Step 3 and decide which mitigation to apply (disable `publishService` on Traefik, or use a transitional IngressClass).
### Add Traefik Helm Repository
```bash
@@ -166,7 +170,7 @@ helm repo update
```bash
helm upgrade --install traefik traefik/traefik \
--namespace traefik --create-namespace \
--set providers.kubernetesIngressNginx.enabled=true
--set providers.kubernetesIngressNGINX.enabled=true
```
Or using a [values file](https://github.com/traefik/traefik-helm-chart/blob/master/traefik/VALUES.md) for more configuration:
@@ -174,7 +178,7 @@ Or using a [values file](https://github.com/traefik/traefik-helm-chart/blob/mast
```yaml tab="traefik-values.yaml"
...
providers:
kubernetesIngressNginx:
kubernetesIngressNGINX:
enabled: true
...
```
@@ -279,11 +283,20 @@ echo $(kubectl get svc -n traefik traefik -o go-template='{{ $ing := index .stat
Some ISPs ignore DNS TTL values to reduce traffic costs, caching records longer than specified. After removing NGINX from DNS, keep NGINX running for at least 24-48 hours before uninstalling to avoid dropping traffic from users whose ISPs have stale DNS caches.
??? info "ExternalDNS Users"
<a id="status-race"></a>
If you use [ExternalDNS](https://github.com/kubernetes-sigs/external-dns) to automatically manage DNS records based on Ingress status, both NGINX and Traefik will compete to update the Ingress status with their LoadBalancer IPs when `publishService` is enabled. Traefik typically wins because it updates faster, which can cause unexpected traffic shifts.
!!! warning "Ingress Status Race Condition During Coexistence"
**Recommended approach for ExternalDNS:**
While both controllers manage the same Ingress resources (same `ingressClassName: nginx`), they will both attempt to write the LoadBalancer address into `status.loadBalancer.ingress[]` on every Ingress they own. Each controller overwrites the other in a tight reconciliation loop, with no error reported in the logs (just repeated `Updated ingress status` info lines on both sides).
Routing itself is not affected: both controllers correctly serve traffic during the coexistence window. The flapping status field affects anything that watches it:
- [ExternalDNS](https://github.com/kubernetes-sigs/external-dns), which may shift DNS records back and forth between the two LoadBalancer IPs.
- kube-state-metrics, monitoring dashboards, and alerting rules that observe Ingress status.
- GitOps tools such as ArgoCD or Flux, which will report a permanent drift on every affected Ingress.
- Custom operators reconciling on the Ingress status field.
**Recommended mitigation (option 1): disable status publishing on Traefik during coexistence**
1. **[Install Traefik](#step-1-install-traefik-alongside-nginx) with `publishService` disabled**:
@@ -296,9 +309,11 @@ echo $(kubectl get svc -n traefik traefik -o go-template='{{ $ing := index .stat
enabled: false # Disable to prevent status updates
```
2. **Test Traefik** using [port-forward](#step-2-verify-traefik-is-handling-traffic) or a separate test hostname
Traefik keeps serving the Ingresses normally. It only stops writing the status field, leaving NGINX as the sole writer.
3. **Switch DNS via NGINX** - Configure NGINX to publish Traefik's service address:
2. **Test Traefik** using [port-forward](#step-2-verify-traefik-is-handling-traffic) or a separate test hostname.
3. **Switch DNS via NGINX** (ExternalDNS users only). Configure NGINX to publish Traefik's service address so ExternalDNS points traffic to Traefik:
```yaml
# nginx-values.yaml
@@ -307,11 +322,13 @@ echo $(kubectl get svc -n traefik traefik -o go-template='{{ $ing := index .stat
pathOverride: "traefik/traefik" # Points to Traefik's service
```
This makes NGINX update the Ingress status with Traefik's LoadBalancer IP, causing ExternalDNS to point traffic to Traefik.
4. **Verify traffic flows through Traefik**. At this point, you can still roll back by removing the `pathOverride`.
4. **Verify traffic flows through Traefik** - At this point, you can still rollback by removing the `pathOverride`
5. **[Enable `publishService` on Traefik](#step-1-install-traefik-alongside-nginx)** and [uninstall NGINX](#step-4-uninstall-ingress-nginx-controller).
5. **[Enable `publishService` on Traefik](#step-1-install-traefik-alongside-nginx)** and [uninstall NGINX](#step-5-uninstall-nginx-ingress-controller)
**Alternative mitigation (option 2): use a transitional IngressClass**
Give the migrating NGINX a distinct IngressClass (for example `nginx-migration`) so the two controllers never own the same Ingress at the same time. This is the approach SUSE documents for RKE2 migrations: see [SUSE: Migrate from Ingress NGINX to Traefik](https://documentation.suse.com/cloudnative/rke2/latest/en/reference/ingress_migration.html). This avoids any contention on `status.loadBalancer.ingress[]` entirely, at the cost of a short traffic-cutover step instead of a progressive DNS shift.
### Option B: External Load Balancer with Weighted Traffic
@@ -443,6 +460,42 @@ kubectl get svc -n ingress-nginx ingress-nginx-controller -o go-template='{{ $in
For more details, see the [GKE LoadBalancer Service parameters documentation](https://cloud.google.com/kubernetes-engine/docs/concepts/service-load-balancer-parameters).
??? note "OVHcloud"
OVHcloud supports static IP on OVHcloud Public Load Balancer, it is based on Openstack Octavia which allocates floating IPs to LoadBalancer services. This requires the [Openstack Cloud Controller Manager](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/openstack-cloud-controller-manager/using-openstack-cloud-controller-manager.md) to be installed in your cluster. If you are using OVHcloud Managed Kubernetes Service (MKS), the Openstack Cloud Controller Manager is already installed and managed for you.
To retain your existing floating IP when migrating from NGINX to Traefik:
**Identify the existing public IP:**
```bash
NGINX_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller \
-o go-template='{{ $ing := index .status.loadBalancer.ingress 0 }}{{ if $ing.ip }}{{ $ing.ip }}{{ else }}{{ $ing.hostname }}{{ end }}')
echo "NGINX IP: $NGINX_IP"
```
**Edit your existing NGINX LoadBalancer service to ensure that the floating IP is not released when the loadbalancer service is deleted:**
kubectl annotate svc my-lb-svc loadbalancer.openstack.org/keep-floatingip=true
```
The `keep-floatingip` annotation prevents the floating IP from being released when the service is deleted or modified.
**Delete the NGINX LoadBalancer service to release the floating IP**
**Update `traefik-values.yaml`:**
```yaml
service:
type: LoadBalancer
spec:
loadBalancerIP: "<your-existing-floating-ip>"
```
To learn more, see the [OVHcloud MKS Public Load Balancer annotations documentation](https://help.ovhcloud.com/csm/en-public-cloud-kubernetes-expose-applications-using-load-balancer?id=kb_article_view&sysparm_article=KB0062878#supported-annotations-features).
??? note "Other Cloud Providers"
- **DigitalOcean:** Supports `loadBalancerIP` with floating IPs
+1 -1
View File
@@ -17,7 +17,7 @@ For more information about the changes in Traefik v2, please refer to the [v2 do
We created a tool to help during the migration: [traefik-migration-tool](https://github.com/traefik/traefik-migration-tool)
This tool allows to:
This tool lets you:
- convert `Ingress` to Traefik `IngressRoute` resources.
- convert `acme.json` file from v1 to v2 format.
+67 -29
View File
@@ -78,7 +78,7 @@ Docker provider `tls.CAOptional` option has been removed in v3, as TLS client au
##### Remediation
The `tls.caOptional` option should be removed from the Docker provider static configuration.
The `tls.caOptional` option should be removed from the Docker provider install configuration.
### Kubernetes Gateway API
@@ -134,8 +134,8 @@ It is now unsupported and would prevent Traefik to start.
##### Remediation
The `http3` option should be removed from the static configuration experimental section.
To configure `http3`, please checkout the [entrypoint configuration documentation](../reference/install-configuration/entrypoints.md#http3).
The `http3` option should be removed from the install configuration experimental section.
To configure `http3`, please checkout the [entrypoint configuration documentation](../reference/install-configuration/entrypoints.md#opt-http3).
### Consul provider
@@ -205,7 +205,7 @@ Consul provider `tls.CAOptional` option has been removed in v3, as TLS client au
##### Remediation
The `tls.caOptional` option should be removed from the Consul provider static configuration.
The `tls.caOptional` option should be removed from the Consul provider install configuration.
### ConsulCatalog provider
@@ -276,7 +276,7 @@ ConsulCatalog provider `endpoint.tls.CAOptional` option has been removed in v3,
##### Remediation
The `endpoint.tls.caOptional` option should be removed from the ConsulCatalog provider static configuration.
The `endpoint.tls.caOptional` option should be removed from the ConsulCatalog provider install configuration.
### Nomad provider
@@ -347,7 +347,7 @@ Nomad provider `endpoint.tls.CAOptional` option has been removed in v3, as TLS c
##### Remediation
The `endpoint.tls.caOptional` option should be removed from the Nomad provider static configuration.
The `endpoint.tls.caOptional` option should be removed from the Nomad provider install configuration.
### Rancher v1 Provider
@@ -374,9 +374,9 @@ This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query.
As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](../providers/kubernetes-crd.md) directly.
As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) directly.
Also, all Rancher provider related configuration should be removed from the static configuration.
Also, all Rancher provider related configuration should be removed from the install configuration.
### Marathon provider
@@ -402,7 +402,7 @@ This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
All Marathon provider related configuration should be removed from the static configuration.
All Marathon provider related configuration should be removed from the install configuration.
### HTTP Provider
@@ -430,7 +430,7 @@ HTTP provider `tls.CAOptional` option has been removed in v3, as TLS client auth
##### Remediation
The `tls.caOptional` option should be removed from the HTTP provider static configuration.
The `tls.caOptional` option should be removed from the HTTP provider install configuration.
### ETCD Provider
@@ -458,7 +458,7 @@ ETCD provider `tls.CAOptional` option has been removed in v3, as TLS client auth
##### Remediation
The `tls.caOptional` option should be removed from the ETCD provider static configuration.
The `tls.caOptional` option should be removed from the ETCD provider install configuration.
### Redis Provider
@@ -486,7 +486,7 @@ Redis provider `tls.CAOptional` option has been removed in v3, as TLS client aut
##### Remediation
The `tls.caOptional` option should be removed from the Redis provider static configuration.
The `tls.caOptional` option should be removed from the Redis provider install configuration.
### InfluxDB v1
@@ -512,7 +512,7 @@ This configuration is now unsupported and would prevent Traefik to start.
#### Remediation
All InfluxDB v1 metrics provider related configuration should be removed from the static configuration.
All InfluxDB v1 metrics provider related configuration should be removed from the install configuration.
### Pilot
@@ -539,7 +539,7 @@ it is now unsupported and would prevent Traefik to start.
#### Remediation
All Pilot related configuration should be removed from the static configuration.
All Pilot related configuration should be removed from the install configuration.
### Kubernetes Ingress Path Matching
@@ -550,16 +550,16 @@ In v3, the Kubernetes Ingress default path matching does not support regexes any
Two levels of remediation are possible:
- Interpret the default path matcher `PathPrefix` with v2 syntax.
This can done globally for all routers with the [static configuration](#configure-the-default-syntax-in-static-configuration) or on a per-router basis by using the [traefik.ingress.kubernetes.io/router.rulesyntax](../routing/providers/kubernetes-ingress.md#annotations) annotation.
This can done globally for all routers with the [install configuration](#configure-the-default-syntax-in-install-configuration) or on a per-router basis by using the [traefik.ingress.kubernetes.io/router.rulesyntax](../reference/routing-configuration/kubernetes/ingress.md#annotations) annotation.
- Adapt the path regex to be compatible with the Go regex syntax and change the default path matcher to use the `PathRegexp` matcher with the [`traefik.ingress.kubernetes.io/router.pathmatcher`](../routing/providers/kubernetes-ingress.md#annotations) annotation.
- Adapt the path regex to be compatible with the Go regex syntax and change the default path matcher to use the `PathRegexp` matcher with the [`traefik.ingress.kubernetes.io/router.pathmatcher`](../reference/routing-configuration/kubernetes/ingress.md#annotations) annotation.
## Operations Changes
### Traefik RBAC Update
In v3, the support of `TCPServersTransport` has been introduced.
When using the KubernetesCRD provider, it is therefore necessary to update [RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) and [CRD](../reference/dynamic-configuration/kubernetes-crd.md) manifests.
When using the KubernetesCRD provider, it is therefore necessary to update RBAC and CRDs ([See requirements](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md#requirements)).
### Content-Type Auto-Detection
@@ -602,7 +602,7 @@ Here are two possible transition strategies:
using OpenTelemetry (OTel) collectors with appropriate exporters configuration is a viable solution.
This allows continued compatibility with the existing infrastructure.
Please check the [OpenTelemetry Tracing provider documention](../observability/tracing/opentelemetry.md) for more information.
Please check the [OpenTelemetry Tracing provider documentation](../reference/install-configuration/observability/tracing.md) for more information.
#### Internal Resources Observability
@@ -610,9 +610,9 @@ In v3, observability for internal routers or services (e.g.: `ping@internal`) is
To enable it one should use the new `addInternals` option for AccessLogs, Metrics or Tracing.
Please take a look at the observability documentation for more information:
- [AccessLogs](../observability/access-logs.md#addinternals)
- [Metrics](../observability/metrics/overview.md#addinternals)
- [Tracing](../observability/tracing/overview.md#addinternals)
- [AccessLogs](../reference/install-configuration/observability/logs-and-accesslogs.md#accesslogs)
- [Metrics](../reference/install-configuration/observability/metrics.md)
- [Tracing](../reference/install-configuration/observability/tracing.md)
#### Access logs
@@ -628,7 +628,7 @@ The default rule matchers syntax is now the v3 one, but for backward compatibili
The v2 rule matchers syntax is deprecated and its support will be removed in the next major version.
For this reason, we encourage migrating to the new syntax.
By default, the `defaultRuleSyntax` static option is automatically set to `v3`, meaning that the default rule is the new one.
By default, the `defaultRuleSyntax` install option is automatically set to `v3`, meaning that the default rule is the new one.
#### New V3 Syntax Notable Changes
@@ -636,6 +636,10 @@ The `Headers` and `HeadersRegexp` matchers have been renamed to `Header` and `He
`PathPrefix` no longer uses regular expressions to match path prefixes.
`Path` and `PathPrefix` no longer support path parameter placeholders (e.g., `{id}`, `{name}`).
Routes using placeholders like ``Path(`/route/{id}`)`` will not match in v3 syntax.
Use `PathRegexp` instead for dynamic path segments.
`QueryRegexp` has been introduced to match query values using a regular expression.
`HeaderRegexp`, `HostRegexp`, `PathRegexp`, `QueryRegexp`, and `HostSNIRegexp` matchers now uses the [Go regexp syntax](https://golang.org/pkg/regexp/syntax/).
@@ -649,34 +653,34 @@ and should be explicitly combined using logical operators to mimic previous beha
#### Remediation
##### Configure the Default Syntax In Static Configuration
##### Configure the Default Syntax In Install Configuration
The default rule matchers syntax is the expected syntax for any router that is not self opt-out from this default value.
It can be configured in the static configuration.
It can be configured in the install configuration.
??? example "An example configuration for the default rule matchers syntax"
```yaml tab="File (YAML)"
# static configuration
# install configuration
core:
defaultRuleSyntax: v2
```
```toml tab="File (TOML)"
# static configuration
# install configuration
[core]
defaultRuleSyntax="v2"
```
```bash tab="CLI"
# static configuration
# install configuration
--core.defaultRuleSyntax=v2
```
##### Configure the Syntax Per Router
The rule syntax can also be configured on a per-router basis.
This allows to have heterogeneous router configurations and ease migration.
This allows you to have heterogeneous router configurations and ease migration.
??? example "An example router with syntax configuration"
@@ -716,6 +720,40 @@ http:
ruleSyntax = "v2"
```
##### Migrate Path Placeholders to PathRegexp
In v2, `Path` and `PathPrefix` supported path parameter placeholders like `{id}` for matching dynamic path segments.
In v3, this is no longer supported and `PathRegexp` should be used instead.
??? example "Migrating a route with path placeholders"
v2 syntax (no longer works in v3):
```yaml
match: Host(`example.com`) && Path(`/products/{id}`)
```
v3 syntax using `PathRegexp`:
```yaml
match: Host(`example.com`) && PathRegexp(`^/products/[^/]+$`)
```
For more complex patterns with multiple placeholders:
v2 syntax:
```yaml
match: Host(`example.com`) && Path(`/users/{userId}/orders/{orderId}`)
```
v3 syntax:
```yaml
match: Host(`example.com`) && PathRegexp(`^/users/[^/]+/orders/[^/]+$`) ## matches any non-slash characters
match: Host(`example.com`) && PathRegexp(`^/users/[a-zA-Z0-9_-]+/orders/[a-zA-Z0-9_-]+$`) ## restricts to alphanumeric, hyphens, and underscores
```
### IPWhiteList
In v3, we renamed the `IPWhiteList` middleware to `IPAllowList` without changing anything to the configuration.
@@ -731,7 +769,7 @@ In v3, we renamed the `IPWhiteList` middleware to `IPAllowList` without changing
### TCP LoadBalancer `terminationDelay` option
The TCP LoadBalancer `terminationDelay` option has been deprecated.
This option can now be configured directly on the `TCPServersTransport` level, please take a look at this [documentation](../routing/services/index.md#terminationdelay)
This option can now be configured directly on the `TCPServersTransport` level, please take a look at this [documentation](../reference/routing-configuration/tcp/serverstransport.md#opt-serverstransport-terminationDelay)
### Kubernetes CRDs API Group `traefik.containo.us`
+13 -13
View File
@@ -9,9 +9,9 @@ How to Migrate from Traefik v2 to Traefik v3.
{: .subtitle }
!!! success "Streamlined Migration Process"
Traefik v3 introduces minimal breaking changes and maintains backward compatibility with v2 syntax in dynamic configuration, offering a gradual migration path.
Traefik v3 introduces minimal breaking changes and maintains backward compatibility with v2 syntax in routing configuration, offering a gradual migration path.
With Traefik v3, we are introducing a streamlined transition process from v2. Minimal breaking changes have been made to specific options in the [static configuration](./v2-to-v3-details.md#install-configuration-changes "Link to install configuration changes"), and we are ensuring backward compatibility with v2 syntax in the [dynamic configuration](./v2-to-v3-details.md#routing-configuration-changes "Link to routing configuration changes"). This will offer a gradual path for adopting the v3 syntax, allowing users to progressively migrate their Kubernetes ingress resources, Docker labels, etc., to the new format.
With Traefik v3, we are introducing a streamlined transition process from v2. Minimal breaking changes have been made to specific options in the [install configuration](./v2-to-v3-details.md#install-configuration-changes "Link to install configuration changes"), and we are ensuring backward compatibility with v2 syntax in the [routing configuration](./v2-to-v3-details.md#routing-configuration-changes "Link to routing configuration changes"). This will offer a gradual path for adopting the v3 syntax, allowing users to progressively migrate their Kubernetes ingress resources, Docker labels, etc., to the new format.
## Migration Overview
@@ -20,33 +20,33 @@ The migration process consists of three progressive steps designed to minimize r
!!! abstract "Migration Steps"
**Step 1:** [Prepare configurations and test v3](#step-1-prepare-configurations-and-test-v3)
**Step 2:** [Migrate production instances to Traefik v3](#step-2-migrate-production-instances-to-traefik-v3)
**Step 3:** [Progressively migrate dynamic configuration](#step-3-progressively-migrate-dynamic-configuration)
**Step 3:** [Progressively migrate routing configuration](#step-3-progressively-migrate-routing-configuration)
---
## Step 1: Prepare Configurations and Test v3
!!! info "Preparation Phase"
This step focuses on updating static configurations and enabling backward compatibility for a safe testing environment.
This step focuses on updating install configurations and enabling backward compatibility for a safe testing environment.
### Configuration Updates
**Review and Update Static Configuration**
**Review and Update install Configuration**
Check the changes in [static configurations](./v2-to-v3-details.md#install-configuration-changes "Link to install configuration changes") and [operations](./v2-to-v3-details.md#operations-changes "Link to operations changes") brought by Traefik v3. Modify your configurations accordingly.
Check the changes in [install configurations](./v2-to-v3-details.md#install-configuration-changes "Link to install configuration changes") and [operations](./v2-to-v3-details.md#operations-changes "Link to operations changes") brought by Traefik v3. Modify your configurations accordingly.
**Enable v2 Compatibility Mode**
Add the following configuration to maintain v2 syntax compatibility:
```yaml
# static configuration
# install configuration
core:
defaultRuleSyntax: v2
```
!!! note "Backward Compatibility"
This snippet in the static configuration makes the [v2 format](../migrate/v2-to-v3-details.md#configure-the-default-syntax-in-static-configuration "Link to configure default syntax in static config") the default rule matchers syntax.
This snippet in the install configuration makes the [v2 format](./v2-to-v3-details.md#configure-the-default-syntax-in-install-configuration "Link to configure default syntax in install config") the default rule matchers syntax.
### Testing Phase
@@ -107,16 +107,16 @@ We strongly advise you to follow a progressive migration strategy ([Kubernetes r
---
## Step 3: Progressively Migrate Dynamic Configuration
## Step 3: Progressively Migrate Routing Configuration
!!! info "Optional Immediate Step"
This step can be done later in the process, as Traefik v3 is compatible with the v2 format for [dynamic configuration](./v2-to-v3-details.md#routing-configuration-changes "Link to routing configuration changes"). Enable Traefik logs to get some help if any deprecated option is in use.
This step can be done later in the process, as Traefik v3 is compatible with the v2 format for [routing configuration](./v2-to-v3-details.md#routing-configuration-changes "Link to routing configuration changes"). Enable Traefik logs to get some help if any deprecated option is in use.
### Migration Process
**Review Dynamic Configuration Changes**
**Review Routing Configuration Changes**
Check the changes in [dynamic configuration](./v2-to-v3-details.md#routing-configuration-changes "Link to routing configuration changes") to understand what updates are needed.
Check the changes in [routing configuration](./v2-to-v3-details.md#routing-configuration-changes "Link to routing configuration changes") to understand what updates are needed.
**Progressive Router Migration**
@@ -140,7 +140,7 @@ Check the changes in [dynamic configuration](./v2-to-v3-details.md#routing-confi
Once all Ingress resources are migrated to v3 syntax, remove the compatibility configuration:
```yaml
# Remove this from static configuration
# Remove this from install configuration
core:
defaultRuleSyntax: v2 # ← Delete this entire section
```
+497 -348
View File
File diff suppressed because it is too large Load Diff
-783
View File
@@ -1,783 +0,0 @@
---
title: "Traefik Access Logs Documentation"
description: "Access logs are a key part of observability in Traefik Proxy. Read the technical documentation to learn their configurations, rotations, and time zones."
---
# Access Logs
Who Calls Whom?
{.subtitle}
By default, logs are written to stdout, in text format.
## Configuration
To enable the access logs:
```yaml tab="File (YAML)"
accessLog: {}
```
```toml tab="File (TOML)"
[accessLog]
```
```bash tab="CLI"
--accesslog=true
```
### `addInternals`
_Optional, Default="false"_
Enables access logs for internal resources (e.g.: `ping@internal`).
```yaml tab="File (YAML)"
accesslog:
addInternals: true
```
```toml tab="File (TOML)"
[accesslog]
addInternals = true
```
```bash tab="CLI"
--accesslog.addinternals
```
### `filePath`
By default access logs are written to the standard output.
To write the logs into a log file, use the `filePath` option.
```yaml tab="File (YAML)"
accessLog:
filePath: "/path/to/access.log"
```
```toml tab="File (TOML)"
[accessLog]
filePath = "/path/to/access.log"
```
```bash tab="CLI"
--accesslog.filepath=/path/to/access.log
```
### `format`
_Optional, Default="common"_
By default, logs are written using the Traefik Common Log Format (CLF).
The available log formats are:
- `common` - Traefik's extended CLF format (default)
- `genericCLF` - Generic CLF format compatible with standard log analyzers
- `json` - JSON format for structured logging
If the given format is unsupported, the default (`common`) is used instead.
!!! info "Traefik Common Log Format vs Generic CLF"
**Traefik Common Log Format (`common`):**
```html
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <HTTP_status> <content-length> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_router_name>" "<Traefik_server_URL>" <request_duration_in_ms>ms
```
**Generic CLF Format (`genericCLF`):**
```html
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <HTTP_status> <content-length> "<request_referrer>" "<request_user_agent>"
```
The `genericCLF` format omits Traefik-specific fields (request count, router name, service URL, and duration) for better compatibility with standard CLF parsers.
```yaml tab="File (YAML)"
# JSON format
accessLog:
format: "json"
```
```toml tab="File (TOML)"
# JSON format
[accessLog]
format = "json"
```
```bash tab="CLI"
# JSON format
--accesslog.format=json
```
### `bufferingSize`
To write the logs in an asynchronous fashion, specify a `bufferingSize` option.
This option represents the number of log lines Traefik will keep in memory before writing them to the selected output.
In some cases, this option can greatly help performances.
```yaml tab="File (YAML)"
# Configuring a buffer of 100 lines
accessLog:
filePath: "/path/to/access.log"
bufferingSize: 100
```
```toml tab="File (TOML)"
# Configuring a buffer of 100 lines
[accessLog]
filePath = "/path/to/access.log"
bufferingSize = 100
```
```bash tab="CLI"
# Configuring a buffer of 100 lines
--accesslog.filepath=/path/to/access.log
--accesslog.bufferingsize=100
```
### Filtering
To filter logs, you can specify a set of filters which are logically "OR-connected".
Thus, specifying multiple filters will keep more access logs than specifying only one.
The available filters are:
- `statusCodes`, to limit the access logs to requests with a status codes in the specified range
- `retryAttempts`, to keep the access logs when at least one retry has happened
- `minDuration`, to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format, see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration))
```yaml tab="File (YAML)"
# Configuring Multiple Filters
accessLog:
filePath: "/path/to/access.log"
format: json
filters:
statusCodes:
- "200"
- "300-302"
retryAttempts: true
minDuration: "10ms"
```
```toml tab="File (TOML)"
# Configuring Multiple Filters
[accessLog]
filePath = "/path/to/access.log"
format = "json"
[accessLog.filters]
statusCodes = ["200", "300-302"]
retryAttempts = true
minDuration = "10ms"
```
```bash tab="CLI"
# Configuring Multiple Filters
--accesslog.filepath=/path/to/access.log
--accesslog.format=json
--accesslog.filters.statuscodes=200,300-302
--accesslog.filters.retryattempts
--accesslog.filters.minduration=10ms
```
### Limiting the Fields/Including Headers
You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.headers` options.
Each field can be set to:
- `keep` to keep the value
- `drop` to drop the value
Header fields may also optionally be set to `redact` to replace the value with "REDACTED".
The `defaultMode` for `fields.names` is `keep`.
The `defaultMode` for `fields.headers` is `drop`.
```yaml tab="File (YAML)"
# Limiting the Logs to Specific Fields
accessLog:
filePath: "/path/to/access.log"
format: json
fields:
defaultMode: keep
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Authorization: drop
Content-Type: keep
```
```toml tab="File (TOML)"
# Limiting the Logs to Specific Fields
[accessLog]
filePath = "/path/to/access.log"
format = "json"
[accessLog.fields]
defaultMode = "keep"
[accessLog.fields.names]
"ClientUsername" = "drop"
[accessLog.fields.headers]
defaultMode = "keep"
[accessLog.fields.headers.names]
"User-Agent" = "redact"
"Authorization" = "drop"
"Content-Type" = "keep"
```
```bash tab="CLI"
# Limiting the Logs to Specific Fields
--accesslog.filepath=/path/to/access.log
--accesslog.format=json
--accesslog.fields.defaultmode=keep
--accesslog.fields.names.ClientUsername=drop
--accesslog.fields.headers.defaultmode=keep
--accesslog.fields.headers.names.User-Agent=redact
--accesslog.fields.headers.names.Authorization=drop
--accesslog.fields.headers.names.Content-Type=keep
```
??? info "Available Fields"
| Field | Description |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `StartUTC` | The time at which request processing started. |
| `StartLocal` | The local time at which request processing started. |
| `Duration` | The total time taken (in nanoseconds) by processing the response, including the origin server's time but not the log writing time. |
| `RouterName` | The name of the Traefik router. |
| `ServiceName` | The name of the Traefik backend. |
| `ServiceURL` | The URL of the Traefik backend. |
| `ServiceAddr` | The IP:port of the Traefik backend (extracted from `ServiceURL`) |
| `ClientAddr` | The remote address in its original form (usually IP:port). |
| `ClientHost` | The remote IP address from which the client request was received. |
| `ClientPort` | The remote TCP port from which the client request was received. |
| `ClientUsername` | The username provided in the URL, if present. |
| `RequestAddr` | The HTTP Host header (usually IP:port). This is treated as not a header by the Go API. |
| `RequestHost` | The HTTP Host server name (not including port). |
| `RequestPort` | The TCP port from the HTTP Host. |
| `RequestMethod` | The HTTP method. |
| `RequestPath` | The HTTP request URI, not including the scheme, host or port. |
| `RequestProtocol` | The version of HTTP requested. |
| `RequestScheme` | The HTTP scheme requested `http` or `https`. |
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
| `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. |
| `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. |
| `OriginContentSize` | The content length specified by the origin server, or 0 if unspecified. |
| `OriginStatus` | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent (0). |
| `DownstreamStatus` | The HTTP status code returned to the client. |
| `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. |
| `RequestCount` | The number of requests received since the Traefik instance started. |
| `GzipRatio` | The response body compression ratio achieved. |
| `Overhead` | The processing time overhead (in nanoseconds) caused by Traefik. |
| `RetryAttempts` | The amount of attempts the request was retried. |
| `TLSVersion` | The TLS version used by the connection (e.g. `1.2`) (if connection is TLS). |
| `TLSCipher` | The TLS cipher used by the connection (e.g. `TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA`) (if connection is TLS) |
| `TLSClientSubject` | The string representation of the TLS client certificate's Subject (e.g. `CN=username,O=organization`) |
| `TraceId` | A consistent identifier for tracking requests across services, including upstream ones managed by Traefik, shown as a 32-hex digit string |
| `SpanId` | A unique identifier for Traefiks root span (EntryPoint) within a request trace, formatted as a 16-hex digit string. |
## Log Rotation
Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal.
This allows the logs to be rotated and processed by an external program, such as `logrotate`.
!!! warning
This does not work on Windows due to the lack of USR signals.
## Time Zones
Traefik will timestamp each log line in UTC time by default.
It is possible to configure the Traefik to timestamp in a specific timezone by ensuring the following configuration has been made in your environment:
1. Provide time zone data to `/etc/localtime` or `/usr/share/zoneinfo` (based on your distribution) or set the environment variable TZ to the desired timezone
2. Specify the field `StartLocal` by dropping the field named `StartUTC` (available on the default Common Log Format (CLF) as well as JSON)
Example utilizing Docker Compose:
```yaml
services:
traefik:
image: traefik:v3.6
environment:
- TZ=US/Alaska
command:
- --accesslog.fields.names.StartUTC=drop
- --providers.docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
## OpenTelemetry
!!! warning "Experimental Feature"
The OpenTelemetry access logs feature is currently experimental and must be explicitly enabled in the experimental section prior to use.
```yaml tab="File (YAML)"
experimental:
otlpLogs: true
```
```toml tab="File (TOML)"
[experimental.otlpLogs]
```
```bash tab="CLI"
--experimental.otlpLogs=true
```
To enable the OpenTelemetry Logger for access logs:
```yaml tab="File (YAML)"
accesslog:
otlp: {}
```
```toml tab="File (TOML)"
[accesslog.otlp]
```
```bash tab="CLI"
--accesslog.otlp=true
```
!!! info "Default protocol"
The OpenTelemetry Logger exporter will export access logs to the collector using HTTPS by default to https://localhost:4318/v1/logs, see the [gRPC Section](#grpc-configuration) to use gRPC.
### `serviceName`
_Optional, Default="traefik"_
Defines the service name resource attribute.
```yaml tab="File (YAML)"
accesslog:
otlp:
serviceName: name
```
```toml tab="File (TOML)"
[accesslog]
[accesslog.otlp]
serviceName = "name"
```
```bash tab="CLI"
--accesslog.otlp.serviceName=name
```
### `resourceAttributes`
_Optional, Default=empty_
Defines additional resource attributes to be sent to the collector.
```yaml tab="File (YAML)"
accesslog:
otlp:
resourceAttributes:
attr1: foo
attr2: bar
```
```toml tab="File (TOML)"
[accesslog]
[accesslog.otlp.resourceAttributes]
attr1 = "foo"
attr2 = "bar"
```
```bash tab="CLI"
--accesslog.otlp.resourceAttributes.attr1=foo
--accesslog.otlp.resourceAttributes.attr2=bar
```
### HTTP configuration
_Optional_
This instructs the exporter to send access logs to the OpenTelemetry Collector using HTTP.
```yaml tab="File (YAML)"
accesslog:
otlp:
http: {}
```
```toml tab="File (TOML)"
[accesslog.otlp.http]
```
```bash tab="CLI"
--accesslog.otlp.http=true
```
#### `endpoint`
_Optional, Default="`https://localhost:4318/v1/logs`", Format="`<scheme>://<host>:<port><path>`"_
URL of the OpenTelemetry Collector to send access logs to.
!!! info "Insecure mode"
To disable TLS, use `http://` instead of `https://` in the `endpoint` configuration.
```yaml tab="File (YAML)"
accesslog:
otlp:
http:
endpoint: https://collector:4318/v1/logs
```
```toml tab="File (TOML)"
[accesslog.otlp.http]
endpoint = "https://collector:4318/v1/logs"
```
```bash tab="CLI"
--accesslog.otlp.http.endpoint=https://collector:4318/v1/logs
```
#### `headers`
_Optional, Default={}_
Additional headers sent with access logs by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
accesslog:
otlp:
http:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[accesslog.otlp.http.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--accesslog.otlp.http.headers.foo=bar --accesslog.otlp.http.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
accesslog:
otlp:
http:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[accesslog.otlp.http.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--accesslog.otlp.http.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
accesslog:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[accesslog.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--accesslog.otlp.http.tls.cert=path/to/foo.cert
--accesslog.otlp.http.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
accesslog:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[accesslog.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--accesslog.otlp.http.tls.cert=path/to/foo.cert
--accesslog.otlp.http.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
accesslog:
otlp:
http:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[accesslog.otlp.http.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--accesslog.otlp.http.tls.insecureSkipVerify=true
```
### gRPC configuration
_Optional_
This instructs the exporter to send access logs to the OpenTelemetry Collector using gRPC.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc: {}
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc]
```
```bash tab="CLI"
--accesslog.otlp.grpc=true
```
#### `endpoint`
_Required, Default="localhost:4317", Format="`<host>:<port>`"_
Address of the OpenTelemetry Collector to send access logs to.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
endpoint: localhost:4317
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc]
endpoint = "localhost:4317"
```
```bash tab="CLI"
--accesslog.otlp.grpc.endpoint=localhost:4317
```
#### `insecure`
_Optional, Default=false_
Allows exporter to send access logs to the OpenTelemetry Collector without using a secured protocol.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
insecure: true
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc]
insecure = true
```
```bash tab="CLI"
--accesslog.otlp.grpc.insecure=true
```
#### `headers`
_Optional, Default={}_
Additional headers sent with access logs by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--accesslog.otlp.grpc.headers.foo=bar --accesslog.otlp.grpc.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--accesslog.otlp.grpc.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--accesslog.otlp.grpc.tls.cert=path/to/foo.cert
--accesslog.otlp.grpc.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--accesslog.otlp.grpc.tls.cert=path/to/foo.cert
--accesslog.otlp.grpc.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
accesslog:
otlp:
grpc:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[accesslog.otlp.grpc.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--accesslog.otlp.grpc.tls.insecureSkipVerify=true
```
{% include-markdown "includes/traefik-for-business-applications.md" %}
-647
View File
@@ -1,647 +0,0 @@
---
title: "Traefik Logs Documentation"
description: "Logs are a key part of observability in Traefik Proxy. Read the technical documentation to learn their configurations, rotations, and time zones."
---
# Logs
Reading What's Happening
{: .subtitle }
By default, logs are written to stdout, in text format.
## Configuration
### General
Traefik logs concern everything that happens to Traefik itself (startup, configuration, events, shutdown, and so on).
#### `filePath`
By default, the logs are written to the standard output.
You can configure a file path instead using the `filePath` option.
When `filePath` is specified, Traefik will write logs only to that file (not to standard output).
```yaml tab="File (YAML)"
# Writing Logs to a File
log:
filePath: "/path/to/traefik.log"
```
```toml tab="File (TOML)"
# Writing Logs to a File
[log]
filePath = "/path/to/traefik.log"
```
```bash tab="CLI"
# Writing Logs to a File
--log.filePath=/path/to/traefik.log
```
#### `format`
By default, the logs use a text format (`common`), but you can also ask for the `json` format in the `format` option.
```yaml tab="File (YAML)"
# Writing Logs to a File, in JSON
log:
filePath: "/path/to/log-file.log"
format: json
```
```toml tab="File (TOML)"
# Writing Logs to a File, in JSON
[log]
filePath = "/path/to/log-file.log"
format = "json"
```
```bash tab="CLI"
# Writing Logs to a File, in JSON
--log.filePath=/path/to/traefik.log
--log.format=json
```
#### `level`
By default, the `level` is set to `ERROR`.
Alternative logging levels are `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, and `PANIC`.
```yaml tab="File (YAML)"
log:
level: DEBUG
```
```toml tab="File (TOML)"
[log]
level = "DEBUG"
```
```bash tab="CLI"
--log.level=DEBUG
```
#### `noColor`
When using the 'common' format, disables the colorized output.
```yaml tab="File (YAML)"
log:
noColor: true
```
```toml tab="File (TOML)"
[log]
noColor = true
```
```bash tab="CLI"
--log.nocolor=true
```
## Log Rotation
The rotation of the log files can be configured with the following options.
### `maxSize`
`maxSize` is the maximum size in megabytes of the log file before it gets rotated.
It defaults to 100 megabytes.
```yaml tab="File (YAML)"
log:
maxSize: 1
```
```toml tab="File (TOML)"
[log]
maxSize = 1
```
```bash tab="CLI"
--log.maxsize=1
```
### `maxBackups`
`maxBackups` is the maximum number of old log files to retain.
The default is to retain all old log files (though `maxAge` may still cause them to get deleted).
```yaml tab="File (YAML)"
log:
maxBackups: 3
```
```toml tab="File (TOML)"
[log]
maxBackups = 3
```
```bash tab="CLI"
--log.maxbackups=3
```
### `maxAge`
`maxAge` is the maximum number of days to retain old log files based on the timestamp encoded in their filename.
Note that a day is defined as 24 hours and may not exactly correspond to calendar days due to daylight savings, leap seconds, etc.
The default is not to remove old log files based on age.
```yaml tab="File (YAML)"
log:
maxAge: 3
```
```toml tab="File (TOML)"
[log]
maxAge = 3
```
```bash tab="CLI"
--log.maxage=3
```
### `compress`
`compress` determines if the rotated log files should be compressed using gzip.
The default is not to perform compression.
```yaml tab="File (YAML)"
log:
compress: true
```
```toml tab="File (TOML)"
[log]
compress = true
```
```bash tab="CLI"
--log.compress=true
```
## OpenTelemetry
!!! warning "Experimental Feature"
The OpenTelemetry logs feature is currently experimental and must be explicitly enabled in the experimental section prior to use.
```yaml tab="File (YAML)"
experimental:
otlpLogs: true
```
```toml tab="File (TOML)"
[experimental.otlpLogs]
```
```bash tab="CLI"
--experimental.otlpLogs=true
```
To enable the OpenTelemetry Logger for logs:
```yaml tab="File (YAML)"
log:
otlp: {}
```
```toml tab="File (TOML)"
[log.otlp]
```
```bash tab="CLI"
--log.otlp=true
```
!!! info "Default protocol"
The OpenTelemetry Logger exporter will export logs to the collector using HTTPS by default to https://localhost:4318/v1/logs, see the [gRPC Section](#grpc-configuration) to use gRPC.
### `serviceName`
_Optional, Default="traefik"_
Defines the service name resource attribute.
```yaml tab="File (YAML)"
log:
otlp:
serviceName: name
```
```toml tab="File (TOML)"
[log]
[log.otlp]
serviceName = "name"
```
```bash tab="CLI"
--log.otlp.serviceName=name
```
### `resourceAttributes`
_Optional, Default=empty_
Defines additional resource attributes to be sent to the collector.
```yaml tab="File (YAML)"
log:
otlp:
resourceAttributes:
attr1: foo
attr2: bar
```
```toml tab="File (TOML)"
[log]
[log.otlp.resourceAttributes]
attr1 = "foo"
attr2 = "bar"
```
```bash tab="CLI"
--log.otlp.resourceAttributes.attr1=foo
--log.otlp.resourceAttributes.attr2=bar
```
### HTTP configuration
_Optional_
This instructs the exporter to send logs to the OpenTelemetry Collector using HTTP.
```yaml tab="File (YAML)"
log:
otlp:
http: {}
```
```toml tab="File (TOML)"
[log.otlp.http]
```
```bash tab="CLI"
--log.otlp.http=true
```
#### `endpoint`
_Optional, Default="`https://localhost:4318/v1/logs`", Format="`<scheme>://<host>:<port><path>`"_
URL of the OpenTelemetry Collector to send logs to.
!!! info "Insecure mode"
To disable TLS, use `http://` instead of `https://` in the `endpoint` configuration.
```yaml tab="File (YAML)"
log:
otlp:
http:
endpoint: https://collector:4318/v1/logs
```
```toml tab="File (TOML)"
[log.otlp.http]
endpoint = "https://collector:4318/v1/logs"
```
```bash tab="CLI"
--log.otlp.http.endpoint=https://collector:4318/v1/logs
```
#### `headers`
_Optional, Default={}_
Additional headers sent with logs by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
log:
otlp:
http:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[log.otlp.http.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--log.otlp.http.headers.foo=bar --log.otlp.http.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
log:
otlp:
http:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[log.otlp.http.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--log.otlp.http.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
log:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[log.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--log.otlp.http.tls.cert=path/to/foo.cert
--log.otlp.http.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
log:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[log.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--log.otlp.http.tls.cert=path/to/foo.cert
--log.otlp.http.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
log:
otlp:
http:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[log.otlp.http.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--log.otlp.http.tls.insecureSkipVerify=true
```
### gRPC configuration
_Optional_
This instructs the exporter to send logs to the OpenTelemetry Collector using gRPC.
```yaml tab="File (YAML)"
log:
otlp:
grpc: {}
```
```toml tab="File (TOML)"
[log.otlp.grpc]
```
```bash tab="CLI"
--log.otlp.grpc=true
```
#### `endpoint`
_Required, Default="localhost:4317", Format="`<host>:<port>`"_
Address of the OpenTelemetry Collector to send logs to.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
endpoint: localhost:4317
```
```toml tab="File (TOML)"
[log.otlp.grpc]
endpoint = "localhost:4317"
```
```bash tab="CLI"
--log.otlp.grpc.endpoint=localhost:4317
```
#### `insecure`
_Optional, Default=false_
Allows exporter to send logs to the OpenTelemetry Collector without using a secured protocol.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
insecure: true
```
```toml tab="File (TOML)"
[log.otlp.grpc]
insecure = true
```
```bash tab="CLI"
--log.otlp.grpc.insecure=true
```
#### `headers`
_Optional, Default={}_
Additional headers sent with logs by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[log.otlp.grpc.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--log.otlp.grpc.headers.foo=bar --log.otlp.grpc.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[log.otlp.grpc.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--log.otlp.grpc.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[log.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--log.otlp.grpc.tls.cert=path/to/foo.cert
--log.otlp.grpc.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[log.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--log.otlp.grpc.tls.cert=path/to/foo.cert
--log.otlp.grpc.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
log:
otlp:
grpc:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[log.otlp.grpc.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--log.otlp.grpc.tls.insecureSkipVerify=true
```
{% include-markdown "includes/traefik-for-business-applications.md" %}
@@ -1,158 +0,0 @@
---
title: "Traefik Datadog Metrics Documentation"
description: "Traefik Proxy supports Datadog for backend metrics. Read the technical documentation to enable Datadog for observability."
---
# Datadog
To enable the Datadog:
```yaml tab="File (YAML)"
metrics:
datadog: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
```
```bash tab="CLI"
--metrics.datadog=true
```
#### `address`
_Required, Default="127.0.0.1:8125"_
Address instructs exporter to send metrics to datadog-agent at this address.
This address can be a Unix Domain Socket (UDS) in the following format: `unix:///path/to/datadog.socket`.
When the prefix is set to `unix`, the socket type will be automatically determined.
To explicitly define the socket type and avoid automatic detection, you can use the prefixes `unixgram` for `SOCK_DGRAM` (datagram sockets) and `unixstream` for `SOCK_STREAM` (stream sockets), respectively.
```yaml tab="File (YAML)"
metrics:
datadog:
address: 127.0.0.1:8125
```
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
address = "127.0.0.1:8125"
```
```bash tab="CLI"
--metrics.datadog.address=127.0.0.1:8125
```
#### `addEntryPointsLabels`
_Optional, Default=true_
Enable metrics on entry points.
```yaml tab="File (YAML)"
metrics:
datadog:
addEntryPointsLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
addEntryPointsLabels = true
```
```bash tab="CLI"
--metrics.datadog.addEntryPointsLabels=true
```
#### `addRoutersLabels`
_Optional, Default=false_
Enable metrics on routers.
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
addRoutersLabels = true
```
```yaml tab="File (YAML)"
metrics:
datadog:
addRoutersLabels: true
```
```bash tab="CLI"
--metrics.datadog.addrouterslabels=true
```
#### `addServicesLabels`
_Optional, Default=true_
Enable metrics on services.
```yaml tab="File (YAML)"
metrics:
datadog:
addServicesLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
addServicesLabels = true
```
```bash tab="CLI"
--metrics.datadog.addServicesLabels=true
```
#### `pushInterval`
_Optional, Default=10s_
The interval used by the exporter to push metrics to datadog-agent.
```yaml tab="File (YAML)"
metrics:
datadog:
pushInterval: 10s
```
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
pushInterval = "10s"
```
```bash tab="CLI"
--metrics.datadog.pushInterval=10s
```
#### `prefix`
_Optional, Default="traefik"_
The prefix to use for metrics collection.
```yaml tab="File (YAML)"
metrics:
datadog:
prefix: traefik
```
```toml tab="File (TOML)"
[metrics]
[metrics.datadog]
prefix = "traefik"
```
```bash tab="CLI"
--metrics.datadog.prefix=traefik
```
@@ -1,219 +0,0 @@
# InfluxDB v2
To enable the InfluxDB2:
```yaml tab="File (YAML)"
metrics:
influxDB2: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
```
```bash tab="CLI"
--metrics.influxdb2=true
```
#### `address`
_Required, Default="http://localhost:8086"_
Address of the InfluxDB v2 instance.
```yaml tab="File (YAML)"
metrics:
influxDB2:
address: http://localhost:8086
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
address = "http://localhost:8086"
```
```bash tab="CLI"
--metrics.influxdb2.address=http://localhost:8086
```
#### `token`
_Required, Default=""_
Token with which to connect to InfluxDB v2.
```yaml tab="File (YAML)"
metrics:
influxDB2:
token: secret
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
token = "secret"
```
```bash tab="CLI"
--metrics.influxdb2.token=secret
```
#### `org`
_Required, Default=""_
Organisation where metrics will be stored.
```yaml tab="File (YAML)"
metrics:
influxDB2:
org: my-org
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
org = "my-org"
```
```bash tab="CLI"
--metrics.influxdb2.org=my-org
```
#### `bucket`
_Required, Default=""_
Bucket where metrics will be stored.
```yaml tab="File (YAML)"
metrics:
influxDB2:
bucket: my-bucket
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
bucket = "my-bucket"
```
```bash tab="CLI"
--metrics.influxdb2.bucket=my-bucket
```
#### `addEntryPointsLabels`
_Optional, Default=true_
Enable metrics on entry points.
```yaml tab="File (YAML)"
metrics:
influxDB2:
addEntryPointsLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
addEntryPointsLabels = true
```
```bash tab="CLI"
--metrics.influxdb2.addEntryPointsLabels=true
```
#### `addRoutersLabels`
_Optional, Default=false_
Enable metrics on routers.
```yaml tab="File (YAML)"
metrics:
influxDB2:
addRoutersLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
addRoutersLabels = true
```
```bash tab="CLI"
--metrics.influxdb2.addrouterslabels=true
```
#### `addServicesLabels`
_Optional, Default=true_
Enable metrics on services.
```yaml tab="File (YAML)"
metrics:
influxDB2:
addServicesLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
addServicesLabels = true
```
```bash tab="CLI"
--metrics.influxdb2.addServicesLabels=true
```
#### `pushInterval`
_Optional, Default=10s_
The interval used by the exporter to push metrics to InfluxDB server.
```yaml tab="File (YAML)"
metrics:
influxDB2:
pushInterval: 10s
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
pushInterval = "10s"
```
```bash tab="CLI"
--metrics.influxdb2.pushInterval=10s
```
#### `additionalLabels`
_Optional, Default={}_
Additional labels (InfluxDB tags) on all metrics.
```yaml tab="File (YAML)"
metrics:
influxDB2:
additionalLabels:
host: example.com
environment: production
```
```toml tab="File (TOML)"
[metrics]
[metrics.influxDB2]
[metrics.influxDB2.additionalLabels]
host = "example.com"
environment = "production"
```
```bash tab="CLI"
--metrics.influxdb2.additionallabels.host=example.com --metrics.influxdb2.additionallabels.environment=production
```
@@ -1,570 +0,0 @@
---
title: "Traefik OpenTelemetry Documentation"
description: "Traefik supports several metrics backends, including OpenTelemetry. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# OpenTelemetry
To enable the OpenTelemetry metrics:
```yaml tab="File (YAML)"
metrics:
otlp: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
```
```bash tab="CLI"
--metrics.otlp=true
```
!!! info "Default protocol"
The OpenTelemetry exporter will export metrics to the collector using HTTPS by default to https://localhost:4318/v1/metrics, see the [gRPC Section](#grpc-configuration) to use gRPC.
#### `addEntryPointsLabels`
_Optional, Default=true_
Enable metrics on entry points.
```yaml tab="File (YAML)"
metrics:
otlp:
addEntryPointsLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
addEntryPointsLabels = true
```
```bash tab="CLI"
--metrics.otlp.addEntryPointsLabels=true
```
#### `addRoutersLabels`
_Optional, Default=false_
Enable metrics on routers.
```yaml tab="File (YAML)"
metrics:
otlp:
addRoutersLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
addRoutersLabels = true
```
```bash tab="CLI"
--metrics.otlp.addRoutersLabels=true
```
#### `addServicesLabels`
_Optional, Default=true_
Enable metrics on services.
```yaml tab="File (YAML)"
metrics:
otlp:
addServicesLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
addServicesLabels = true
```
```bash tab="CLI"
--metrics.otlp.addServicesLabels=true
```
#### `explicitBoundaries`
_Optional, Default=".005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10"_
Explicit boundaries for Histogram data points.
```yaml tab="File (YAML)"
metrics:
otlp:
explicitBoundaries:
- 0.1
- 0.3
- 1.2
- 5.0
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
explicitBoundaries = [0.1,0.3,1.2,5.0]
```
```bash tab="CLI"
--metrics.otlp.explicitBoundaries=0.1,0.3,1.2,5.0
```
#### `pushInterval`
_Optional, Default=10s_
Interval at which metrics are sent to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
metrics:
otlp:
pushInterval: 10s
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
pushInterval = "10s"
```
```bash tab="CLI"
--metrics.otlp.pushInterval=10s
```
#### `serviceName`
_Optional, Default="traefik"_
Defines the service name resource attribute.
```yaml tab="File (YAML)"
metrics:
otlp:
serviceName: name
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp]
serviceName = "name"
```
```bash tab="CLI"
--metrics.otlp.serviceName=name
```
#### `resourceAttributes`
_Optional, Default=empty_
Defines additional resource attributes to be sent to the collector.
```yaml tab="File (YAML)"
metrics:
otlp:
resourceAttributes:
attr1: foo
attr2: bar
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.resourceAttributes]
attr1 = "foo"
attr2 = "bar"
```
```bash tab="CLI"
--metrics.otlp.resourceAttributes.attr1=foo
--metrics.otlp.resourceAttributes.attr2=bar
```
### HTTP configuration
_Optional_
This instructs the exporter to send the metrics to the OpenTelemetry Collector using HTTP.
```yaml tab="File (YAML)"
metrics:
otlp:
http: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.http]
```
```bash tab="CLI"
--metrics.otlp.http=true
```
#### `endpoint`
_Optional, Default="https://localhost:4318/v1/metrics", Format="`<scheme>://<host>:<port><path>`"_
URL of the OpenTelemetry Collector to send metrics to.
!!! info "Insecure mode"
To disable TLS, use `http://` instead of `https://` in the `endpoint` configuration.
```yaml tab="File (YAML)"
metrics:
otlp:
http:
endpoint: https://collector:4318/v1/metrics
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.http]
endpoint = "https://collector:4318/v1/metrics"
```
```bash tab="CLI"
--metrics.otlp.http.endpoint=https://collector:4318/v1/metrics
```
#### `headers`
_Optional, Default={}_
Additional headers sent with metrics by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
metrics:
otlp:
http:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.http.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--metrics.otlp.http.headers.foo=bar --metrics.otlp.http.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send metrics to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
metrics:
otlp:
http:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[metrics.otlp.http.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--metrics.otlp.http.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
metrics:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[metrics.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--metrics.otlp.http.tls.cert=path/to/foo.cert
--metrics.otlp.http.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
metrics:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[metrics.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--metrics.otlp.http.tls.cert=path/to/foo.cert
--metrics.otlp.http.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
metrics:
otlp:
http:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[metrics.otlp.http.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--metrics.otlp.http.tls.insecureSkipVerify=true
```
### gRPC configuration
_Optional_
This instructs the exporter to send metrics to the OpenTelemetry Collector using gRPC.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.grpc]
```
```bash tab="CLI"
--metrics.otlp.grpc=true
```
#### `endpoint`
_Required, Default="localhost:4317", Format="`<host>:<port>`"_
Address of the OpenTelemetry Collector to send metrics to.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
endpoint: localhost:4317
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.grpc]
endpoint = "localhost:4317"
```
```bash tab="CLI"
--metrics.otlp.grpc.endpoint=localhost:4317
```
#### `insecure`
_Optional, Default=false_
Allows exporter to send metrics to the OpenTelemetry Collector without using a secured protocol.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
insecure: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.grpc]
insecure = true
```
```bash tab="CLI"
--metrics.otlp.grpc.insecure=true
```
#### `headers`
_Optional, Default={}_
Additional headers sent with metrics by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[metrics]
[metrics.otlp.grpc.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--metrics.otlp.grpc.headers.foo=bar --metrics.otlp.grpc.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send metrics to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[metrics.otlp.grpc.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--metrics.otlp.grpc.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[metrics.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--metrics.otlp.grpc.tls.cert=path/to/foo.cert
--metrics.otlp.grpc.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[metrics.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--metrics.otlp.grpc.tls.cert=path/to/foo.cert
--metrics.otlp.grpc.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
metrics:
otlp:
grpc:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[metrics.otlp.grpc.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--metrics.otlp.grpc.tls.insecureSkipVerify=true
```
@@ -1,332 +0,0 @@
---
title: "Traefik Metrics Overview"
description: "Traefik Proxy supports these metrics backend systems: Datadog, InfluxDB 2.X, Prometheus, and StatsD. Read the full documentation to get started."
---
# Metrics
Traefik provides metrics in the [OpenTelemetry](./opentelemetry.md) format as well as the following vendor specific backends:
- [Datadog](./datadog.md)
- [InfluxDB2](./influxdb2.md)
- [Prometheus](./prometheus.md)
- [StatsD](./statsd.md)
Traefik Proxy hosts an official Grafana dashboard for both [on-premises](https://grafana.com/grafana/dashboards/17346)
and [Kubernetes](https://grafana.com/grafana/dashboards/17347) deployments.
## Common Options
### `addInternals`
_Optional, Default="false"_
Enables metrics for internal resources (e.g.: `ping@internals`).
```yaml tab="File (YAML)"
metrics:
addInternals: true
```
```toml tab="File (TOML)"
[metrics]
addInternals = true
```
```bash tab="CLI"
--metrics.addinternals
```
## Global Metrics
| Metric | Type | [Labels](#labels) | Description |
|----------------------------|-------|--------------------------|--------------------------------------------------------------------|
| Config reload total | Count | | The total count of configuration reloads. |
| Config reload last success | Gauge | | The timestamp of the last configuration reload success. |
| Open connections | Gauge | `entrypoint`, `protocol` | The current count of open connections, by entrypoint and protocol. |
| TLS certificates not after | Gauge | | The expiration date of certificates. |
```opentelemetry tab="OpenTelemetry"
traefik_config_reloads_total
traefik_config_last_reload_success
traefik_open_connections
traefik_tls_certs_not_after
```
```prom tab="Prometheus"
traefik_config_reloads_total
traefik_config_last_reload_success
traefik_open_connections
traefik_tls_certs_not_after
```
```dd tab="Datadog"
config.reload.total
config.reload.lastSuccessTimestamp
open.connections
tls.certs.notAfterTimestamp
```
```influxdb tab="InfluxDB2"
traefik.config.reload.total
traefik.config.reload.lastSuccessTimestamp
traefik.open.connections
traefik.tls.certs.notAfterTimestamp
```
```statsd tab="StatsD"
# Default prefix: "traefik"
{prefix}.config.reload.total
{prefix}.config.reload.lastSuccessTimestamp
{prefix}.open.connections
{prefix}.tls.certs.notAfterTimestamp
```
### Labels
Here is a comprehensive list of labels that are provided by the global metrics:
| Label | Description | example |
|--------------|----------------------------------------|----------------------|
| `entrypoint` | Entrypoint that handled the connection | "example_entrypoint" |
| `protocol` | Connection protocol | "TCP" |
## OpenTelemetry Semantic Conventions
Traefik Proxy follows [official OpenTelemetry semantic conventions v1.23.1](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-metrics.md).
### HTTP Server
| Metric | Type | [Labels](#labels) | Description |
|-------------------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|
| http.server.request.duration | Histogram | `error.type`, `http.request.method`, `http.response.status_code`, `network.protocol.name`, `server.address`, `server.port`, `url.scheme` | Duration of HTTP server requests |
#### Labels
Here is a comprehensive list of labels that are provided by the metrics:
| Label | Description | example |
|-----------------------------|--------------------------------------------------------------|---------------|
| `error.type` | Describes a class of error the operation ended with | "500" |
| `http.request.method` | HTTP request method | "GET" |
| `http.response.status_code` | HTTP response status code | "200" |
| `network.protocol.name` | OSI application layer or non-OSI equivalent | "http/1.1" |
| `network.protocol.version` | Version of the protocol specified in `network.protocol.name` | "1.1" |
| `server.address` | Name of the local HTTP server that received the request | "example.com" |
| `server.port` | Port of the local HTTP server that received the request | "80" |
| `url.scheme` | The URI scheme component identifying the used protocol | "http" |
### HTTP Client
| Metric | Type | [Labels](#labels) | Description |
|-------------------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|
| http.client.request.duration | Histogram | `error.type`, `http.request.method`, `http.response.status_code`, `network.protocol.name`, `server.address`, `server.port`, `url.scheme` | Duration of HTTP client requests |
#### Labels
Here is a comprehensive list of labels that are provided by the metrics:
| Label | Description | example |
|-----------------------------|--------------------------------------------------------------|---------------|
| `error.type` | Describes a class of error the operation ended with | "500" |
| `http.request.method` | HTTP request method | "GET" |
| `http.response.status_code` | HTTP response status code | "200" |
| `network.protocol.name` | OSI application layer or non-OSI equivalent | "http/1.1" |
| `network.protocol.version` | Version of the protocol specified in `network.protocol.name` | "1.1" |
| `server.address` | Name of the local HTTP server that received the request | "example.com" |
| `server.port` | Port of the local HTTP server that received the request | "80" |
| `url.scheme` | The URI scheme component identifying the used protocol | "http" |
## HTTP Metrics
On top of the official OpenTelemetry semantic conventions, Traefik provides its own metrics to monitor the incoming traffic.
### EntryPoint Metrics
| Metric | Type | [Labels](#labels) | Description |
|-----------------------|-----------|--------------------------------------------|---------------------------------------------------------------------|
| Requests total | Count | `code`, `method`, `protocol`, `entrypoint` | The total count of HTTP requests received by an entrypoint. |
| Requests TLS total | Count | `tls_version`, `tls_cipher`, `entrypoint` | The total count of HTTPS requests received by an entrypoint. |
| Request duration | Histogram | `code`, `method`, `protocol`, `entrypoint` | Request processing duration histogram on an entrypoint. |
| Requests bytes total | Count | `code`, `method`, `protocol`, `entrypoint` | The total size of HTTP requests in bytes handled by an entrypoint. |
| Responses bytes total | Count | `code`, `method`, `protocol`, `entrypoint` | The total size of HTTP responses in bytes handled by an entrypoint. |
```opentelemetry tab="OpenTelemetry"
traefik_entrypoint_requests_total
traefik_entrypoint_requests_tls_total
traefik_entrypoint_request_duration_seconds
traefik_entrypoint_requests_bytes_total
traefik_entrypoint_responses_bytes_total
```
```prom tab="Prometheus"
traefik_entrypoint_requests_total
traefik_entrypoint_requests_tls_total
traefik_entrypoint_request_duration_seconds
traefik_entrypoint_requests_bytes_total
traefik_entrypoint_responses_bytes_total
```
```dd tab="Datadog"
entrypoint.request.total
entrypoint.request.tls.total
entrypoint.request.duration
entrypoint.requests.bytes.total
entrypoint.responses.bytes.total
```
```influxdb tab="InfluxDB2"
traefik.entrypoint.requests.total
traefik.entrypoint.requests.tls.total
traefik.entrypoint.request.duration
traefik.entrypoint.requests.bytes.total
traefik.entrypoint.responses.bytes.total
```
```statsd tab="StatsD"
# Default prefix: "traefik"
{prefix}.entrypoint.request.total
{prefix}.entrypoint.request.tls.total
{prefix}.entrypoint.request.duration
{prefix}.entrypoint.requests.bytes.total
{prefix}.entrypoint.responses.bytes.total
```
### Router Metrics
| Metric | Type | [Labels](#labels) | Description |
|-----------------------|-----------|---------------------------------------------------|----------------------------------------------------------------|
| Requests total | Count | `code`, `method`, `protocol`, `router`, `service` | The total count of HTTP requests handled by a router. |
| Requests TLS total | Count | `tls_version`, `tls_cipher`, `router`, `service` | The total count of HTTPS requests handled by a router. |
| Request duration | Histogram | `code`, `method`, `protocol`, `router`, `service` | Request processing duration histogram on a router. |
| Requests bytes total | Count | `code`, `method`, `protocol`, `router`, `service` | The total size of HTTP requests in bytes handled by a router. |
| Responses bytes total | Count | `code`, `method`, `protocol`, `router`, `service` | The total size of HTTP responses in bytes handled by a router. |
```opentelemetry tab="OpenTelemetry"
traefik_router_requests_total
traefik_router_requests_tls_total
traefik_router_request_duration_seconds
traefik_router_requests_bytes_total
traefik_router_responses_bytes_total
```
```prom tab="Prometheus"
traefik_router_requests_total
traefik_router_requests_tls_total
traefik_router_request_duration_seconds
traefik_router_requests_bytes_total
traefik_router_responses_bytes_total
```
```dd tab="Datadog"
router.request.total
router.request.tls.total
router.request.duration
router.requests.bytes.total
router.responses.bytes.total
```
```influxdb tab="InfluxDB2"
traefik.router.requests.total
traefik.router.requests.tls.total
traefik.router.request.duration
traefik.router.requests.bytes.total
traefik.router.responses.bytes.total
```
```statsd tab="StatsD"
# Default prefix: "traefik"
{prefix}.router.request.total
{prefix}.router.request.tls.total
{prefix}.router.request.duration
{prefix}.router.requests.bytes.total
{prefix}.router.responses.bytes.total
```
### Service Metrics
| Metric | Type | Labels | Description |
|-----------------------|-----------|-----------------------------------------|-------------------------------------------------------------|
| Requests total | Count | `code`, `method`, `protocol`, `service` | The total count of HTTP requests processed on a service. |
| Requests TLS total | Count | `tls_version`, `tls_cipher`, `service` | The total count of HTTPS requests processed on a service. |
| Request duration | Histogram | `code`, `method`, `protocol`, `service` | Request processing duration histogram on a service. |
| Retries total | Count | `service` | The count of requests retries on a service. |
| Server UP | Gauge | `service`, `url` | Current service's server status, 0 for a down or 1 for up. |
| Requests bytes total | Count | `code`, `method`, `protocol`, `service` | The total size of requests in bytes received by a service. |
| Responses bytes total | Count | `code`, `method`, `protocol`, `service` | The total size of responses in bytes returned by a service. |
```opentelemetry tab="OpenTelemetry"
traefik_service_requests_total
traefik_service_requests_tls_total
traefik_service_request_duration_seconds
traefik_service_retries_total
traefik_service_server_up
traefik_service_requests_bytes_total
traefik_service_responses_bytes_total
```
```prom tab="Prometheus"
traefik_service_requests_total
traefik_service_requests_tls_total
traefik_service_request_duration_seconds
traefik_service_retries_total
traefik_service_server_up
traefik_service_requests_bytes_total
traefik_service_responses_bytes_total
```
```dd tab="Datadog"
service.request.total
router.service.tls.total
service.request.duration
service.retries.total
service.server.up
service.requests.bytes.total
service.responses.bytes.total
```
```influxdb tab="InfluxDB2"
traefik.service.requests.total
traefik.service.requests.tls.total
traefik.service.request.duration
traefik.service.retries.total
traefik.service.server.up
traefik.service.requests.bytes.total
traefik.service.responses.bytes.total
```
```statsd tab="StatsD"
# Default prefix: "traefik"
{prefix}.service.request.total
{prefix}.service.request.tls.total
{prefix}.service.request.duration
{prefix}.service.retries.total
{prefix}.service.server.up
{prefix}.service.requests.bytes.total
{prefix}.service.responses.bytes.total
```
### Labels
Here is a comprehensive list of labels that are provided by the metrics:
| Label | Description | example |
|---------------|---------------------------------------|----------------------------|
| `cn` | Certificate Common Name | "example.com" |
| `code` | Request code | "200" |
| `entrypoint` | Entrypoint that handled the request | "example_entrypoint" |
| `method` | Request Method | "GET" |
| `protocol` | Request protocol | "http" |
| `router` | Router that handled the request | "example_router" |
| `sans` | Certificate Subject Alternative NameS | "example.com" |
| `serial` | Certificate Serial Number | "123..." |
| `service` | Service that handled the request | "example_service@provider" |
| `tls_cipher` | TLS cipher used for the request | "TLS_FALLBACK_SCSV" |
| `tls_version` | TLS version used for the request | "1.0" |
| `url` | Service server url | "http://example.com" |
!!! info "`method` label value"
If the HTTP method verb on a request is not one defined in the set of common methods for [`HTTP/1.1`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)
or the [`PRI`](https://datatracker.ietf.org/doc/html/rfc7540#section-11.6) verb (for `HTTP/2`),
then the value for the method label becomes `EXTENSION_METHOD`.
@@ -1,238 +0,0 @@
---
title: "Traefik Prometheus Documentation"
description: "Traefik supports several metrics backends, including Prometheus. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# Prometheus
To enable the Prometheus:
```yaml tab="File (YAML)"
metrics:
prometheus: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
```
```bash tab="CLI"
--metrics.prometheus=true
```
#### `buckets`
_Optional, Default="0.100000, 0.300000, 1.200000, 5.000000"_
Buckets for latency metrics.
```yaml tab="File (YAML)"
metrics:
prometheus:
buckets:
- 0.1
- 0.3
- 1.2
- 5.0
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
buckets = [0.1,0.3,1.2,5.0]
```
```bash tab="CLI"
--metrics.prometheus.buckets=0.1,0.3,1.2,5.0
```
#### `addEntryPointsLabels`
_Optional, Default=true_
Enable metrics on entry points.
```yaml tab="File (YAML)"
metrics:
prometheus:
addEntryPointsLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
addEntryPointsLabels = true
```
```bash tab="CLI"
--metrics.prometheus.addEntryPointsLabels=true
```
#### `addRoutersLabels`
_Optional, Default=false_
Enable metrics on routers.
```yaml tab="File (YAML)"
metrics:
prometheus:
addRoutersLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
addRoutersLabels = true
```
```bash tab="CLI"
--metrics.prometheus.addrouterslabels=true
```
#### `addServicesLabels`
_Optional, Default=true_
Enable metrics on services.
```yaml tab="File (YAML)"
metrics:
prometheus:
addServicesLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
addServicesLabels = true
```
```bash tab="CLI"
--metrics.prometheus.addServicesLabels=true
```
#### `entryPoint`
_Optional, Default=traefik_
Entry point used to expose metrics.
```yaml tab="File (YAML)"
entryPoints:
metrics:
address: :8082
metrics:
prometheus:
entryPoint: metrics
```
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.metrics]
address = ":8082"
[metrics]
[metrics.prometheus]
entryPoint = "metrics"
```
```bash tab="CLI"
--entryPoints.metrics.address=:8082
--metrics.prometheus.entryPoint=metrics
```
#### `manualRouting`
_Optional, Default=false_
If `manualRouting` is `true`, it disables the default internal router in order to allow one to create a custom router for the `prometheus@internal` service.
```yaml tab="File (YAML)"
metrics:
prometheus:
manualRouting: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
manualRouting = true
```
```bash tab="CLI"
--metrics.prometheus.manualrouting=true
```
#### `headerLabels`
_Optional_
Defines the extra labels for the `requests_total` metrics, and for each of them, the request header containing the value for this label.
Please note that if the header is not present in the request it will be added nonetheless with an empty value.
In addition, the label should be a valid label name for Prometheus metrics,
otherwise, the Prometheus metrics provider will fail to serve any Traefik-related metric.
```yaml tab="File (YAML)"
metrics:
prometheus:
headerLabels:
label: headerKey
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
[metrics.prometheus.headerLabels]
label = "headerKey"
```
```bash tab="CLI"
--metrics.prometheus.headerlabels.label=headerKey
```
##### Example
Here is an example of the entryPoint `requests_total` metric with an additional "useragent" label.
When configuring the label in Static Configuration:
```yaml tab="File (YAML)"
metrics:
prometheus:
headerLabels:
useragent: User-Agent
```
```toml tab="File (TOML)"
[metrics]
[metrics.prometheus]
[metrics.prometheus.headerLabels]
useragent = "User-Agent"
```
```bash tab="CLI"
--metrics.prometheus.headerlabels.useragent=User-Agent
```
And performing a request with a custom User-Agent:
```bash
curl -H "User-Agent: foobar" http://localhost
```
The following metric is produced :
```bash
traefik_entrypoint_requests_total{code="200",entrypoint="web",method="GET",protocol="http",useragent="foobar"} 1
```
!!! info "`Host` header value"
The `Host` header is never present in the Header map of a request, as per go documentation says:
// For incoming requests, the Host header is promoted to the
// Request.Host field and removed from the Header map.
As a workaround, to obtain the Host of a request as a label, one should use instead the `X-Forwarded-Host` header.
@@ -1,154 +0,0 @@
---
title: "Traefik StatsD Documentation"
description: "Traefik supports several metrics backends, including StatsD. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# StatsD
To enable the Statsd:
```yaml tab="File (YAML)"
metrics:
statsD: {}
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
```
```bash tab="CLI"
--metrics.statsd=true
```
#### `address`
_Required, Default="localhost:8125"_
Address instructs exporter to send metrics to statsd at this address.
```yaml tab="File (YAML)"
metrics:
statsD:
address: localhost:8125
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
address = "localhost:8125"
```
```bash tab="CLI"
--metrics.statsd.address=localhost:8125
```
#### `addEntryPointsLabels`
_Optional, Default=true_
Enable metrics on entry points.
```yaml tab="File (YAML)"
metrics:
statsD:
addEntryPointsLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
addEntryPointsLabels = true
```
```bash tab="CLI"
--metrics.statsd.addEntryPointsLabels=true
```
#### `addRoutersLabels`
_Optional, Default=false_
Enable metrics on routers.
```yaml tab="File (YAML)"
metrics:
statsD:
addRoutersLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
addRoutersLabels = true
```
```bash tab="CLI"
--metrics.statsd.addrouterslabels=true
```
#### `addServicesLabels`
_Optional, Default=true_
Enable metrics on services.
```yaml tab="File (YAML)"
metrics:
statsD:
addServicesLabels: true
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
addServicesLabels = true
```
```bash tab="CLI"
--metrics.statsd.addServicesLabels=true
```
#### `pushInterval`
_Optional, Default=10s_
The interval used by the exporter to push metrics to statsD.
```yaml tab="File (YAML)"
metrics:
statsD:
pushInterval: 10s
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
pushInterval = "10s"
```
```bash tab="CLI"
--metrics.statsd.pushInterval=10s
```
#### `prefix`
_Optional, Default="traefik"_
The prefix to use for metrics collection.
```yaml tab="File (YAML)"
metrics:
statsD:
prefix: traefik
```
```toml tab="File (TOML)"
[metrics]
[metrics.statsD]
prefix = "traefik"
```
```bash tab="CLI"
--metrics.statsd.prefix=traefik
```
-106
View File
@@ -1,106 +0,0 @@
---
title: "Traefik Observability Overview"
description: "Traefik provides Logs, Access Logs, Metrics and Tracing. Read the full documentation to get started."
---
# Overview
Traefiks observability features include logs, access logs, metrics, and tracing. You can configure these options globally or at more specific levels, such as per router or per entry point.
## Configuration Example
Enable access logs, metrics, and tracing globally
```yaml tab="File (YAML)"
accessLog: {}
metrics:
otlp: {}
tracing: {}
```
```yaml tab="File (TOML)"
[accessLog]
[metrics]
[metrics.otlp]
[tracing]
```
```bash tab="CLI"
--accesslog=true
--metrics.otlp=true
--tracing=true
```
You can disable access logs, metrics, and tracing for a specific entrypoint attached to a router:
```yaml tab="File (YAML)"
# Static Configuration
entryPoints:
EntryPoint0:
address: ':8000/udp'
observability:
accessLogs: false
tracing: false
metrics: false
```
```toml tab="File (TOML)"
# Static Configuration
[entryPoints.EntryPoint0]
address = ":8000/udp"
[entryPoints.EntryPoint0.observability]
accessLogs = false
tracing = false
metrics = false
```
```bash tab="CLI"
# Static Configuration
--entryPoints.EntryPoint0.address=:8000/udp
--entryPoints.EntryPoint0.observability.accessLogs=false
--entryPoints.EntryPoint0.observability.metrics=false
--entryPoints.EntryPoint0.observability.tracing=false
```
!!!note "Default Behavior"
A router with its own observability configuration will override the global default.
## Configuration Options
### Logs
Traefik logs informs about everything that happens within Traefik (startup, configuration, events, shutdown, and so on).
Read the [Logs documentation](./logs.md) to learn how to configure it.
### Access Logs
Access logs are a key part of observability in Traefik.
They are providing valuable insights about incoming traffic, and allow to monitor it.
The access logs record detailed information about each request received by Traefik,
including the source IP address, requested URL, response status code, and more.
Read the [Access Logs documentation](./access-logs.md) to learn how to configure it.
### Metrics
Traefik offers a metrics feature that provides valuable insights about the performance and usage.
These metrics include the number of requests received, the requests duration, and more.
On top of supporting metrics in the OpenTelemetry format, Traefik supports the following vendor specific metrics systems: Prometheus, Datadog, InfluxDB 2.X, and StatsD.
Read the [Metrics documentation](./metrics/overview.md) to learn how to configure it.
### Tracing
The Traefik tracing system allows developers to gain deep visibility into the flow of requests through their infrastructure.
Traefik provides tracing information in the OpenTelemery format.
Read the [Tracing documentation](./tracing/overview.md) to learn how to configure it.
@@ -1,432 +0,0 @@
---
title: "Traefik OpenTelemetry Documentation"
description: "Traefik supports several tracing backends, including OpenTelemetry. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation."
---
# OpenTelemetry
Traefik Proxy follows [official OpenTelemetry semantic conventions v1.37.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.37.0/docs/http/http-spans.md).
To enable the OpenTelemetry tracer:
```yaml tab="File (YAML)"
tracing:
otlp: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp]
```
```bash tab="CLI"
--tracing.otlp=true
```
!!! info "Default protocol"
The OpenTelemetry trace exporter will export traces to the collector using HTTPS by default to https://localhost:4318/v1/traces, see the [gRPC Section](#grpc-configuration) to use gRPC.
!!! info "Trace sampling"
By default, the OpenTelemetry trace exporter will sample 100% of traces.
See [OpenTelemetry's SDK configuration](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#general-sdk-configuration) to customize the sampling strategy.
!!! info "Propagation"
Traefik supports the `OTEL_PROPAGATORS` env variable to set up the propragators. The supported propagators are:
- tracecontext (default)
- baggage (default)
- b3
- b3multi
- jaeger
- xray
- ottrace
Example of configuration:
OTEL_PROPAGATORS=b3,jaeger
### HTTP configuration
_Optional_
This instructs the exporter to send spans to the OpenTelemetry Collector using HTTP.
```yaml tab="File (YAML)"
tracing:
otlp:
http: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.http]
```
```bash tab="CLI"
--tracing.otlp.http=true
```
#### `endpoint`
_Optional, Default="https://localhost:4318/v1/traces", Format="`<scheme>://<host>:<port><path>`"_
URL of the OpenTelemetry Collector to send spans to.
!!! info "Insecure mode"
To disable TLS, use `http://` instead of `https://` in the `endpoint` configuration.
```yaml tab="File (YAML)"
tracing:
otlp:
http:
endpoint: https://collector:4318/v1/traces
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.http]
endpoint = "https://collector:4318/v1/traces"
```
```bash tab="CLI"
--tracing.otlp.http.endpoint=https://collector:4318/v1/traces
```
#### `headers`
_Optional, Default={}_
Additional headers sent with traces by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
tracing:
otlp:
http:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.http.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--tracing.otlp.http.headers.foo=bar --tracing.otlp.http.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send spans to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
tracing:
otlp:
http:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[tracing.otlp.http.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--tracing.otlp.http.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
tracing:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[tracing.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--tracing.otlp.http.tls.cert=path/to/foo.cert
--tracing.otlp.http.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
tracing:
otlp:
http:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[tracing.otlp.http.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--tracing.otlp.http.tls.cert=path/to/foo.cert
--tracing.otlp.http.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
tracing:
otlp:
http:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[tracing.otlp.http.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--tracing.otlp.http.tls.insecureSkipVerify=true
```
### gRPC configuration
_Optional_
This instructs the exporter to send spans to the OpenTelemetry Collector using gRPC.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc: {}
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.grpc]
```
```bash tab="CLI"
--tracing.otlp.grpc=true
```
#### `endpoint`
_Required, Default="localhost:4317", Format="`<host>:<port>`"_
Address of the OpenTelemetry Collector to send spans to.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
endpoint: localhost:4317
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.grpc]
endpoint = "localhost:4317"
```
```bash tab="CLI"
--tracing.otlp.grpc.endpoint=localhost:4317
```
#### `insecure`
_Optional, Default=false_
Allows exporter to send spans to the OpenTelemetry Collector without using a secured protocol.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
insecure: true
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.grpc]
insecure = true
```
```bash tab="CLI"
--tracing.otlp.grpc.insecure=true
```
#### `headers`
_Optional, Default={}_
Additional headers sent with traces by the exporter to the OpenTelemetry Collector.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
headers:
foo: bar
baz: buz
```
```toml tab="File (TOML)"
[tracing]
[tracing.otlp.grpc.headers]
foo = "bar"
baz = "buz"
```
```bash tab="CLI"
--tracing.otlp.grpc.headers.foo=bar --tracing.otlp.grpc.headers.baz=buz
```
#### `tls`
_Optional_
Defines the Client TLS configuration used by the exporter to send spans to the OpenTelemetry Collector.
##### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the OpenTelemetry Collector,
it defaults to the system bundle.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
ca: path/to/ca.crt
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
ca = "path/to/ca.crt"
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.ca=path/to/ca.crt
```
##### `cert`
_Optional_
`cert` is the path to the public certificate used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.cert=path/to/foo.cert
--tracing.otlp.grpc.tls.key=path/to/foo.key
```
##### `key`
_Optional_
`key` is the path to the private key used for the secure connection to the OpenTelemetry Collector.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
cert: path/to/foo.cert
key: path/to/foo.key
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
cert = "path/to/foo.cert"
key = "path/to/foo.key"
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.cert=path/to/foo.cert
--tracing.otlp.grpc.tls.key=path/to/foo.key
```
##### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`,
the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers.
```yaml tab="File (YAML)"
tracing:
otlp:
grpc:
tls:
insecureSkipVerify: true
```
```toml tab="File (TOML)"
[tracing.otlp.grpc.tls]
insecureSkipVerify = true
```
```bash tab="CLI"
--tracing.otlp.grpc.tls.insecureSkipVerify=true
```
@@ -1,187 +0,0 @@
---
title: "Traefik Tracing Overview"
description: "The Traefik Proxy tracing system allows developers to visualize call flows in their infrastructure. Read the full documentation."
---
# Tracing
Visualize the Requests Flow
{: .subtitle }
The tracing system allows developers to visualize call flows in their infrastructure.
Traefik uses [OpenTelemetry](https://opentelemetry.io/ "Link to website of OTel"), an open standard designed for distributed tracing.
Please check our dedicated [OTel docs](./opentelemetry.md) to learn more.
## Configuration
To enable the tracing:
```yaml tab="File (YAML)"
tracing: {}
```
```toml tab="File (TOML)"
[tracing]
```
```bash tab="CLI"
--tracing=true
```
### Common Options
#### `addInternals`
_Optional, Default="false"_
Enables tracing for internal resources (e.g.: `ping@internal`).
```yaml tab="File (YAML)"
tracing:
addInternals: true
```
```toml tab="File (TOML)"
[tracing]
addInternals = true
```
```bash tab="CLI"
--tracing.addinternals
```
#### `serviceName`
_Required, Default="traefik"_
Service name used in selected backend.
```yaml tab="File (YAML)"
tracing:
serviceName: traefik
```
```toml tab="File (TOML)"
[tracing]
serviceName = "traefik"
```
```bash tab="CLI"
--tracing.serviceName=traefik
```
#### `sampleRate`
_Optional, Default=1.0_
The proportion of requests to trace, specified between 0.0 and 1.0.
```yaml tab="File (YAML)"
tracing:
sampleRate: 0.2
```
```toml tab="File (TOML)"
[tracing]
sampleRate = 0.2
```
```bash tab="CLI"
--tracing.sampleRate=0.2
```
#### `resourceAttributes`
_Optional, Default=empty_
Defines additional resource attributes to be sent to the collector.
```yaml tab="File (YAML)"
tracing:
resourceAttributes:
attr1: foo
attr2: bar
```
```toml tab="File (TOML)"
[tracing]
[tracing.resourceAttributes]
attr1 = "foo"
attr2 = "bar"
```
```bash tab="CLI"
--tracing.resourceAttributes.attr1=foo
--tracing.resourceAttributes.attr2=bar
```
#### `capturedRequestHeaders`
_Optional, Default=empty_
Defines the list of request headers to add as attributes.
It applies to client and server kind spans.
```yaml tab="File (YAML)"
tracing:
capturedRequestHeaders:
- X-CustomHeader
- X-OtherHeader
```
```toml tab="File (TOML)"
[tracing]
capturedRequestHeaders = ["X-CustomHeader", "X-OtherHeader"]
```
```bash tab="CLI"
--tracing.capturedRequestHeaders="X-CustomHeader,X-OtherHeader"
```
#### `capturedResponseHeaders`
_Optional, Default=empty_
Defines the list of response headers to add as attributes.
It applies to client and server kind spans.
```yaml tab="File (YAML)"
tracing:
capturedResponseHeaders:
- X-CustomHeader
- X-OtherHeader
```
```toml tab="File (TOML)"
[tracing]
capturedResponseHeaders = ["X-CustomHeader", "X-OtherHeader"]
```
```bash tab="CLI"
--tracing.capturedResponseHeaders="X-CustomHeader,X-OtherHeader"
```
#### `safeQueryParams`
_Optional, Default=[]_
By default, all query parameters are redacted.
Defines the list of query parameters to not redact.
```yaml tab="File (YAML)"
tracing:
safeQueryParams:
- bar
- buz
```
```toml tab="File (TOML)"
[tracing]
safeQueryParams = ["bar", "buz"]
```
```bash tab="CLI"
--tracing.safeQueryParams=bar,buz
```
@@ -175,6 +175,7 @@ When using the `json` format, you can customize which fields are included in you
- **Request Fields:** You can choose to `keep`, `drop`, or `redact` any of the standard request fields. A complete list of available fields like `ClientHost`, `RequestMethod`, and `Duration` can be found in the [reference documentation](../reference/install-configuration/observability/logs-and-accesslogs.md#json-format-fields).
- **Request Headers:** You can also specify which request headers should be included in the logs, and whether their values should be `kept`, `dropped`, or `redacted`.
- **Request Query Parameters:** You can choose to `keep` or `drop` the query parameters for a request.
!!! info
For detailed configuration options, refer to the [reference documentation](../reference/install-configuration/observability/logs-and-accesslogs.md).
-179
View File
@@ -1,179 +0,0 @@
---
title: "Traefik API Documentation"
description: "Traefik Proxy exposes information through API handlers. Learn about the security, configuration, and endpoints of APIs. Read the technical documentation."
---
# API
Traefik exposes a number of information through an API handler, such as the configuration of all routers, services, middlewares, etc.
As with all features of Traefik, this handler can be enabled with the [static configuration](../getting-started/configuration-overview.md#the-static-configuration).
## Security
Enabling the API in production is not recommended, because it will expose all configuration elements,
including sensitive data.
In production, it should be at least secured by authentication and authorizations.
!!! info
It's recommended to NOT publicly exposing the API's port, keeping it restricted to internal networks
(as in the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), applied to networks).
## Configuration
If you enable the API, a new special `service` named `api@internal` is created and can then be referenced in a router.
To enable the API handler, use the following option on the
[static configuration](../getting-started/configuration-overview.md#the-static-configuration):
```yaml tab="File (YAML)"
# Static Configuration
api: {}
```
```toml tab="File (TOML)"
# Static Configuration
[api]
```
```bash tab="CLI"
--api=true
```
And then define a routing configuration on Traefik itself with the
[dynamic configuration](../getting-started/configuration-overview.md#the-dynamic-configuration):
--8<-- "content/operations/include-api-examples.md"
??? warning "The router's [rule](../routing/routers/index.md#rule) must catch requests for the URI path `/api`"
Using an "Host" rule is recommended, by catching all the incoming traffic on this host domain to the API.
However, you can also use "path prefix" rule or any combination or rules.
```bash tab="Host Rule"
# Matches http://traefik.example.com, http://traefik.example.com/api
# or http://traefik.example.com/hello
rule = "Host(`traefik.example.com`)"
```
```bash tab="Path Prefix Rule"
# Matches http://api.traefik.example.com/api or http://example.com/api
# but does not match http://api.traefik.example.com/hello
rule = "PathPrefix(`/api`)"
```
```bash tab="Combination of Rules"
# Matches http://traefik.example.com/api or http://traefik.example.com/dashboard
# but does not match http://traefik.example.com/hello
rule = "Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
```
### `insecure`
Enable the API in `insecure` mode, which means that the API will be available directly on the entryPoint named `traefik`, on path `/api`.
!!! info
If the entryPoint named `traefik` is not configured, it will be automatically created on port 8080.
```yaml tab="File (YAML)"
api:
insecure: true
```
```toml tab="File (TOML)"
[api]
insecure = true
```
```bash tab="CLI"
--api.insecure=true
```
### `dashboard`
_Optional, Default=true_
Enable the dashboard. More about the dashboard features [here](./dashboard.md).
```yaml tab="File (YAML)"
api:
dashboard: true
```
```toml tab="File (TOML)"
[api]
dashboard = true
```
```bash tab="CLI"
--api.dashboard=true
```
!!! warning "With Dashboard enabled, the router [rule](../routing/routers/index.md#rule) must catch requests for both `/api` and `/dashboard`"
Please check the [Dashboard documentation](./dashboard.md#dashboard-router-rule) to learn more about this and to get examples.
### `debug`
_Optional, Default=false_
Enable additional [endpoints](./api.md#endpoints) for debugging and profiling, served under `/debug/`.
```yaml tab="File (YAML)"
api:
debug: true
```
```toml tab="File (TOML)"
[api]
debug = true
```
```bash tab="CLI"
--api.debug=true
```
## Endpoints
All the following endpoints must be accessed with a `GET` HTTP request.
!!! info "Pagination"
By default, up to 100 results are returned per page, and the next page can be checked using the `X-Next-Page` HTTP Header.
To control pagination, use the `page` and `per_page` query parameters.
```bash
curl https://traefik.example.com:8080/api/http/routers?page=2&per_page=20
```
| Path | Description |
|--------------------------------|-----------------------------------------------------------------------------------------------------|
| `/api/http/routers` | Lists all the HTTP routers information. |
| `/api/http/routers/{name}` | Returns the information of the HTTP router specified by `name`. |
| `/api/http/services` | Lists all the HTTP services information. |
| `/api/http/services/{name}` | Returns the information of the HTTP service specified by `name`. |
| `/api/http/middlewares` | Lists all the HTTP middlewares information. |
| `/api/http/middlewares/{name}` | Returns the information of the HTTP middleware specified by `name`. |
| `/api/tcp/routers` | Lists all the TCP routers information. |
| `/api/tcp/routers/{name}` | Returns the information of the TCP router specified by `name`. |
| `/api/tcp/services` | Lists all the TCP services information. |
| `/api/tcp/services/{name}` | Returns the information of the TCP service specified by `name`. |
| `/api/tcp/middlewares` | Lists all the TCP middlewares information. |
| `/api/tcp/middlewares/{name}` | Returns the information of the TCP middleware specified by `name`. |
| `/api/udp/routers` | Lists all the UDP routers information. |
| `/api/udp/routers/{name}` | Returns the information of the UDP router specified by `name`. |
| `/api/udp/services` | Lists all the UDP services information. |
| `/api/udp/services/{name}` | Returns the information of the UDP service specified by `name`. |
| `/api/entrypoints` | Lists all the entry points information. |
| `/api/entrypoints/{name}` | Returns the information of the entry point specified by `name`. |
| `/api/overview` | Returns statistic information about http and tcp as well as enabled features and providers. |
| `/api/support-dump` | Returns an archive that contains the anonymized static configuration and the runtime configuration. |
| `/api/rawdata` | Returns information about dynamic configurations, errors, status and dependency relations. |
| `/api/version` | Returns information about Traefik version. |
| `/debug/vars` | See the [expvar](https://golang.org/pkg/expvar/) Go documentation. |
| `/debug/pprof/` | See the [pprof Index](https://golang.org/pkg/net/http/pprof/#Index) Go documentation. |
| `/debug/pprof/cmdline` | See the [pprof Cmdline](https://golang.org/pkg/net/http/pprof/#Cmdline) Go documentation. |
| `/debug/pprof/profile` | See the [pprof Profile](https://golang.org/pkg/net/http/pprof/#Profile) Go documentation. |
| `/debug/pprof/symbol` | See the [pprof Symbol](https://golang.org/pkg/net/http/pprof/#Symbol) Go documentation. |
| `/debug/pprof/trace` | See the [pprof Trace](https://golang.org/pkg/net/http/pprof/#Trace) Go documentation. |
{% include-markdown "includes/traefik-for-business-applications.md" %}

Some files were not shown because too many files have changed in this diff Show More