1
0
mirror of https://github.com/containous/traefik.git synced 2025-09-06 05:44:21 +03:00

Compare commits

...

221 Commits

Author SHA1 Message Date
Jean-Baptiste Doumenjou
e73fd70add Prepare release v1.7.29 2021-03-29 18:12:04 +02:00
Ludovic Fernandez
c47849d43a Update to go1.16
Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
Co-authored-by: Michael Matur <michael.matur@gmail.com>
2021-03-22 18:00:04 +01:00
Romain
2921e1059a Prepare release v1.7.28 2021-01-13 18:14:03 +01:00
Fernandez Ludovic
fe8e539422 chore: Do a Docker login on Travis CI. 2021-01-13 17:43:55 +01:00
Fernandez Ludovic
45f0591cf6 fix: encrypted key in Travis CI. 2021-01-13 17:39:05 +01:00
Romain
d7f752de46 Prepare release v1.7.27 2021-01-13 17:16:05 +01:00
Romain
b7adc1960c Update copyright year for 2021 2021-01-13 16:02:03 +01:00
Jean-Baptiste Doumenjou
0fb277fd25 Fix tlsclientheaders integration test 2021-01-13 12:02:04 +01:00
Travis Payne
6c9e1d996e Fix stickiness support in Service Fabric. 2021-01-07 18:14:04 +01:00
Amos Shapira
0e942ace3b docs: fix language "if challenge is not known" 2021-01-04 11:42:03 +01:00
Romain
d1befe7b12 Fix documentation deployment. 2020-09-23 10:00:03 +02:00
Romain
274cab4bb3 chore: apply new documentation style.
Co-authored-by: jbdoumenjou <jb.doumenjou@gmail.com>
2020-09-23 09:26:04 +02:00
Nick Douma
d04b812412 Do not SetError on tracing event when whitelist allowed request 2020-09-21 12:00:04 +02:00
Amos Shapira
a3d37f636e Fix typo "CA's" instead of "CA:s" 2020-09-21 10:24:04 +02:00
Romain
e148a5b8f7 chore: move to Traefik organization.
Co-authored-by: jbdoumenjou <jb.doumenjou@gmail.com>
2020-09-21 10:20:04 +02:00
Michael
e382d2940f Add mixtus for documentation 2020-08-07 16:36:03 +02:00
Ludovic Fernandez
5afa78e18e Prepare release v1.7.26 2020-07-28 17:32:03 +02:00
Ludovic Fernandez
cfa04c300c fix: clean X-Forwarded-Prefix header for the dashboard. 2020-07-28 10:10:03 +02:00
Cory Claflin
cb6b94ff40 Change apiVersion to apps/v1 in examples/k8s/cheese-deployments.yaml 2020-07-27 16:24:03 +02:00
Ludovic Fernandez
0b2a6cecd1 Prepare release v1.7.25 2020-07-15 12:28:03 +02:00
Fernandez Ludovic
fee89273a3 chore: update doc analytics. 2020-07-03 12:07:46 +02:00
Richard Kojedzinszky
463e2285d6 Backport "Same Configuration Check" from master 2020-07-01 11:36:03 +02:00
Romain
c65277a6f0 Fix ipv6 handling in redirect middleware 2020-06-19 10:08:04 +02:00
Douglas De Toni Machado
bb14c3e812 Doc improvement on entrypoints whitelist for v1.7 2020-05-20 10:44:04 +02:00
kobayashi
85580dde3c Add ingress setup for minikube in docs 2020-05-14 18:06:05 +02:00
Ludovic Fernandez
4bb6d1bf4f Prepare release v1.7.24 2020-03-25 14:48:05 +01:00
Ludovic Fernandez
459cabca8e fix: stickiness annotations support. 2020-03-25 10:58:04 +01:00
Ludovic Fernandez
dcca37fe29 Prepare release v1.7.23 2020-03-23 16:50:04 +01:00
Julien Salleyron
a610f0b2a1 Force http/1.1 for upgrade (Traefik v1) 2020-03-23 15:18:04 +01:00
Ludovic Fernandez
ded285be29 Fix sameSite (Traefik v1) 2020-03-23 13:10:04 +01:00
Ludovic Fernandez
4b31d3306b fix: max TLS version. 2020-03-22 17:54:03 +01:00
Ludovic Fernandez
5a6652fc20 Prepare release v1.7.22 2020-03-18 15:00:07 +01:00
robotte
91b0e2e4dc Complete TLS example for Kubernetes Ingress in user guide 2020-03-09 19:16:05 +01:00
Ludovic Fernandez
554bceb75b Skip redirection with invalid regex syntax. 2020-03-09 13:24:05 +01:00
Ludovic Fernandez
ce76212605 fix: manual provider code name. 2020-03-08 12:08:03 +01:00
bjthomas1
d474c87cde Updated rbac and demonset example bloc 2020-03-02 09:48:04 +01:00
Ludovic Fernandez
862772230c Update to go1.14 2020-03-02 09:30:05 +01:00
Ludovic Fernandez
09fa1e6546 Fix typo in user guide. 2020-02-27 21:06:05 +01:00
Omer Karjevsky
c3125104d9 Clear closed hijacked h2c connections 2020-02-27 14:08:04 +01:00
Ludovic Fernandez
31786f7163 Prepare release v1.7.21 2020-02-20 18:22:04 +01:00
pierresteiner
d7ed42d614 Fix sample for ssl-header in docs 2020-02-19 17:18:04 +01:00
mpl
4c709c2fcd Improve rate-limiting doc 2020-02-07 17:26:05 +01:00
Yazan Dabain
8dac076711 Fix finding proper provided certificate when ACME is enabled 2020-02-06 10:08:04 +01:00
Julien Salleyron
0b039499c6 don't create http client in each request in forward auth 2020-02-04 18:36:04 +01:00
Steven
2124975432 Fix dnspod update. 2020-01-26 12:42:03 +01:00
Jean-Baptiste Doumenjou
e4725619ea Update the k8s api version in the documentation 2020-01-13 15:44:05 +01:00
Ludovic Fernandez
d24f78222c fix: skip ECS container when information are missing instead of panic. 2020-01-06 15:10:05 +01:00
Daniel Tomcej
3f1925e20e Add edge case for root path with rewrite-target 2019-12-19 09:24:04 +01:00
Ludovic Fernandez
a8393faf0a Prepare release v1.7.20 2019-12-10 17:50:05 +01:00
Daniel Tomcej
4b8ece5b42 Truncate key for identification in log 2019-12-09 11:50:06 +01:00
Brad Jones
7574bb9226 Add a warning note regarding optional TLS mutual auth 2019-11-27 17:18:05 +01:00
Ludovic Fernandez
f68b629469 fix: location header rewrite.
Co-authored-by: Daniel Tomcej <daniel.tomcej@gmail.com>
2019-11-18 14:28:06 +01:00
Ludovic Fernandez
f9e9e11035 Prepare release v1.7.19 2019-10-28 14:58:04 +01:00
Daniel Tomcej
772c9ca4d5 Allow Default Certificate to work on macOS 10.15 2019-10-25 17:08:05 +02:00
Ismail Alidzhikov
208d0fa471 Update DaemonSet apiVersion 2019-10-20 23:50:04 +02:00
mikezhang
9f72b6d1d5 Add functions to support precise float compute of weight (#5663) 2019-10-16 17:29:21 +02:00
Ingo Gottwald
29ef007917 Backport Go 1.13 integration test fixes 2019-10-07 10:46:04 +02:00
Eliel Goncalves
590a0d67bb Fix Location response header http to https when SSL 2019-10-07 10:16:05 +02:00
mpl
74ad83f05a Prepare release v1.7.18 2019-09-26 15:46:05 +02:00
Ludovic Fernandez
d707c8ba93 Prepare release v1.7.17 2019-09-23 19:48:04 +02:00
Nicholas Wiersma
640eb62ca1 Avoid closing stdout when the accesslog handler is closed
Co-authored-by: Ludovic Fernandez <ldez@users.noreply.github.com>
Co-authored-by: jlevesy <julien.levesy@containo.us>
2019-09-23 14:50:06 +02:00
mpl
216710864e Actually send header and code during WriteHeader, if needed
Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
2019-09-20 18:42:03 +02:00
Brad Jones
226f20b626 Add note clarifying client certificate header 2019-09-19 09:06:03 +02:00
Ludovic Fernandez
151be83bce Update docs links. 2019-09-18 15:38:04 +02:00
Ludovic Fernandez
d1a8c7fa78 Update Traefik image version. 2019-09-17 14:12:04 +02:00
Ludovic Fernandez
254dc38c3d Prepare release v1.7.16 2019-09-13 15:04:04 +02:00
mpl
24d084d7e6 implement Flusher and Hijacker for codeCatcher 2019-09-13 14:32:03 +02:00
Ludovic Fernandez
df5f530058 Prepare release v1.7.15 2019-09-12 18:10:05 +02:00
mpl
753d173965 error pages: do not buffer response when it's not an error 2019-09-12 16:20:05 +02:00
Daniel Tomcej
ffd1f122de Add TLS minversion constraint 2019-09-12 14:48:05 +02:00
Piotr Majkrzak
f98b57fdf4 Fix wrong handling of insecure tls auth forward ingress annotation 2019-09-12 11:44:05 +02:00
Damien Duportal
2d37f08864 Improve Access Logs Documentation page 2019-09-11 18:14:03 +02:00
Nicholas Wiersma
a7dbcc282c Consider default cert domain in certificate store
Co-authored-by: Nicolas Mengin <nmengin.pro@gmail.com>
2019-09-11 17:46:04 +02:00
David Dymko
f4f62e7fb3 Update Acme doc - Vultr Wildcard & Root 2019-09-09 09:26:04 +02:00
mpl
4cae8bcb10 Finish kubernetes throttling refactoring 2019-08-31 05:10:04 -07:00
Ben Weissmann
bee370ec6b Throttle Kubernetes config refresh 2019-08-30 03:16:04 -07:00
pitan
f1d016b893 Typo in basic auth usersFile label consul-catalog 2019-08-21 01:36:03 -07:00
Erik Wegner
4defbbe848 Kubernetes support for Auth.HeaderField 2019-08-21 01:30:05 -07:00
Ludovic Fernandez
f397342f16 Prepare release v1.7.14 2019-08-14 02:06:03 -07:00
Ludovic Fernandez
989a59cc29 Update to go1.12.8 2019-08-14 01:52:05 -07:00
Julien Levesy
c5b71592c8 Make hijackConnectionTracker.Close thread safe 2019-08-12 02:34:04 -07:00
Ludovic Fernandez
9de3129a55 Prepare release v1.7.13 2019-08-08 09:04:03 -07:00
Douglas Wagner
40ab1f325c Wrr loadbalancer honors old weight on recovered servers 2019-08-07 08:14:04 -07:00
Daniel Becker
73e0561610 Update lego 2019-08-05 09:08:04 -07:00
Jean Prat
0a89cccdc0 warning should not be a fail status 2019-08-05 08:40:04 -07:00
Daniel Tomcej
b102e6de5a Add missing KeyUsages for default generated certificate 2019-08-05 06:20:05 -07:00
alvarezbruned
2064a6f805 Add example for CLI 2019-08-01 05:38:04 -07:00
Amir Keibi
72e2ddff98 Updating Service Fabric documentation 2019-07-26 02:30:05 -07:00
David Dymko
7db41967c6 Fixed doc link for AlibabaCloud 2019-07-16 16:02:04 +02:00
Jean-Baptiste Doumenjou
a8680a8719 Fixes the TLS Mutual Authentication documentation 2019-07-15 08:46:04 +02:00
Ludovic Fernandez
7e11fa1193 Update Docker version. 2019-07-15 07:04:02 +02:00
gurayyildirim
489b5a6150 Format YAML example on user guide 2019-07-08 10:40:03 +02:00
Daniel Tomcej
8027e8ee23 Check for multiport services on Global Backend Ingress 2019-06-27 09:42:03 +02:00
Damien Duportal
d35d5bd2e8 Update documentation to clarify the default format for logs 2019-06-26 14:28:04 +02:00
stffabi
8e47bdedc6 Clear TLS client headers if TLSMutualAuth is optional 2019-06-26 11:32:04 +02:00
Damien Duportal
51419a9235 Update Slack support channel references to Discourse community forum 2019-06-25 10:06:03 +02:00
Ludovic Fernandez
32fd52c698 Use dynamodbav tags to override json tags. 2019-06-24 09:14:03 +02:00
Ludovic Fernandez
468e4ebd98 Add remarks about Rancher 2 2019-06-21 19:04:04 +02:00
Damien Duportal
92a57384a4 Allows logs to use local time zone instead of UTC
Co-authored-by: Ludovic Fernandez <ldez@users.noreply.github.com>
2019-06-17 09:20:03 +02:00
Damien Duportal
2067a433cd Improve API / Dashboard wording in documentation 2019-06-04 00:42:05 +02:00
kolaente
16f1f851cc Use the latest stable version of traefik in the docs 2019-06-03 17:38:07 +02:00
Daniel Tomcej
8e992c7cfb Update docker api version 2019-06-03 11:28:06 +02:00
Ludovic Fernandez
9da0bcf3aa Prepare release v1.7.12 2019-05-29 20:42:06 +02:00
Ludovic Fernandez
51287d9316 Remove authentication hashes from API 2019-05-29 19:22:07 +02:00
Ludovic Fernandez
29307fe9fa fix: update-lego. 2019-05-28 17:32:05 +02:00
ravilr
52772c9642 fix kubernetes template for backend responseforwarding flushinterval setting 2019-05-23 18:14:05 +02:00
ravilr
8f135fdb0a Add missing callback on close of hijacked connections 2019-05-23 09:40:04 +02:00
Ludovic Fernandez
7722a41270 Adds a log fields documentation. 2019-05-21 17:02:11 +02:00
Alex Antonov
cd11b1aab4 Upgraded DataDog tracing library to 1.13.0 2019-05-15 18:04:06 +02:00
Ludovic Fernandez
e7564d4cf8 Enhance KV logs. 2019-05-15 17:20:08 +02:00
Wenxuan Zhao
cc130fb673 Allow SANs for wildcards domain. (#4821) 2019-05-03 18:08:37 +02:00
Greg Berns
4106cf647b Docs: Troubleshooting help for Docker Swarm labels 2019-05-03 10:28:05 +02:00
Ludovic Fernandez
8a1c3510ea Prepare release v1.7.11 2019-04-26 10:34:06 +02:00
Jean-Baptiste Doumenjou
787b0a3ac7 Enhance KV client error management
Co-authored-by: Ludovic Fernandez <ldez@users.noreply.github.com>
2019-04-26 09:36:03 +02:00
Ludovic Fernandez
a6d86cdddb fix: update lego. 2019-04-23 11:40:05 +02:00
mpl
9559a56011 Improve log message about redundant TLS certificate 2019-04-15 12:32:03 +02:00
ctas582
07e8042192 Forward all header values from forward auth response 2019-04-10 17:18:06 +02:00
Martin Hoefling
edd8e36dcc Documentation Update: Hosting.de wildcard support tested 2019-04-09 16:52:05 +02:00
Ludovic Fernandez
e291dcb8d1 Get Structor version from CI env var. 2019-04-08 08:44:03 +02:00
Ludovic Fernandez
de6e365b74 Update zipkin-go-opentracing. 2019-04-05 11:18:04 +02:00
Amir Aslaminejad
98a5e08553 Remove usage of github.com/satori/go.uuid 2019-04-05 08:44:03 +02:00
Brandon McNama
ba44619828 Update Wildcard Domain documentation 2019-04-01 17:42:04 +02:00
Ludovic Fernandez
86d700c845 Enhance k8s tests maintainability 2019-04-01 17:02:06 +02:00
Ludovic Fernandez
b2f11afcc2 Update certificates for some Docker images 2019-04-01 00:54:03 +02:00
Maxim Fominykh
cfb356c68e Keep consistent order 2019-03-29 16:40:03 +01:00
Ludovic Fernandez
266f5d18a8 Prepare release v1.7.10 2019-03-28 15:42:05 +01:00
Julien Salleyron
305af43fb9 Add entrypoints prefix in kubernetes frontend/backend id 2019-03-28 14:22:05 +01:00
Julien Salleyron
30545808d9 Remove thoas/stats fork 2019-03-28 13:46:04 +01:00
Michael
358f125a58 Migrate to dep 0.5 (#4684) 2019-03-28 12:58:57 +01:00
Andy Kipp
57ae9a80d5 Support external name service on global default backend 2019-03-27 17:48:04 +01:00
Alex Antonov
e32c021f16 Added support for configuring trace headers for DataDog tracing 2019-03-27 17:20:05 +01:00
Siyu
0db2a9aadd Exclude websocket connections from Average Response Time 2019-03-27 15:48:04 +01:00
tomberek
4f4dab3ca5 Reorder Auth and TLSClientHeaders middleware 2019-03-27 11:54:05 +01:00
Ludovic Fernandez
eaee39e534 fix: update lego. 2019-03-27 11:18:04 +01:00
Jonas Thelemann
d85eb0495c Add _FILE Environment Variable Documentation 2019-03-27 10:50:03 +01:00
Ludovic Fernandez
8aa618775d New build system for experimental Docker image. 2019-03-19 11:58:03 +01:00
Ludovic Fernandez
f6b7e333be Change deploy script. 2019-03-19 07:20:02 +01:00
Ludovic Fernandez
108d9dbb3f Update structor to restore permalink for the latest version 2019-03-18 11:32:03 +01:00
Emile Vauge
2a1fa32950 Add TraefikEE as security workaround 2019-03-15 18:54:05 +01:00
Ludovic Fernandez
ee7aa77833 Update structor 2019-03-15 16:04:04 +01:00
Ludovic Fernandez
fcc4cab614 Migrate to go-acme/lego. 2019-03-12 16:40:04 +01:00
Damien Duportal
1206cd52fc Travis: switch fallback dockerfile for structor 2019-02-27 18:56:04 +01:00
Daniel Tomcej
5cdba752a4 Loop through service ports for global backend 2019-02-26 17:18:04 +01:00
Damien Duportal
b48ea1e173 Update Structor to v1.4.0 2019-02-20 13:50:03 +01:00
Ludovic Fernandez
373040f552 Applies new goimports recommendations. 2019-02-18 07:50:03 +01:00
Ludovic Fernandez
443902a0f0 Prepare release v1.7.9 2019-02-11 12:24:03 +01:00
Ludovic Fernandez
9eb02d9b03 Add support for specifying the name of the endpoint. 2019-02-11 09:12:04 +01:00
Ludovic Fernandez
2eb651645d Updates of Lego. 2019-02-11 08:52:03 +01:00
Ludovic Fernandez
630571fdc8 Fixes the display of the associativity rules. 2019-02-08 09:06:03 +01:00
Rémy G
00fc43ebce Fixed curl example 2019-02-06 17:10:09 +01:00
Mohamed Abdelkader Hizaoui
6d906fa4c8 Add Tracing Header Context Name option for Jaeger 2019-02-05 18:20:03 +01:00
Doctori
6a4c7796e3 app-root on non-explicit path include "/" in the redirect 2019-02-05 17:30:07 +01:00
Adam Gołąb
67704e333d Update default value in docs of buckets for Prometheus 2019-02-05 16:36:08 +01:00
SALLEYRON Julien
76c9cea856 fix missing trailers with retry 2019-02-01 09:50:04 +01:00
apsifly
0366fb9bc2 handle errors when working with rancher 2019-01-30 17:10:03 +01:00
Jean-Baptiste Doumenjou
5fed947eaa insecureSkipVerify for the passTLSCert transport 2019-01-30 16:50:05 +01:00
Ludovic Fernandez
c289279d24 doc: update change log. 2019-01-30 16:26:06 +01:00
Ludovic Fernandez
418dca1113 Prepare release v1.7.8 2019-01-29 17:22:07 +01:00
Ludovic Fernandez
ed293e3058 Fixes docker swarm mode refresh second for KV. 2019-01-29 17:08:08 +01:00
Foivos Filippopoulos
40bb0cd879 Check for dynamic tls updates on configuration preload 2019-01-29 16:46:09 +01:00
Ludovic Fernandez
32f5e0df8f Updates lego. 2019-01-25 10:24:04 +01:00
Maarten van der Hoef
40b8a93930 Generic awsvpc support, not just Fargate 2019-01-21 17:00:07 +01:00
hwhelan-CB
b52b0f58b9 Cache exising task definitions to avoid rate limiting 2019-01-19 08:56:02 +01:00
David Birks
0016db0856 Minor formatting fixes 2019-01-16 20:10:04 +01:00
Joost Cassee
5aeca4507e Support Datadog tracer priority sampling 2019-01-16 17:08:06 +01:00
Thorsten
11bfb49e65 Route priorities: document minimum priority value 2019-01-16 16:44:05 +01:00
Dragnucs
d0cdb5608f Note about quotes for entrypoint definition with docker-compose 2019-01-16 16:36:07 +01:00
Timo Reimann
8bb8ad5e02 Assert that test timeout service is ready. 2019-01-16 15:00:09 +01:00
rbq
b488d8365c Allow Træfik to update Ingress status 2019-01-15 16:42:05 +01:00
Ludovic Fernandez
e2bd7b45d1 doc: more detailed info about Google Cloud DNS. 2019-01-15 16:30:08 +01:00
Tim Stackhouse
c8ea2ce703 Tested wildcard ACME challenge with DNSimple 2019-01-14 17:40:04 +01:00
Henri Larget
7d1edcd735 doc missing information about statistics parameter 2019-01-14 17:28:04 +01:00
Ishaan Bahal
9660c31d3d Removed repeated entryPoints.http from grpc.md 2019-01-11 16:34:04 +01:00
Ludovic Fernandez
37ac19583a fix: update lego. 2019-01-11 16:22:03 +01:00
Emile Vauge
ca60c52199 Happy 2019 2019-01-08 16:22:04 +01:00
Ludovic Fernandez
9cddf5616a Prepare release v1.7.7 2019-01-08 10:52:03 +01:00
Jean-Baptiste Doumenjou
f8ba843ad2 Add Pass TLS Cert Issuer and Domain Component 2019-01-08 09:46:04 +01:00
Daniel Tomcej
e598d6bcca Skip TLS section with no secret in Kubernetes ingress 2019-01-08 09:22:03 +01:00
Julien Levesy
52ec0e8d34 Retry middleware : store headers per attempts and propagate them when responding. 2019-01-07 23:18:03 +01:00
Jack
13c32dee11 Harden Traefik systemd service 2019-01-07 19:02:03 +01:00
Tim Möhlmann
6db120fd8e Test and exit for jq error before domain loop 2019-01-07 18:50:04 +01:00
Ludovic Fernandez
b6b3a9ed7f Update Lego 2019-01-07 18:30:06 +01:00
Radoslaw Wesolowski
b5a4d0797a Redirection status codes for methods different than GET 2019-01-07 17:56:04 +01:00
Michael
9ec2887494 Fix html-proofer and nokogiri version 2019-01-07 17:28:03 +01:00
Asmir Mustafic
94de6eb7f2 Letsencrypt - Add info on httpreq format 2019-01-04 17:24:04 +01:00
Wim Fournier
0e643f06a3 Proposing a small update to documentation 2019-01-03 18:30:05 +01:00
Daniel Tomcej
4db0dd9a7f Allow empty path with App-root annotation 2018-12-26 11:52:03 +01:00
Daniel Tomcej
ee19e66aba Check for watched namespace before getting kubernetes objects 2018-12-26 11:30:05 +01:00
zarqman
16ed13ba6f kubernetes: sort and uniq TLS secrets 2018-12-20 20:08:03 +01:00
Joost Cassee
8f5e972843 Update contributing docs: use dep version < 0.5.0 2018-12-20 17:38:04 +01:00
Damien Duportal
4b70ff82b9 Check for anchors (hashes) for external links on the documentation 2018-12-19 17:36:04 +01:00
Damien Duportal
1468e1f697 Rephrase the traefik.backend definition in documentation 2018-12-19 16:50:04 +01:00
Cleber Rech
7a963e75fd Update broken link for Docker service constraints 2018-12-18 12:26:03 +01:00
Ludovic Fernandez
9203ba5f95 Prepare release v1.7.6 2018-12-14 04:42:03 +01:00
Wim Fournier
302849282c Fix label segmentation when using custom prefix 2018-12-07 16:38:03 +01:00
Michael
2a227fa4c7 Prepare release v1.7.5 2018-12-03 11:34:04 +01:00
hwhelan-CB
31b80683c8 Filter ECS tasks by LastStatus before adding to list of service tasks 2018-12-03 10:54:07 +01:00
Michael
6aa040ad9f Fix upgrade flaeg 2018-12-03 10:34:04 +01:00
SALLEYRON Julien
617de78d14 Fix unannonced trailers problem when body is empty 2018-11-30 16:56:03 +01:00
Ludovic Fernandez
44605731dc Matcher associativity rule. 2018-11-30 09:08:03 +01:00
Thomas Krzero
9d26839e54 [docker backend] - Add config flag to set refreshSeconds for swarmmode ticker 2018-11-27 17:44:04 +01:00
Damien Duportal
7a93bcc869 Add a "Security Consideration" section in the Docker's backend section of the documentation 2018-11-27 13:54:04 +01:00
Gérald Croës
0840fd0f96 Log configuration errors from providers and keeps listening 2018-11-26 18:52:03 +01:00
Daniel Tomcej
4a5f5440d7 Implement Case-insensitive SNI matching 2018-11-26 10:38:03 +01:00
Ludovic Fernandez
479ee9af49 Fix partial declaration of authentication. 2018-11-22 16:52:03 +01:00
Siyu
ef6c1fac4b Update swarm mode endpoint 2018-11-20 16:40:06 +01:00
Ludovic Fernandez
53201b65b0 fix: ACME spec and Cloudflare. 2018-11-16 16:40:04 +01:00
Julien Levesy
9cb4d56c03 Clarify swarm loadbalancer documentation 2018-11-15 19:46:03 +01:00
Michael
f25ebc7e3d Query params in health check 2018-11-15 15:50:03 +01:00
Alex Antonov
4c25cda55f Upgraded DD APM library 2018-11-15 11:16:03 +01:00
Shane Hanna
18962b61d6 Include an explicit list of kubernetes protocol annotations in docs. 2018-11-15 10:52:04 +01:00
Michael Terrington
d0aa993661 Improve kubernetes TLS user guide 2018-11-14 10:24:03 +01:00
Si Westcott
df688dba0e frame-deny should be set to true to enable the header 2018-11-14 08:42:03 +01:00
Demian
69585c58cd Allow usersFile comments 2018-11-12 17:28:04 +01:00
stffabi
b889b0191c Remove X-Forwarded-Uri and X-Forwarded-Method from untrusted IP 2018-11-12 17:06:04 +01:00
SALLEYRON Julien
9b0586cba7 Verify ctx when we send configuration message in docker provider 2018-11-12 09:52:03 +01:00
Giorgio Comai
a20f5bda0b Fix spelling in comment 2018-11-08 08:30:04 +01:00
Tobias Hernstig
28d5731b87 Documentation: Rename "admin panel" to "dashboard 2018-11-08 08:20:03 +01:00
Rouven Bauer
66486eacdc ACME DNS provider is called acme-dns 2018-11-07 16:26:03 +01:00
Kim Min
2b82ed054c Support canary weight for external name service 2018-11-06 07:48:02 +01:00
Michael
cd6f0c0ded Fix ssl force host secure middleware 2018-10-31 15:00:09 +01:00
5208 changed files with 15658 additions and 1364340 deletions

View File

@@ -1,3 +1,5 @@
dist/
!dist/traefik
site/
vendor/
/traefik

2
.gitattributes vendored
View File

@@ -1 +1 @@
# vendor/github.com/xenolf/lego/providers/dns/cloudxns/cloudxns.go eol=crlf
# vendor/github.com/go-acme/lego/providers/dns/cloudxns/cloudxns.go eol=crlf

24
.github/CODEOWNERS vendored
View File

@@ -1,24 +0,0 @@
provider/kubernetes/** @containous/kubernetes
provider/rancher/** @containous/rancher
provider/marathon/** @containous/marathon
provider/docker/** @containous/docker
docs/user-guide/kubernetes.md @containous/kubernetes
docs/user-guide/marathon.md @containous/marathon
docs/user-guide/swarm.md @containous/docker
docs/user-guide/swarm-mode.md @containous/docker
docs/configuration/backends/docker.md @containous/docker
docs/configuration/backends/kubernetes.md @containous/kubernetes
docs/configuration/backends/marathon.md @containous/marathon
docs/configuration/backends/rancher.md @containous/rancher
examples/k8s/ @containous/kubernetes
examples/compose-k8s.yaml @containous/kubernetes
examples/k8s.namespace.yaml @containous/kubernetes
examples/compose-rancher.yml @containous/rancher
examples/compose-marathon.yml @containous/marathon
vendor/github.com/gambol99/go-marathon @containous/marathon
vendor/github.com/rancher @containous/rancher
vendor/k8s.io/ @containous/kubernetes

View File

@@ -12,7 +12,7 @@ HOW TO WRITE A GOOD PULL REQUEST?
- Write useful descriptions and titles.
- Address review comments in terms of additional commits.
- Do not amend/squash existing ones unless the PR is trivial.
- Read the contributing guide: https://github.com/containous/traefik/blob/master/CONTRIBUTING.md.
- Read the contributing guide: https://github.com/traefik/traefik/blob/master/CONTRIBUTING.md.
-->

22
.gitignore vendored
View File

@@ -1,15 +1,21 @@
/dist
/autogen/genstatic/gen.go
.idea/
.intellij/
*.iml
/traefik
/traefik.toml
/static/
/webui/.tmp/
.vscode/
.DS_Store
/static/
/autogen/genstatic/gen.go
/webui/.tmp/
/examples/acme/acme.json
/site/
/docs/site/
/traefik.toml
/traefik.yml
/dist
/traefik
*.log
*.exe
.DS_Store
/examples/acme/acme.json
cover.out
vendor/
plugins-storage/
traefik_changelog.md

View File

@@ -1,42 +0,0 @@
{
"Vendor": true,
"Sort": [
"path",
"line",
"column",
"severity",
"linter"
],
"Test": true,
"Cyclo": 15,
"Enable": [
"gotypex",
"nakedret",
"vet",
"goimports",
"golint",
"ineffassign",
"gotype",
"misspell",
"structcheck",
"gosimple",
"unconvert",
"varcheck",
"errcheck",
"unused",
"deadcode",
"staticcheck"
],
"Disable": [
"gas",
"maligned",
"interfacer",
"goconst",
"gocyclo",
"vetshadow"
],
"Exclude": [
"autogen/.*"
],
"Deadline": "5m"
}

20
.semaphoreci/golang.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e
curl -O https://dl.google.com/go/go1.14.linux-amd64.tar.gz
tar -xvf go1.14.linux-amd64.tar.gz
rm -rf go1.14.linux-amd64.tar.gz
sudo mkdir -p /usr/local/golang/1.14/go
sudo mv go /usr/local/golang/1.14/
sudo rm /usr/local/bin/go
sudo chmod +x /usr/local/golang/1.14/go/bin/go
sudo ln -s /usr/local/golang/1.14/go/bin/go /usr/local/bin/go
export GOROOT="/usr/local/golang/1.14/go"
export GOTOOLDIR="/usr/local/golang/1.14/go/pkg/tool/linux_amd64"
go version

View File

@@ -1,11 +1,11 @@
#!/usr/bin/env bash
set -e
export DOCKER_VERSION=17.03.1
export DOCKER_VERSION=18.09.7
source .semaphoreci/vars
if [ -z "${PULL_REQUEST_NUMBER}" ]; then SHOULD_TEST="-*-"; else TEMP_STORAGE=$(curl --silent https://patch-diff.githubusercontent.com/raw/containous/traefik/pull/${PULL_REQUEST_NUMBER}.diff | patch --dry-run -p1 -R); fi
if [ -z "${PULL_REQUEST_NUMBER}" ]; then SHOULD_TEST="-*-"; else TEMP_STORAGE=$(curl --silent https://patch-diff.githubusercontent.com/raw/traefik/traefik/pull/${PULL_REQUEST_NUMBER}.diff | patch --dry-run -p1 -R); fi
if [ -n "$TEMP_STORAGE" ]; then SHOULD_TEST=$(echo "$TEMP_STORAGE" | grep -Ev '(.md|.yaml|.yml)' || :); fi

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -e
export REPO='containous/traefik'
export REPO='traefik/traefik'
if VERSION=$(git describe --exact-match --abbrev=0 --tags);
then

View File

@@ -13,6 +13,7 @@ env:
- VERSION: $TRAVIS_TAG
- CODENAME: maroilles
- N_MAKE_JOBS: 2
- DOCS_VERIFY_SKIP: true
script:
- echo "Skipping tests... (Tests are executed on SemaphoreCI)"
@@ -25,14 +26,15 @@ before_deploy:
sudo -E apt-get -yq update;
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install docker-ce=${DOCKER_VERSION}*;
docker version;
echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin;
make image;
if [ "$TRAVIS_TAG" ]; then
make -j${N_MAKE_JOBS} crossbinary-parallel;
tar cfz dist/traefik-${VERSION}.src.tar.gz --exclude-vcs --exclude dist .;
fi;
curl -sI https://github.com/containous/structor/releases/latest | grep -Fi Location | tr -d '\r' | sed "s/tag/download/g" | awk -F " " '{ print $2 "/structor_linux-amd64"}' | wget --output-document=$GOPATH/bin/structor -i -;
chmod +x $GOPATH/bin/structor;
structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/master/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/containous/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/containous/structor/master/requirements-override.txt" --exp-branch=master --debug;
curl -sfL https://raw.githubusercontent.com/traefik/structor/master/godownloader.sh | bash -s -- -b "${GOPATH}/bin" ${STRUCTOR_VERSION}
curl -sSfL https://raw.githubusercontent.com/traefik/mixtus/master/godownloader.sh | sh -s -- -b "${GOPATH}/bin" ${MIXTUS_VERSION}
structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --exp-branch=master --force-edit-url --debug;
fi
deploy:
- provider: releases
@@ -41,24 +43,17 @@ deploy:
skip_cleanup: true
file_glob: true
on:
repo: containous/traefik
repo: traefik/traefik
tags: true
- provider: script
script: sh script/deploy.sh
skip_cleanup: true
on:
repo: containous/traefik
repo: traefik/traefik
tags: true
- provider: script
script: sh script/deploy-docker.sh
script: mixtus --dst-doc-path="./traefik" --dst-owner=traefik --dst-repo-name=doc --git-user-email="30906710+traefiker@users.noreply.github.com" --git-user-name=traefiker --src-doc-path="./site" --src-owner=containous --src-repo-name=traefik
skip_cleanup: true
on:
repo: containous/traefik
- provider: pages
edge: false
github_token: ${GITHUB_TOKEN}
local_dir: site
skip_cleanup: true
on:
repo: containous/traefik
repo: traefik/traefik
all_branches: true

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at contact@containo.us
reported by contacting the project team at contact@traefik.io
All complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.

View File

@@ -13,11 +13,11 @@ You need to run the `binary` target. This will create binaries for Linux platfor
$ make binary
docker build -t "traefik-dev:no-more-godep-ever" -f build.Dockerfile .
Sending build context to Docker daemon 295.3 MB
Step 0 : FROM golang:1.11-alpine
Step 0 : FROM golang:1.14-alpine
---> 8c6473912976
Step 1 : RUN go get github.com/golang/dep/cmd/dep
[...]
docker run --rm -v "/var/run/docker.sock:/var/run/docker.sock" -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/user/go/src/github.com/containous/traefik/"dist":/go/src/github.com/containous/traefik/"dist"" "traefik-dev:no-more-godep-ever" ./script/make.sh generate binary
docker run --rm -v "/var/run/docker.sock:/var/run/docker.sock" -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/user/go/src/github.com/traefik/traefik/"dist":/go/src/github.com/traefik/traefik/"dist"" "traefik-dev:no-more-godep-ever" ./script/make.sh generate binary
---> Making bundle: generate (in .)
removed 'gen.go'
@@ -32,7 +32,7 @@ traefik*
##### Setting up your `go` environment
- You need `go` v1.9+
- It is recommended you clone Traefik into a directory like `~/go/src/github.com/containous/traefik` (This is the official golang workspace hierarchy, and will allow dependencies to resolve properly)
- It is recommended you clone Traefik into a directory like `~/go/src/github.com/traefik/traefik` (This is the official golang workspace hierarchy, and will allow dependencies to resolve properly)
- Set your `GOPATH` and `PATH` variable to be set to `~/go` via:
```bash
@@ -61,7 +61,7 @@ GORACE=""
Once your environment is set up and the Traefik repository cloned you can build Traefik. You need get `go-bindata` once to be able to use `go generate` command as part of the build. The steps to build are:
```bash
cd ~/go/src/github.com/containous/traefik
cd ~/go/src/github.com/traefik/traefik
# Get go-bindata. Please note, the ellipses are required
go get github.com/containous/go-bindata/...
@@ -77,7 +77,7 @@ go build ./cmd/traefik
# run other commands like tests
```
You will find the Traefik executable in the `~/go/src/github.com/containous/traefik` folder as `traefik`.
You will find the Traefik executable in the `~/go/src/github.com/traefik/traefik` folder as `traefik`.
### Updating the templates
@@ -87,7 +87,7 @@ If you happen to update the provider templates (in `/templates`), you need to ru
[dep](https://github.com/golang/dep) is not required for building; however, it is necessary to modify dependencies (i.e., add, update, or remove third-party packages)
You need to use [dep](https://github.com/golang/dep) >= O.4.1.
You need to use [dep](https://github.com/golang/dep) >= 0.5.0.
If you want to add a dependency, use `dep ensure -add` to have [dep](https://github.com/golang/dep) put it into the vendor folder and update the dep manifest/lock files (`Gopkg.toml` and `Gopkg.lock`, respectively).
@@ -117,13 +117,13 @@ integration test using the `test-integration` target.
$ make test-unit
docker build -t "traefik-dev:your-feature-branch" -f build.Dockerfile .
# […]
docker run --rm -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/user/go/src/github/containous/traefik/dist:/go/src/github.com/containous/traefik/dist" "traefik-dev:your-feature-branch" ./script/make.sh generate test-unit
docker run --rm -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/user/go/src/github/traefik/traefik/dist:/go/src/github.com/traefik/traefik/dist" "traefik-dev:your-feature-branch" ./script/make.sh generate test-unit
---> Making bundle: generate (in .)
removed 'gen.go'
---> Making bundle: test-unit (in .)
+ go test -cover -coverprofile=cover.out .
ok github.com/containous/traefik 0.005s coverage: 4.1% of statements
ok github.com/traefik/traefik 0.005s coverage: 4.1% of statements
Test success
```
@@ -151,14 +151,14 @@ More: https://labix.org/gocheck
Unit tests can be run from the cloned directory by `$ go test ./...` which should return `ok` similar to:
```
ok _/home/user/go/src/github/containous/traefik 0.004s
ok _/home/user/go/src/github/traefik/traefik 0.004s
```
Integration tests must be run from the `integration/` directory and require the `-integration` switch to be passed like this: `$ cd integration && go test -integration ./...`.
## Documentation
The [documentation site](http://docs.traefik.io/) is built with [mkdocs](http://mkdocs.org/)
The [documentation site](https://doc.traefik.io/traefik/v1.7/) is built with [mkdocs](https://mkdocs.org/)
### Building Documentation
@@ -170,7 +170,7 @@ You can build the documentation and serve it locally with livereloading, using t
$ make docs
docker build -t traefik-docs -f docs.Dockerfile .
# […]
docker run --rm -v /home/user/go/github/containous/traefik:/mkdocs -p 8000:8000 traefik-docs mkdocs serve
docker run --rm -v /home/user/go/github/traefik/traefik:/mkdocs -p 8000:8000 traefik-docs mkdocs serve
# […]
[I 170828 20:47:48 server:283] Serving on http://0.0.0.0:8000
[I 170828 20:47:48 handlers:60] Start watching changes
@@ -224,7 +224,7 @@ You can verify that the documentation meets some expectations, as checking for d
$ make docs-verify
docker build -t traefik-docs-verify ./script/docs-verify-docker-image ## Build Validator image
...
docker run --rm -v /home/travis/build/containous/traefik:/app traefik-docs-verify ## Check for dead links and w3c compliance
docker run --rm -v /home/travis/build/traefik/traefik:/app traefik-docs-verify ## Check for dead links and w3c compliance
=== Checking HTML content...
Running ["HtmlCheck", "ImageCheck", "ScriptCheck", "LinkCheck"] on /app/site/basics/index.html on *.html...
```
@@ -236,6 +236,14 @@ $ make docs-clean docs-verify
...
```
Please note that verification can be disabled by setting the environment variable `DOCS_VERIFY_SKIP` to `true`:
```shell
DOCS_VERIFY_SKIP=true make docs-verify
...
DOCS_LINT_SKIP is true: no linting done.
```
## How to Write a Good Issue
Please keep in mind that the GitHub issue tracker is not intended as a general support forum, but for reporting bugs and feature requests.

1829
Gopkg.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,266 +0,0 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
[[constraint]]
branch = "master"
name = "github.com/ArthurHlt/go-eureka-client"
[[constraint]]
branch = "master"
name = "github.com/BurntSushi/toml"
[[constraint]]
branch = "master"
name = "github.com/BurntSushi/ty"
[[constraint]]
branch = "master"
name = "github.com/NYTimes/gziphandler"
[[constraint]]
branch = "containous-fork"
name = "github.com/abbot/go-http-auth"
source = "github.com/containous/go-http-auth"
[[constraint]]
branch = "master"
name = "github.com/armon/go-proxyproto"
[[constraint]]
name = "github.com/aws/aws-sdk-go"
version = "1.13.11"
[[constraint]]
branch = "master"
name = "github.com/cenk/backoff"
[[constraint]]
name = "github.com/containous/flaeg"
version = "1.3.0"
[[constraint]]
branch = "master"
name = "github.com/containous/mux"
[[constraint]]
name = "github.com/containous/staert"
version = "3.1.1"
[[constraint]]
name = "github.com/containous/traefik-extra-service-fabric"
version = "1.3.0"
[[constraint]]
name = "github.com/coreos/go-systemd"
version = "14.0.0"
[[constraint]]
branch = "master"
name = "github.com/docker/leadership"
source = "github.com/containous/leadership"
[[constraint]]
name = "github.com/eapache/channels"
version = "1.1.0"
[[constraint]]
branch = "master"
name = "github.com/elazarl/go-bindata-assetfs"
[[constraint]]
branch = "fork-containous"
name = "github.com/go-check/check"
source = "github.com/containous/check"
[[override]]
branch = "fork-containous"
name = "github.com/go-check/check"
source = "github.com/containous/check"
[[constraint]]
name = "github.com/go-kit/kit"
version = "0.7.0"
[[constraint]]
branch = "master"
name = "github.com/gorilla/websocket"
[[constraint]]
name = "github.com/hashicorp/consul"
version = "1.0.6"
[[constraint]]
name = "github.com/influxdata/influxdb"
version = "1.3.7"
[[constraint]]
branch = "master"
name = "github.com/jjcollinge/servicefabric"
[[constraint]]
branch = "master"
name = "github.com/abronan/valkeyrie"
[[constraint]]
name = "github.com/mesosphere/mesos-dns"
source = "https://github.com/containous/mesos-dns.git"
[[constraint]]
branch = "master"
name = "github.com/mitchellh/copystructure"
[[constraint]]
branch = "master"
name = "github.com/mitchellh/hashstructure"
[[constraint]]
branch = "master"
name = "github.com/mitchellh/mapstructure"
[[constraint]]
name = "github.com/opentracing/opentracing-go"
version = "1.0.2"
[[constraint]]
branch = "containous-fork"
name = "github.com/rancher/go-rancher-metadata"
source = "github.com/containous/go-rancher-metadata"
[[constraint]]
branch = "master"
name = "github.com/ryanuber/go-glob"
[[constraint]]
name = "github.com/satori/go.uuid"
version = "1.1.0"
[[constraint]]
branch = "master"
name = "github.com/stvp/go-udp-testing"
[[constraint]]
name = "github.com/stretchr/testify"
version = "1.2.1"
[[constraint]]
name = "github.com/uber/jaeger-client-go"
version = "2.9.0"
[[constraint]]
name = "github.com/uber/jaeger-lib"
version = "1.1.0"
[[constraint]]
branch = "v1"
name = "github.com/unrolled/secure"
[[constraint]]
name = "github.com/vdemeester/shakers"
version = "0.1.0"
[[constraint]]
branch = "master"
name = "github.com/vulcand/oxy"
[[constraint]]
branch = "master"
name = "github.com/xenolf/lego"
# version = "1.0.0"
[[constraint]]
name = "google.golang.org/grpc"
version = "1.5.2"
[[constraint]]
name = "gopkg.in/fsnotify.v1"
source = "github.com/fsnotify/fsnotify"
version = "1.4.2"
[[constraint]]
name = "k8s.io/client-go"
version = "6.0.0"
[[constraint]]
name = "k8s.io/api"
version = "kubernetes-1.9.0"
[[constraint]]
name = "k8s.io/apimachinery"
version = "kubernetes-1.9.0"
[[constraint]]
branch = "master"
name = "github.com/libkermit/docker"
[[constraint]]
branch = "master"
name = "github.com/libkermit/docker-check"
[[constraint]]
branch = "master"
name = "github.com/libkermit/compose"
[[constraint]]
name = "github.com/docker/docker"
revision = "7848b8beb9d38a98a78b75f78e05f8d2255f9dfe"
[[override]]
name = "github.com/docker/docker"
revision = "7848b8beb9d38a98a78b75f78e05f8d2255f9dfe"
[[override]]
name = "github.com/docker/cli"
revision = "6b63d7b96a41055baddc3fa71f381c7f60bd5d8e"
[[override]]
name = "github.com/docker/distribution"
revision = "edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c"
[[override]]
branch = "master"
name = "github.com/docker/libcompose"
[[override]]
name = "github.com/Nvveen/Gotty"
revision = "a8b993ba6abdb0e0c12b0125c603323a71c7790c"
source = "github.com/ijc25/Gotty"
[[override]]
# ALWAYS keep this override
name = "github.com/mailgun/timetools"
revision = "7e6055773c5137efbeb3bd2410d705fe10ab6bfd"
[[override]]
branch = "master"
name = "github.com/miekg/dns"
[prune]
non-go = true
go-tests = true
unused-packages = true
[[constraint]]
name = "github.com/patrickmn/go-cache"
version = "2.1.0"
[[constraint]]
name = "gopkg.in/DataDog/dd-trace-go.v1"
version = "1.0.0"

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016-2018 Containous SAS
Copyright (c) 2016-2018 Containous SAS; 2020-2021 Traefik Labs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -27,7 +27,7 @@ We use [PRM](https://github.com/ldez/prm) to manage locally pull requests.
## Bots
### [Myrmica Lobicornis](https://github.com/containous/lobicornis/)
### [Myrmica Lobicornis](https://github.com/traefik/lobicornis/)
**Update and Merge Pull Request**
@@ -51,13 +51,13 @@ This label is used when:
- Preparing the release
### [Myrmica Bibikoffi](https://github.com/containous/bibikoffi/)
### [Myrmica Bibikoffi](https://github.com/traefik/bibikoffi/)
* closes stale issues [cron]
* use some criterion as number of days between creation, last update, labels, ...
### [Myrmica Aloba](https://github.com/containous/aloba)
### [Myrmica Aloba](https://github.com/traefik/aloba)
**Manage GitHub labels**

View File

@@ -14,15 +14,16 @@ TRAEFIK_ENVS := \
SRCS = $(shell git ls-files '*.go' | grep -v '^vendor/')
BIND_DIR := "dist"
TRAEFIK_MOUNT := -v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/containous/traefik/$(BIND_DIR)"
TRAEFIK_MOUNT := -v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/traefik/traefik/$(BIND_DIR)"
GIT_BRANCH := $(subst heads/,,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null))
TRAEFIK_DEV_IMAGE := traefik-dev$(if $(GIT_BRANCH),:$(subst /,-,$(GIT_BRANCH)))
REPONAME := $(shell echo $(REPO) | tr '[:upper:]' '[:lower:]')
TRAEFIK_IMAGE := $(if $(REPONAME),$(REPONAME),"containous/traefik")
TRAEFIK_IMAGE := $(if $(REPONAME),$(REPONAME),"traefik/traefik")
INTEGRATION_OPTS := $(if $(MAKE_DOCKER_HOST),-e "DOCKER_HOST=$(MAKE_DOCKER_HOST)", -e "TEST_CONTAINER=1" -v "/var/run/docker.sock:/var/run/docker.sock")
TRAEFIK_DOC_IMAGE := traefik-docs
TRAEFIK_DOC_VERIFY_IMAGE := $(TRAEFIK_DOC_IMAGE)-verify
DOCS_VERIFY_SKIP ?= false
DOCKER_BUILD_ARGS := $(if $(DOCKER_VERSION), "--build-arg=DOCKER_VERSION=$(DOCKER_VERSION)",)
DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)"
@@ -75,7 +76,7 @@ test-integration: build ## run the integration tests
TEST_HOST=1 ./script/make.sh test-integration
validate: build ## validate code, vendor and autogen
$(DOCKER_RUN_TRAEFIK) ./script/make.sh validate-gofmt validate-govet validate-golint validate-misspell validate-vendor validate-autogen
$(DOCKER_RUN_TRAEFIK) ./script/make.sh validate-gofmt validate-golint validate-misspell validate-vendor validate-autogen
build: dist
docker build $(DOCKER_BUILD_ARGS) -t "$(TRAEFIK_DEV_IMAGE)" -f build.Dockerfile .
@@ -104,8 +105,12 @@ docs: docs-image
docs-build: site
docs-verify: site
docker build -t $(TRAEFIK_DOC_VERIFY_IMAGE) ./script/docs-verify-docker-image ## Build Validator image
docker run --rm -v $(CURDIR):/app $(TRAEFIK_DOC_VERIFY_IMAGE) ## Check for dead links and w3c compliance
ifeq ($(DOCS_VERIFY_SKIP),false)
docker build -t $(TRAEFIK_DOC_VERIFY_IMAGE) ./script/docs-verify-docker-image
docker run --rm -v $(CURDIR):/app $(TRAEFIK_DOC_VERIFY_IMAGE)
else
@echo "DOCS_LINT_SKIP is true: no linting done."
endif
site: docs-image
docker run $(DOCKER_RUN_DOC_OPTS) $(TRAEFIK_DOC_IMAGE) mkdocs build
@@ -128,7 +133,7 @@ generate-webui: build-webui
if [ ! -d "static" ]; then \
mkdir -p static; \
docker run --rm -v "$$PWD/static":'/src/static' traefik-webui npm run build; \
echo 'For more informations show `webui/readme.md`' > $$PWD/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \
echo 'For more information show `webui/readme.md`' > $$PWD/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \
fi
lint:
@@ -140,12 +145,5 @@ fmt:
pull-images:
grep --no-filename -E '^\s+image:' ./integration/resources/compose/*.yml | awk '{print $$2}' | sort | uniq | xargs -P 6 -n 1 docker pull
dep-ensure:
dep ensure -v
./script/prune-dep.sh
dep-prune:
./script/prune-dep.sh
help: ## this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

View File

@@ -4,10 +4,10 @@
</p>
[![Build Status SemaphoreCI](https://semaphoreci.com/api/v1/containous/traefik/branches/master/shields_badge.svg)](https://semaphoreci.com/containous/traefik)
[![Docs](https://img.shields.io/badge/docs-current-brightgreen.svg)](https://docs.traefik.io)
[![Go Report Card](https://goreportcard.com/badge/containous/traefik)](http://goreportcard.com/report/containous/traefik)
[![Docs](https://img.shields.io/badge/docs-current-brightgreen.svg)](https://doc.traefik.io/traefik/v1.7)
[![Go Report Card](https://goreportcard.com/badge/traefik/traefik)](http://goreportcard.com/report/traefik/traefik)
[![](https://images.microbadger.com/badges/image/traefik.svg)](https://microbadger.com/images/traefik)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/containous/traefik/blob/master/LICENSE.md)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/traefik/traefik/blob/master/LICENSE.md)
[![Join the chat at https://slack.traefik.io](https://img.shields.io/badge/style-register-green.svg?style=social&label=Slack)](https://slack.traefik.io)
[![Twitter](https://img.shields.io/twitter/follow/traefik.svg?style=social)](https://twitter.com/intent/follow?screen_name=traefik)
@@ -70,22 +70,22 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t
## Supported Backends
- [Docker](https://docs.traefik.io/configuration/backends/docker) / [Swarm mode](https://docs.traefik.io/configuration/backends/docker#docker-swarm-mode)
- [Kubernetes](https://docs.traefik.io/configuration/backends/kubernetes)
- [Mesos](https://docs.traefik.io/configuration/backends/mesos) / [Marathon](https://docs.traefik.io/configuration/backends/marathon)
- [Rancher](https://docs.traefik.io/configuration/backends/rancher) (API, Metadata)
- [Azure Service Fabric](https://docs.traefik.io/configuration/backends/servicefabric)
- [Consul Catalog](https://docs.traefik.io/configuration/backends/consulcatalog)
- [Consul](https://docs.traefik.io/configuration/backends/consul) / [Etcd](https://docs.traefik.io/configuration/backends/etcd) / [Zookeeper](https://docs.traefik.io/configuration/backends/zookeeper) / [BoltDB](https://docs.traefik.io/configuration/backends/boltdb)
- [Eureka](https://docs.traefik.io/configuration/backends/eureka)
- [Amazon ECS](https://docs.traefik.io/configuration/backends/ecs)
- [Amazon DynamoDB](https://docs.traefik.io/configuration/backends/dynamodb)
- [File](https://docs.traefik.io/configuration/backends/file)
- [Rest](https://docs.traefik.io/configuration/backends/rest)
- [Docker](https://doc.traefik.io/traefik/v1.7/configuration/backends/docker) / [Swarm mode](https://doc.traefik.io/traefik/v1.7/configuration/backends/docker#docker-swarm-mode)
- [Kubernetes](https://doc.traefik.io/traefik/v1.7/configuration/backends/kubernetes)
- [Mesos](https://doc.traefik.io/traefik/v1.7/configuration/backends/mesos) / [Marathon](https://doc.traefik.io/traefik/v1.7/configuration/backends/marathon)
- [Rancher](https://doc.traefik.io/traefik/v1.7/configuration/backends/rancher) (API, Metadata)
- [Azure Service Fabric](https://doc.traefik.io/traefik/v1.7/configuration/backends/servicefabric)
- [Consul Catalog](https://doc.traefik.io/traefik/v1.7/configuration/backends/consulcatalog)
- [Consul](https://doc.traefik.io/traefik/v1.7/configuration/backends/consul) / [Etcd](https://doc.traefik.io/traefik/v1.7/configuration/backends/etcd) / [Zookeeper](https://doc.traefik.io/traefik/v1.7/configuration/backends/zookeeper) / [BoltDB](https://doc.traefik.io/traefik/v1.7/configuration/backends/boltdb)
- [Eureka](https://doc.traefik.io/traefik/v1.7/configuration/backends/eureka)
- [Amazon ECS](https://doc.traefik.io/traefik/v1.7/configuration/backends/ecs)
- [Amazon DynamoDB](https://doc.traefik.io/traefik/v1.7/configuration/backends/dynamodb)
- [File](https://doc.traefik.io/traefik/v1.7/configuration/backends/file)
- [Rest](https://doc.traefik.io/traefik/v1.7/configuration/backends/rest)
## Quickstart
To get your hands on Traefik, you can use the [5-Minute Quickstart](http://docs.traefik.io/#the-traefik-quickstart-using-docker) in our documentation (you will need Docker).
To get your hands on Traefik, you can use the [5-Minute Quickstart](http://doc.traefik.io/traefik/v1.7/#the-traefik-quickstart-using-docker) in our documentation (you will need Docker).
Alternatively, if you don't want to install anything on your computer, you can try Traefik online in this great [Katacoda tutorial](https://www.katacoda.com/courses/traefik/deploy-load-balancer) that shows how to load balance requests between multiple Docker containers.
@@ -100,7 +100,7 @@ You can access the simple HTML frontend of Traefik.
## Documentation
You can find the complete documentation at [https://docs.traefik.io](https://docs.traefik.io).
You can find the complete documentation at [https://doc.traefik.io/traefik/v1.7](https://doc.traefik.io/traefik/v1.7).
A collection of contributions around Traefik can be found at [https://awesome.traefik.io](https://awesome.traefik.io).
## Support
@@ -109,17 +109,17 @@ To get community support, you can:
- join the Traefik community Slack channel: [![Join the chat at https://slack.traefik.io](https://img.shields.io/badge/style-register-green.svg?style=social&label=Slack)](https://slack.traefik.io)
- use [Stack Overflow](https://stackoverflow.com/questions/tagged/traefik) (using the `traefik` tag)
If you need commercial support, please contact [Containo.us](https://containo.us) by mail: <mailto:support@containo.us>.
If you need commercial support, please contact [Traefik.io](https://traefik.io) by mail: <mailto:support@traefik.io>.
## Download
- Grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
- Grab the latest binary from the [releases](https://github.com/traefik/traefik/releases) page and run it with the [sample configuration file](https://raw.githubusercontent.com/traefik/traefik/v1.7/traefik.sample.toml):
```shell
./traefik --configFile=traefik.toml
```
- Or use the official tiny Docker image and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
- Or use the official tiny Docker image and run it with the [sample configuration file](https://raw.githubusercontent.com/traefik/traefik/v1.7/traefik.sample.toml):
```shell
docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
@@ -128,12 +128,12 @@ docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.to
- Or get the sources:
```shell
git clone https://github.com/containous/traefik
git clone https://github.com/traefik/traefik
```
## Introductory Videos
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at [GopherCon 2017](https://gophercon.com/).
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at GopherCon 2017.
You will learn Traefik basics in less than 10 minutes.
[![Traefik GopherCon 2017](https://img.youtube.com/vi/RgudiksfL-k/0.jpg)](https://www.youtube.com/watch?v=RgudiksfL-k)

View File

@@ -14,18 +14,19 @@ import (
"sync"
"time"
"github.com/containous/traefik/log"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/types"
"github.com/xenolf/lego/acme"
"github.com/go-acme/lego/v3/certcrypto"
"github.com/go-acme/lego/v3/registration"
"github.com/traefik/traefik/log"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/types"
)
// Account is used to store lets encrypt registration info
type Account struct {
Email string
Registration *acme.RegistrationResource
Registration *registration.Resource
PrivateKey []byte
KeyType acme.KeyType
KeyType certcrypto.KeyType
DomainsCertificate DomainsCertificates
ChallengeCerts map[string]*ChallengeCert
HTTPChallenge map[string]map[string][]byte
@@ -100,7 +101,7 @@ func (a *Account) GetEmail() string {
}
// GetRegistration returns lets encrypt registration resource
func (a *Account) GetRegistration() *acme.RegistrationResource {
func (a *Account) GetRegistration() *registration.Resource {
return a.Registration
}
@@ -110,7 +111,12 @@ func (a *Account) GetPrivateKey() crypto.PrivateKey {
return privateKey
}
log.Errorf("Cannot unmarshall private key %+v", a.PrivateKey)
keySnippet := ""
if len(a.PrivateKey) >= 16 {
keySnippet = string(a.PrivateKey[:16])
}
log.Errorf("Cannot unmarshall private key beginning with %s", keySnippet)
return nil
}

View File

@@ -20,21 +20,26 @@ import (
"github.com/containous/flaeg"
"github.com/containous/mux"
"github.com/containous/staert"
"github.com/containous/traefik/cluster"
"github.com/containous/traefik/log"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/containous/traefik/version"
"github.com/eapache/channels"
"github.com/go-acme/lego/v3/certificate"
"github.com/go-acme/lego/v3/challenge"
"github.com/go-acme/lego/v3/challenge/dns01"
"github.com/go-acme/lego/v3/challenge/http01"
"github.com/go-acme/lego/v3/lego"
legolog "github.com/go-acme/lego/v3/log"
"github.com/go-acme/lego/v3/providers/dns"
"github.com/go-acme/lego/v3/registration"
"github.com/sirupsen/logrus"
"github.com/xenolf/lego/acme"
legolog "github.com/xenolf/lego/log"
"github.com/xenolf/lego/providers/dns"
"github.com/traefik/traefik/cluster"
"github.com/traefik/traefik/log"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/safe"
"github.com/traefik/traefik/types"
"github.com/traefik/traefik/version"
)
var (
// OSCPMustStaple enables OSCP stapling as from https://github.com/xenolf/lego/issues/270
// OSCPMustStaple enables OSCP stapling as from https://github.com/go-acme/lego/issues/270
OSCPMustStaple = false
)
@@ -57,7 +62,7 @@ type ACME struct {
DelayDontCheckDNS flaeg.Duration `description:"(Deprecated) Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` // Deprecated
ACMELogging bool `description:"Enable debug logging of ACME actions."`
OverrideCertificates bool `description:"Enable to override certificates in key-value store when using storeconfig"`
client *acme.Client
client *lego.Client
store cluster.Store
challengeHTTPProvider *challengeHTTPProvider
challengeTLSProvider *challengeTLSProvider
@@ -70,8 +75,6 @@ type ACME struct {
}
func (a *ACME) init() error {
acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
if a.ACMELogging {
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.InfoLevel), "legolog: ", 0)
} else {
@@ -89,7 +92,7 @@ func (a *ACME) init() error {
// AddRoutes add routes on internal router
func (a *ACME) AddRoutes(router *mux.Router) {
router.Methods(http.MethodGet).
Path(acme.HTTP01ChallengePath("{token}")).
Path(http01.ChallengePath("{token}")).
Handler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if a.challengeHTTPProvider == nil {
rw.WriteHeader(http.StatusNotFound)
@@ -222,7 +225,7 @@ func (a *ACME) leadershipListener(elected bool) error {
// New users will need to register; be sure to save it
log.Debug("Register...")
reg, err := a.client.Register(true)
reg, err := a.client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
if err != nil {
return err
}
@@ -367,7 +370,7 @@ func (a *ACME) renewCertificates() {
}
func (a *ACME) renewACMECertificate(certificateResource *DomainsCertificate) (*Certificate, error) {
renewedCert, err := a.client.RenewCertificate(acme.CertificateResource{
renewedCert, err := a.client.Certificate.Renew(certificate.Resource{
Domain: certificateResource.Certificate.Domain,
CertURL: certificateResource.Certificate.CertURL,
CertStableURL: certificateResource.Certificate.CertStableURL,
@@ -416,28 +419,19 @@ func (a *ACME) storeRenewedCertificate(certificateResource *DomainsCertificate,
return nil
}
func dnsOverrideDelay(delay flaeg.Duration) error {
var err error
if delay > 0 {
log.Debugf("Delaying %d rather than validating DNS propagation", delay)
acme.PreCheckDNS = func(_, _ string) (bool, error) {
time.Sleep(time.Duration(delay))
return true, nil
}
} else if delay < 0 {
err = fmt.Errorf("invalid negative DelayBeforeCheck: %d", delay)
}
return err
}
func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
func (a *ACME) buildACMEClient(account *Account) (*lego.Client, error) {
log.Debug("Building ACME client...")
caServer := "https://acme-v02.api.letsencrypt.org/directory"
if len(a.CAServer) > 0 {
caServer = a.CAServer
}
client, err := acme.NewClient(caServer, account, account.KeyType)
config := lego.NewConfig(account)
config.CADirURL = caServer
config.Certificate.KeyType = account.KeyType
config.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
client, err := lego.NewClient(config)
if err != nil {
return nil, err
}
@@ -446,22 +440,23 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
if a.DNSChallenge != nil && len(a.DNSChallenge.Provider) > 0 {
log.Debugf("Using DNS Challenge provider: %s", a.DNSChallenge.Provider)
err = dnsOverrideDelay(a.DNSChallenge.DelayBeforeCheck)
if err != nil {
return nil, err
}
acmeprovider.SetRecursiveNameServers(a.DNSChallenge.Resolvers)
acmeprovider.SetPropagationCheck(a.DNSChallenge.DisablePropagationCheck)
var provider acme.ChallengeProvider
var provider challenge.Provider
provider, err = dns.NewDNSChallengeProviderByName(a.DNSChallenge.Provider)
if err != nil {
return nil, err
}
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSALPN01})
err = client.SetChallengeProvider(acme.DNS01, provider)
err = client.Challenge.SetDNS01Provider(provider,
dns01.CondOption(len(a.DNSChallenge.Resolvers) > 0, dns01.AddRecursiveNameservers(a.DNSChallenge.Resolvers)),
dns01.CondOption(a.DNSChallenge.DisablePropagationCheck || a.DNSChallenge.DelayBeforeCheck > 0,
dns01.AddPreCheck(func(_, _ string) (bool, error) {
if a.DNSChallenge.DelayBeforeCheck > 0 {
log.Debugf("Delaying %d rather than validating DNS propagation now.", a.DNSChallenge.DelayBeforeCheck)
time.Sleep(time.Duration(a.DNSChallenge.DelayBeforeCheck))
}
return true, nil
})),
)
return client, err
}
@@ -469,17 +464,16 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
if a.HTTPChallenge != nil && len(a.HTTPChallenge.EntryPoint) > 0 {
log.Debug("Using HTTP Challenge provider.")
client.ExcludeChallenges([]acme.Challenge{acme.DNS01, acme.TLSALPN01})
a.challengeHTTPProvider = &challengeHTTPProvider{store: a.store}
err = client.SetChallengeProvider(acme.HTTP01, a.challengeHTTPProvider)
err = client.Challenge.SetHTTP01Provider(a.challengeHTTPProvider)
return client, err
}
// TLS Challenge
if a.TLSChallenge != nil {
log.Debug("Using TLS Challenge provider.")
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.DNS01})
err = client.SetChallengeProvider(acme.TLSALPN01, a.challengeTLSProvider)
err = client.Challenge.SetTLSALPN01Provider(a.challengeTLSProvider)
return client, err
}
@@ -551,7 +545,7 @@ func (a *ACME) LoadCertificateForDomains(domains []string) {
a.addResolvingDomains(uncheckedDomains)
defer a.removeResolvingDomains(uncheckedDomains)
certificate, err := a.getDomainsCertificates(uncheckedDomains)
cert, err := a.getDomainsCertificates(uncheckedDomains)
if err != nil {
log.Errorf("Error getting ACME certificates %+v : %v", uncheckedDomains, err)
return
@@ -570,7 +564,7 @@ func (a *ACME) LoadCertificateForDomains(domains []string) {
domain = types.Domain{Main: uncheckedDomains[0]}
}
account = object.(*Account)
_, err = account.DomainsCertificate.addCertificateForDomains(certificate, domain)
_, err = account.DomainsCertificate.addCertificateForDomains(cert, domain)
if err != nil {
log.Errorf("Error adding ACME certificates %+v : %v", uncheckedDomains, err)
return
@@ -698,7 +692,7 @@ func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) {
var cleanDomains []string
for _, domain := range domains {
canonicalDomain := types.CanonicalDomain(domain)
cleanDomain := acme.UnFqdn(canonicalDomain)
cleanDomain := dns01.UnFqdn(canonicalDomain)
if canonicalDomain != cleanDomain {
log.Warnf("FQDN detected, please remove the trailing dot: %s", canonicalDomain)
}
@@ -708,18 +702,24 @@ func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) {
log.Debugf("Loading ACME certificates %s...", cleanDomains)
bundle := true
certificate, err := a.client.ObtainCertificate(cleanDomains, bundle, nil, OSCPMustStaple)
request := certificate.ObtainRequest{
Domains: cleanDomains,
Bundle: bundle,
MustStaple: OSCPMustStaple,
}
cert, err := a.client.Certificate.Obtain(request)
if err != nil {
return nil, fmt.Errorf("cannot obtain certificates: %+v", err)
}
log.Debugf("Loaded ACME certificates %s", cleanDomains)
return &Certificate{
Domain: certificate.Domain,
CertURL: certificate.CertURL,
CertStableURL: certificate.CertStableURL,
PrivateKey: certificate.PrivateKey,
Certificate: certificate.Certificate,
Domain: cert.Domain,
CertURL: cert.CertURL,
CertStableURL: cert.CertStableURL,
PrivateKey: cert.PrivateKey,
Certificate: cert.Certificate,
}, nil
}
@@ -751,12 +751,6 @@ func (a *ACME) getValidDomains(domains []string, wildcardAllowed bool) ([]string
return nil, fmt.Errorf("unable to generate a wildcard certificate for domain %q : ACME does not allow '*.*' wildcard domain", strings.Join(domains, ","))
}
}
for _, san := range domains[1:] {
if strings.HasPrefix(san, "*") {
return nil, fmt.Errorf("unable to generate a certificate for domains %q: SANs can not be a wildcard domain", strings.Join(domains, ","))
}
}
domains = fun.Map(types.CanonicalDomain, domains).([]string)
return domains, nil

View File

@@ -11,11 +11,10 @@ import (
"testing"
"time"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/tls/generate"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/xenolf/lego/acme"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/tls/generate"
"github.com/traefik/traefik/types"
)
func TestDomainsSet(t *testing.T) {
@@ -258,39 +257,10 @@ func TestRemoveDuplicates(t *testing.T) {
}
}
func TestNoPreCheckOverride(t *testing.T) {
acme.PreCheckDNS = nil // Irreversable - but not expecting real calls into this during testing process
err := dnsOverrideDelay(0)
if err != nil {
t.Errorf("Error in dnsOverrideDelay :%v", err)
}
if acme.PreCheckDNS != nil {
t.Error("Unexpected change to acme.PreCheckDNS when leaving DNS verification as is.")
}
}
func TestSillyPreCheckOverride(t *testing.T) {
err := dnsOverrideDelay(-5)
if err == nil {
t.Error("Missing expected error in dnsOverrideDelay!")
}
}
func TestPreCheckOverride(t *testing.T) {
acme.PreCheckDNS = nil // Irreversable - but not expecting real calls into this during testing process
err := dnsOverrideDelay(5)
if err != nil {
t.Errorf("Error in dnsOverrideDelay :%v", err)
}
if acme.PreCheckDNS == nil {
t.Error("No change to acme.PreCheckDNS when meant to be adding enforcing override function.")
}
}
func TestAcmeClientCreation(t *testing.T) {
acme.PreCheckDNS = nil // Irreversable - but not expecting real calls into this during testing process
// Lengthy setup to avoid external web requests - oh for easier golang testing!
account := &Account{Email: "f@f"}
account.PrivateKey, _ = base64.StdEncoding.DecodeString(`
MIIBPAIBAAJBAMp2Ni92FfEur+CAvFkgC12LT4l9D53ApbBpDaXaJkzzks+KsLw9zyAxvlrfAyTCQ
7tDnEnIltAXyQ0uOFUUdcMCAwEAAQJAK1FbipATZcT9cGVa5x7KD7usytftLW14heQUPXYNV80r/3
@@ -298,8 +268,9 @@ lmnpvjL06dffRpwkYeN8DATQF/QOcy3NNNGDw/4QIhAPAKmiZFxA/qmRXsuU8Zhlzf16WrNZ68K64
asn/h3qZrAiEA1+wFR3WXCPIolOvd7AHjfgcTKQNkoMPywU4FYUNQ1AkCIQDv8yk0qPjckD6HVCPJ
llJh9MC0svjevGtNlxJoE3lmEQIhAKXy1wfZ32/XtcrnENPvi6lzxI0T94X7s5pP3aCoPPoJAiEAl
cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`{
_, err := w.Write([]byte(`{
"GPHhmRVEDas": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
"keyChange": "https://foo/acme/key-change",
"meta": {
@@ -310,9 +281,20 @@ cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
"newOrder": "https://foo/acme/new-order",
"revokeCert": "https://foo/acme/revoke-cert"
}`))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}))
defer ts.Close()
a := ACME{DNSChallenge: &acmeprovider.DNSChallenge{Provider: "manual", DelayBeforeCheck: 10}, CAServer: ts.URL}
a := ACME{
CAServer: ts.URL,
DNSChallenge: &acmeprovider.DNSChallenge{
Provider: "manual",
DelayBeforeCheck: 10,
DisablePropagationCheck: true,
},
}
client, err := a.buildACMEClient(account)
if err != nil {
@@ -321,9 +303,6 @@ cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
if client == nil {
t.Error("No client from buildACMEClient!")
}
if acme.PreCheckDNS == nil {
t.Error("No change to acme.PreCheckDNS when meant to be adding enforcing override function.")
}
}
func TestAcme_getUncheckedCertificates(t *testing.T) {
@@ -440,12 +419,12 @@ func TestAcme_getValidDomain(t *testing.T) {
expectedDomains: []string{"*.traefik.wtf", "traefik.wtf"},
},
{
desc: "unexpected SANs",
desc: "wildcard SANs",
domains: []string{"*.traefik.wtf", "*.acme.wtf"},
dnsChallenge: &acmeprovider.DNSChallenge{},
wildcardAllowed: true,
expectedErr: "unable to generate a certificate for domains \"*.traefik.wtf,*.acme.wtf\": SANs can not be a wildcard domain",
expectedDomains: nil,
expectedErr: "",
expectedDomains: []string{"*.traefik.wtf", "*.acme.wtf"},
},
}
for _, test := range testCases {

View File

@@ -6,13 +6,13 @@ import (
"time"
"github.com/cenk/backoff"
"github.com/containous/traefik/cluster"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/xenolf/lego/acme"
"github.com/go-acme/lego/v3/challenge"
"github.com/traefik/traefik/cluster"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/safe"
)
var _ acme.ChallengeProviderTimeout = (*challengeHTTPProvider)(nil)
var _ challenge.ProviderTimeout = (*challengeHTTPProvider)(nil)
type challengeHTTPProvider struct {
store cluster.Store

View File

@@ -8,13 +8,14 @@ import (
"time"
"github.com/cenk/backoff"
"github.com/containous/traefik/cluster"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/xenolf/lego/acme"
"github.com/go-acme/lego/v3/challenge"
"github.com/go-acme/lego/v3/challenge/tlsalpn01"
"github.com/traefik/traefik/cluster"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/safe"
)
var _ acme.ChallengeProviderTimeout = (*challengeTLSProvider)(nil)
var _ challenge.ProviderTimeout = (*challengeTLSProvider)(nil)
type challengeTLSProvider struct {
store cluster.Store
@@ -113,7 +114,7 @@ func (c *challengeTLSProvider) Timeout() (timeout, interval time.Duration) {
}
func tlsALPN01ChallengeCert(domain, keyAuth string) (*ChallengeCert, error) {
tempCertPEM, rsaPrivPEM, err := acme.TLSALPNChallengeBlocks(domain, keyAuth)
tempCertPEM, rsaPrivPEM, err := tlsalpn01.ChallengeBlocks(domain, keyAuth)
if err != nil {
return nil, err
}

View File

@@ -5,8 +5,8 @@ import (
"io/ioutil"
"os"
"github.com/containous/traefik/log"
"github.com/containous/traefik/provider/acme"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/provider/acme"
)
// LocalStore is a store using a file as storage

View File

@@ -7,32 +7,32 @@ import (
"time"
"github.com/containous/flaeg"
"github.com/containous/traefik/acme"
"github.com/containous/traefik/api"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/middlewares"
"github.com/containous/traefik/provider"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/provider/boltdb"
"github.com/containous/traefik/provider/consul"
"github.com/containous/traefik/provider/consulcatalog"
"github.com/containous/traefik/provider/docker"
"github.com/containous/traefik/provider/dynamodb"
"github.com/containous/traefik/provider/ecs"
"github.com/containous/traefik/provider/etcd"
"github.com/containous/traefik/provider/eureka"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/provider/kubernetes"
"github.com/containous/traefik/provider/kv"
"github.com/containous/traefik/provider/marathon"
"github.com/containous/traefik/provider/mesos"
"github.com/containous/traefik/provider/rancher"
"github.com/containous/traefik/provider/zk"
"github.com/containous/traefik/safe"
traefiktls "github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/elazarl/go-bindata-assetfs"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/thoas/stats"
"github.com/traefik/traefik/acme"
"github.com/traefik/traefik/api"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/middlewares"
"github.com/traefik/traefik/provider"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/provider/boltdb"
"github.com/traefik/traefik/provider/consul"
"github.com/traefik/traefik/provider/consulcatalog"
"github.com/traefik/traefik/provider/docker"
"github.com/traefik/traefik/provider/dynamodb"
"github.com/traefik/traefik/provider/ecs"
"github.com/traefik/traefik/provider/etcd"
"github.com/traefik/traefik/provider/eureka"
"github.com/traefik/traefik/provider/file"
"github.com/traefik/traefik/provider/kubernetes"
"github.com/traefik/traefik/provider/kv"
"github.com/traefik/traefik/provider/marathon"
"github.com/traefik/traefik/provider/mesos"
"github.com/traefik/traefik/provider/rancher"
"github.com/traefik/traefik/provider/zk"
"github.com/traefik/traefik/safe"
traefiktls "github.com/traefik/traefik/tls"
"github.com/traefik/traefik/types"
)
func TestDo_globalConfiguration(t *testing.T) {

View File

@@ -2,10 +2,11 @@ package api
import (
"net/http"
"net/url"
"github.com/containous/mux"
"github.com/containous/traefik/log"
"github.com/elazarl/go-bindata-assetfs"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/traefik/traefik/log"
)
// DashboardHandler expose dashboard routes
@@ -23,17 +24,35 @@ func (g DashboardHandler) AddRoutes(router *mux.Router) {
// Expose dashboard
router.Methods(http.MethodGet).
Path("/").
HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
http.Redirect(response, request, request.Header.Get("X-Forwarded-Prefix")+"/dashboard/", 302)
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
http.Redirect(resp, req, safePrefix(req)+"/dashboard/", 302)
})
router.Methods(http.MethodGet).
Path("/dashboard/status").
HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
http.Redirect(response, request, "/dashboard/", 302)
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
http.Redirect(resp, req, "/dashboard/", 302)
})
router.Methods(http.MethodGet).
PathPrefix("/dashboard/").
Handler(http.StripPrefix("/dashboard/", http.FileServer(g.Assets)))
}
func safePrefix(req *http.Request) string {
prefix := req.Header.Get("X-Forwarded-Prefix")
if prefix == "" {
return ""
}
parse, err := url.Parse(prefix)
if err != nil {
return ""
}
if parse.Host != "" {
return ""
}
return parse.Path
}

54
api/dashboard_test.go Normal file
View File

@@ -0,0 +1,54 @@
package api
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_safePrefix(t *testing.T) {
testCases := []struct {
desc string
value string
expected string
}{
{
desc: "host",
value: "https://example.com",
expected: "",
},
{
desc: "host with path",
value: "https://example.com/foo/bar?test",
expected: "",
},
{
desc: "path",
value: "/foo/bar",
expected: "/foo/bar",
},
{
desc: "path without leading slash",
value: "foo/bar",
expected: "foo/bar",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
req, err := http.NewRequest(http.MethodGet, "http://localhost", nil)
require.NoError(t, err)
req.Header.Set("X-Forwarded-Prefix", test.value)
prefix := safePrefix(req)
assert.Equal(t, test.expected, prefix)
})
}
}

View File

@@ -4,13 +4,13 @@ import (
"net/http"
"github.com/containous/mux"
"github.com/containous/traefik/log"
"github.com/containous/traefik/middlewares"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/containous/traefik/version"
"github.com/elazarl/go-bindata-assetfs"
assetfs "github.com/elazarl/go-bindata-assetfs"
thoas_stats "github.com/thoas/stats"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/middlewares"
"github.com/traefik/traefik/safe"
"github.com/traefik/traefik/types"
"github.com/traefik/traefik/version"
"github.com/unrolled/render"
)

View File

@@ -159,6 +159,9 @@ var _templatesConsul_catalogTmpl = []byte(`[backends]
{{if $loadBalancer.Stickiness }}
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -236,6 +239,18 @@ var _templatesConsul_catalogTmpl = []byte(`[backends]
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Subject }}
{{if $issuer }}
[frontends."frontend-{{ $service.ServiceName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -642,6 +657,9 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
{{if $loadBalancer.Stickiness }}
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -719,6 +737,18 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Issuer }}
{{if $issuer }}
[frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -976,6 +1006,9 @@ var _templatesEcsTmpl = []byte(`[backends]
{{if $loadBalancer.Stickiness }}
[backends."backend-{{ $serviceName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -1055,6 +1088,18 @@ var _templatesEcsTmpl = []byte(`[backends]
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Issuer }}
{{if $issuer }}
[frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -1280,7 +1325,7 @@ var _templatesKubernetesTmpl = []byte(`[backends]
{{if $backend.ResponseForwarding }}
[backends."{{ $backendName }}".responseForwarding]
flushInterval = "{{ $backend.responseForwarding.FlushInterval }}"
flushInterval = "{{ $backend.ResponseForwarding.FlushInterval }}"
{{end}}
[backends."{{ $backendName }}".loadBalancer]
@@ -1289,6 +1334,9 @@ var _templatesKubernetesTmpl = []byte(`[backends]
{{if $backend.LoadBalancer.Stickiness }}
[backends."{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $backend.LoadBalancer.Stickiness.CookieName }}"
secure = {{ $backend.LoadBalancer.Stickiness.Secure }}
httpOnly = {{ $backend.LoadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $backend.LoadBalancer.Stickiness.SameSite }}"
{{end}}
{{if $backend.MaxConn }}
@@ -1329,7 +1377,9 @@ var _templatesKubernetesTmpl = []byte(`[backends]
{{if $frontend.Auth }}
[frontends."{{ $frontendName }}".auth]
headerField = "X-WebAuth-User"
{{if $frontend.Auth.HeaderField }}
headerField = "{{ $frontend.Auth.HeaderField }}"
{{end}}
{{if $frontend.Auth.Basic }}
[frontends."{{ $frontendName }}".auth.basic]
@@ -1422,6 +1472,18 @@ var _templatesKubernetesTmpl = []byte(`[backends]
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Subject }}
{{if $issuer }}
[frontends."{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -1532,6 +1594,9 @@ var _templatesKvTmpl = []byte(`[backends]
{{if $loadBalancer.Stickiness }}
[backends."{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -1609,6 +1674,18 @@ var _templatesKvTmpl = []byte(`[backends]
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Subject }}
{{if $issuer }}
[frontends."{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -1908,6 +1985,9 @@ var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }}
{{if $loadBalancer.Stickiness }}
[backends."{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -1985,6 +2065,18 @@ var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }}
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Subject }}
{{if $issuer }}
[frontends."{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -2228,6 +2320,9 @@ var _templatesMesosTmpl = []byte(`[backends]
{{if $loadBalancer.Stickiness }}
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -2305,6 +2400,18 @@ var _templatesMesosTmpl = []byte(`[backends]
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Subject }}
{{if $issuer }}
[frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}
@@ -2602,6 +2709,9 @@ var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }}
{{if $loadBalancer.Stickiness }}
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
secure = {{ $loadBalancer.Stickiness.Secure }}
httpOnly = {{ $loadBalancer.Stickiness.HTTPOnly }}
sameSite = "{{ $loadBalancer.Stickiness.SameSite }}"
{{end}}
{{end}}
@@ -2678,6 +2788,18 @@ var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }}
organization = {{ $subject.Organization }}
commonName = {{ $subject.CommonName }}
serialNumber = {{ $subject.SerialNumber }}
domainComponent = {{ $subject.DomainComponent }}
{{end}}
{{ $issuer := $infos.Subject }}
{{if $issuer }}
[frontends."frontend-{{ $frontendName }}".passTLSClientCert.infos.issuer]
country = {{ $issuer.Country }}
province = {{ $issuer.Province }}
locality = {{ $issuer.Locality }}
organization = {{ $issuer.Organization }}
commonName = {{ $issuer.CommonName }}
serialNumber = {{ $issuer.SerialNumber }}
domainComponent = {{ $issuer.DomainComponent }}
{{end}}
{{end}}
{{end}}

View File

@@ -1,27 +1,34 @@
FROM golang:1.11-alpine
FROM golang:1.16-alpine
RUN apk --update upgrade \
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar \
&& rm -rf /var/cache/apk/*
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
&& update-ca-certificates \
&& rm -rf /var/cache/apk/*
RUN go get github.com/containous/go-bindata/... \
&& go get golang.org/x/lint/golint \
&& go get github.com/kisielk/errcheck \
RUN go get golang.org/x/lint/golint \
&& go get github.com/client9/misspell/cmd/misspell
# Which docker version to test on
ARG DOCKER_VERSION=17.03.2
ARG DEP_VERSION=0.4.1
# Download dep binary to bin folder in $GOPATH
RUN mkdir -p /usr/local/bin \
&& curl -fsSL -o /usr/local/bin/dep https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 \
&& chmod +x /usr/local/bin/dep
ARG DOCKER_VERSION=18.09.7
# Download docker
RUN mkdir -p /usr/local/bin \
&& curl -fL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}-ce.tgz \
&& curl -fL https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz \
| tar -xzC /usr/local/bin --transform 's#^.+/##x'
WORKDIR /go/src/github.com/containous/traefik
COPY . /go/src/github.com/containous/traefik
# Download go-bindata binary to bin folder in $GOPATH
RUN mkdir -p /usr/local/bin \
&& curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \
&& chmod +x /usr/local/bin/go-bindata
# Download misspell binary to bin folder in $GOPATH
RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4
WORKDIR /go/src/github.com/traefik/traefik
# Download go modules
COPY go.mod .
COPY go.sum .
RUN GO111MODULE=on GOPROXY=https://proxy.golang.org go mod download
COPY . /go/src/github.com/traefik/traefik

View File

@@ -10,10 +10,10 @@ import (
"github.com/abronan/valkeyrie/store"
"github.com/cenk/backoff"
"github.com/containous/staert"
"github.com/containous/traefik/job"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/satori/go.uuid"
"github.com/google/uuid"
"github.com/traefik/traefik/job"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/safe"
)
// Metadata stores Object plus metadata
@@ -125,7 +125,7 @@ func (d *Datastore) reload() error {
// Begin creates a transaction with the KV store.
func (d *Datastore) Begin() (Transaction, Object, error) {
id := uuid.NewV4().String()
id := uuid.New().String()
log.Debugf("Transaction %s begins", id)
remoteLock, err := d.kv.NewLock(d.lockKey, &store.LockOptions{TTL: 20 * time.Second, Value: []byte(id)})
if err != nil {

View File

@@ -7,10 +7,10 @@ import (
"github.com/cenk/backoff"
"github.com/containous/mux"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/docker/leadership"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/safe"
"github.com/traefik/traefik/types"
"github.com/unrolled/render"
)

View File

@@ -9,13 +9,13 @@ import (
"text/template"
"github.com/containous/flaeg"
"github.com/containous/traefik/anonymize"
"github.com/containous/traefik/cmd"
"github.com/containous/traefik/cmd/version"
"github.com/traefik/traefik/anonymize"
"github.com/traefik/traefik/cmd"
"github.com/traefik/traefik/cmd/version"
)
const (
bugTracker = "https://github.com/containous/traefik/issues/new"
bugTracker = "https://github.com/traefik/traefik/issues/new"
bugTemplate = `<!--
DO NOT FILE ISSUES FOR GENERAL SUPPORT QUESTIONS.

View File

@@ -3,13 +3,13 @@ package bug
import (
"testing"
"github.com/containous/traefik/anonymize"
"github.com/containous/traefik/cmd"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/traefik/traefik/anonymize"
"github.com/traefik/traefik/cmd"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/provider/file"
"github.com/traefik/traefik/tls"
"github.com/traefik/traefik/types"
)
func Test_createReport(t *testing.T) {

View File

@@ -4,32 +4,32 @@ import (
"time"
"github.com/containous/flaeg"
"github.com/containous/traefik-extra-service-fabric"
"github.com/containous/traefik/api"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/middlewares/accesslog"
"github.com/containous/traefik/middlewares/tracing"
"github.com/containous/traefik/middlewares/tracing/datadog"
"github.com/containous/traefik/middlewares/tracing/jaeger"
"github.com/containous/traefik/middlewares/tracing/zipkin"
"github.com/containous/traefik/ping"
"github.com/containous/traefik/provider/boltdb"
"github.com/containous/traefik/provider/consul"
"github.com/containous/traefik/provider/consulcatalog"
"github.com/containous/traefik/provider/docker"
"github.com/containous/traefik/provider/dynamodb"
"github.com/containous/traefik/provider/ecs"
"github.com/containous/traefik/provider/etcd"
"github.com/containous/traefik/provider/eureka"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/provider/kubernetes"
"github.com/containous/traefik/provider/marathon"
"github.com/containous/traefik/provider/mesos"
"github.com/containous/traefik/provider/rancher"
"github.com/containous/traefik/provider/rest"
"github.com/containous/traefik/provider/zk"
"github.com/containous/traefik/types"
servicefabric "github.com/containous/traefik-extra-service-fabric"
sf "github.com/jjcollinge/servicefabric"
"github.com/traefik/traefik/api"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/middlewares/accesslog"
"github.com/traefik/traefik/middlewares/tracing"
"github.com/traefik/traefik/middlewares/tracing/datadog"
"github.com/traefik/traefik/middlewares/tracing/jaeger"
"github.com/traefik/traefik/middlewares/tracing/zipkin"
"github.com/traefik/traefik/ping"
"github.com/traefik/traefik/provider/boltdb"
"github.com/traefik/traefik/provider/consul"
"github.com/traefik/traefik/provider/consulcatalog"
"github.com/traefik/traefik/provider/docker"
"github.com/traefik/traefik/provider/dynamodb"
"github.com/traefik/traefik/provider/ecs"
"github.com/traefik/traefik/provider/etcd"
"github.com/traefik/traefik/provider/eureka"
"github.com/traefik/traefik/provider/file"
"github.com/traefik/traefik/provider/kubernetes"
"github.com/traefik/traefik/provider/marathon"
"github.com/traefik/traefik/provider/mesos"
"github.com/traefik/traefik/provider/rancher"
"github.com/traefik/traefik/provider/rest"
"github.com/traefik/traefik/provider/zk"
"github.com/traefik/traefik/types"
)
// TraefikConfiguration holds GlobalConfiguration and other stuff
@@ -46,6 +46,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
defaultDocker.ExposedByDefault = true
defaultDocker.Endpoint = "unix:///var/run/docker.sock"
defaultDocker.SwarmMode = false
defaultDocker.SwarmModeRefreshSeconds = 15
// default File
var defaultFile file.Provider
@@ -110,6 +111,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
defaultConsulCatalog.Prefix = "traefik"
defaultConsulCatalog.FrontEndRule = "Host:{{.ServiceName}}.{{.Domain}}"
defaultConsulCatalog.Stale = false
defaultConsulCatalog.StrictChecks = true
// default Etcd
var defaultEtcd etcd.Provider
@@ -223,10 +225,11 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
ServiceName: "traefik",
SpanNameLimit: 0,
Jaeger: &jaeger.Config{
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
TraceContextHeaderName: "uber-trace-id",
},
Zipkin: &zipkin.Config{
HTTPEndpoint: "http://localhost:9411/api/v1/spans",
@@ -238,6 +241,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
LocalAgentHostPort: "localhost:8126",
GlobalTag: "",
Debug: false,
PrioritySampling: false,
},
}

View File

@@ -9,8 +9,8 @@ import (
"time"
"github.com/containous/flaeg"
"github.com/containous/traefik/cmd"
"github.com/containous/traefik/configuration"
"github.com/traefik/traefik/cmd"
"github.com/traefik/traefik/configuration"
)
// NewCmd builds a new HealthCheck command

View File

@@ -10,10 +10,10 @@ import (
"github.com/abronan/valkeyrie/store"
"github.com/containous/flaeg"
"github.com/containous/staert"
"github.com/containous/traefik/acme"
"github.com/containous/traefik/cluster"
"github.com/containous/traefik/cmd"
"github.com/containous/traefik/log"
"github.com/traefik/traefik/acme"
"github.com/traefik/traefik/cluster"
"github.com/traefik/traefik/cmd"
"github.com/traefik/traefik/log"
)
// NewCmd builds a new StoreConfig command

View File

@@ -14,29 +14,29 @@ import (
"github.com/cenk/backoff"
"github.com/containous/flaeg"
"github.com/containous/staert"
"github.com/containous/traefik/autogen/genstatic"
"github.com/containous/traefik/cmd"
"github.com/containous/traefik/cmd/bug"
"github.com/containous/traefik/cmd/healthcheck"
"github.com/containous/traefik/cmd/storeconfig"
cmdVersion "github.com/containous/traefik/cmd/version"
"github.com/containous/traefik/collector"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/configuration/router"
"github.com/containous/traefik/job"
"github.com/containous/traefik/log"
"github.com/containous/traefik/provider/ecs"
"github.com/containous/traefik/provider/kubernetes"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/server"
"github.com/containous/traefik/server/uuid"
traefiktls "github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/containous/traefik/version"
"github.com/coreos/go-systemd/daemon"
"github.com/elazarl/go-bindata-assetfs"
assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/ogier/pflag"
"github.com/sirupsen/logrus"
"github.com/traefik/traefik/autogen/genstatic"
"github.com/traefik/traefik/cmd"
"github.com/traefik/traefik/cmd/bug"
"github.com/traefik/traefik/cmd/healthcheck"
"github.com/traefik/traefik/cmd/storeconfig"
cmdVersion "github.com/traefik/traefik/cmd/version"
"github.com/traefik/traefik/collector"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/configuration/router"
"github.com/traefik/traefik/job"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/provider/ecs"
"github.com/traefik/traefik/provider/kubernetes"
"github.com/traefik/traefik/safe"
"github.com/traefik/traefik/server"
"github.com/traefik/traefik/server/uuid"
traefiktls "github.com/traefik/traefik/tls"
"github.com/traefik/traefik/types"
"github.com/traefik/traefik/version"
"github.com/vulcand/oxy/roundrobin"
)
@@ -352,14 +352,14 @@ func stats(globalConfiguration *configuration.GlobalConfiguration) {
Stats collection is enabled.
Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.
Help us improve Traefik by leaving this feature on :)
More details on: https://docs.traefik.io/basics/#collected-data
More details on: https://doc.traefik.io/traefik/v1.7/basics/#collected-data
`)
collect(globalConfiguration)
} else {
log.Info(`
Stats collection is disabled.
Help us improve Traefik by turning this feature on :)
More details on: https://docs.traefik.io/basics/#collected-data
More details on: https://doc.traefik.io/traefik/v1.7/basics/#collected-data
`)
}
}

View File

@@ -8,7 +8,7 @@ import (
"text/template"
"github.com/containous/flaeg"
"github.com/containous/traefik/version"
"github.com/traefik/traefik/version"
)
var versionTemplate = `Version: {{.Version}}

View File

@@ -9,11 +9,11 @@ import (
"strconv"
"time"
"github.com/containous/traefik/anonymize"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/log"
"github.com/containous/traefik/version"
"github.com/mitchellh/hashstructure"
"github.com/traefik/traefik/anonymize"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/version"
)
// collectorURL URL where the stats are send

View File

@@ -1,40 +1,41 @@
package configuration
import (
"errors"
"fmt"
"strings"
"time"
"github.com/containous/flaeg"
"github.com/containous/traefik-extra-service-fabric"
"github.com/containous/traefik/acme"
"github.com/containous/traefik/api"
"github.com/containous/traefik/log"
"github.com/containous/traefik/middlewares/tracing"
"github.com/containous/traefik/middlewares/tracing/datadog"
"github.com/containous/traefik/middlewares/tracing/jaeger"
"github.com/containous/traefik/middlewares/tracing/zipkin"
"github.com/containous/traefik/ping"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/provider/boltdb"
"github.com/containous/traefik/provider/consul"
"github.com/containous/traefik/provider/consulcatalog"
"github.com/containous/traefik/provider/docker"
"github.com/containous/traefik/provider/dynamodb"
"github.com/containous/traefik/provider/ecs"
"github.com/containous/traefik/provider/etcd"
"github.com/containous/traefik/provider/eureka"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/provider/kubernetes"
"github.com/containous/traefik/provider/marathon"
"github.com/containous/traefik/provider/mesos"
"github.com/containous/traefik/provider/rancher"
"github.com/containous/traefik/provider/rest"
"github.com/containous/traefik/provider/zk"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/pkg/errors"
lego "github.com/xenolf/lego/acme"
servicefabric "github.com/containous/traefik-extra-service-fabric"
"github.com/go-acme/lego/v3/challenge/dns01"
"github.com/traefik/traefik/acme"
"github.com/traefik/traefik/api"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/middlewares/tracing"
"github.com/traefik/traefik/middlewares/tracing/datadog"
"github.com/traefik/traefik/middlewares/tracing/jaeger"
"github.com/traefik/traefik/middlewares/tracing/zipkin"
"github.com/traefik/traefik/ping"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/provider/boltdb"
"github.com/traefik/traefik/provider/consul"
"github.com/traefik/traefik/provider/consulcatalog"
"github.com/traefik/traefik/provider/docker"
"github.com/traefik/traefik/provider/dynamodb"
"github.com/traefik/traefik/provider/ecs"
"github.com/traefik/traefik/provider/etcd"
"github.com/traefik/traefik/provider/eureka"
"github.com/traefik/traefik/provider/file"
"github.com/traefik/traefik/provider/kubernetes"
"github.com/traefik/traefik/provider/marathon"
"github.com/traefik/traefik/provider/mesos"
"github.com/traefik/traefik/provider/rancher"
"github.com/traefik/traefik/provider/rest"
"github.com/traefik/traefik/provider/zk"
"github.com/traefik/traefik/tls"
"github.com/traefik/traefik/types"
jaegercli "github.com/uber/jaeger-client-go"
)
const (
@@ -235,6 +236,10 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
} else {
gc.Docker.TemplateVersion = 2
}
if gc.Docker.SwarmModeRefreshSeconds <= 0 {
gc.Docker.SwarmModeRefreshSeconds = 15
}
}
if gc.Marathon != nil {
@@ -331,10 +336,11 @@ func (gc *GlobalConfiguration) initTracing() {
case jaeger.Name:
if gc.Tracing.Jaeger == nil {
gc.Tracing.Jaeger = &jaeger.Config{
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
TraceContextHeaderName: jaegercli.TraceContextHeaderName,
}
}
if gc.Tracing.Zipkin != nil {
@@ -368,6 +374,7 @@ func (gc *GlobalConfiguration) initTracing() {
LocalAgentHostPort: "localhost:8126",
GlobalTag: "",
Debug: false,
PrioritySampling: false,
}
}
if gc.Tracing.Zipkin != nil {
@@ -405,11 +412,11 @@ func (gc *GlobalConfiguration) initACMEProvider() {
}
for _, domain := range gc.ACME.Domains {
if domain.Main != lego.UnFqdn(domain.Main) {
if domain.Main != dns01.UnFqdn(domain.Main) {
log.Warnf("FQDN detected, please remove the trailing dot: %s", domain.Main)
}
for _, san := range domain.SANs {
if san != lego.UnFqdn(san) {
if san != dns01.UnFqdn(san) {
log.Warnf("FQDN detected, please remove the trailing dot: %s", san)
}
}

View File

@@ -5,14 +5,15 @@ import (
"time"
"github.com/containous/flaeg"
"github.com/containous/traefik/acme"
"github.com/containous/traefik/middlewares/tracing"
"github.com/containous/traefik/middlewares/tracing/jaeger"
"github.com/containous/traefik/middlewares/tracing/zipkin"
"github.com/containous/traefik/provider"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/provider/file"
"github.com/stretchr/testify/assert"
"github.com/traefik/traefik/acme"
"github.com/traefik/traefik/middlewares/tracing"
"github.com/traefik/traefik/middlewares/tracing/jaeger"
"github.com/traefik/traefik/middlewares/tracing/zipkin"
"github.com/traefik/traefik/provider"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/provider/file"
"github.com/traefik/traefik/tls"
)
const defaultConfigFile = "traefik.toml"
@@ -142,10 +143,11 @@ func TestSetEffectiveConfigurationTracing(t *testing.T) {
expected: &tracing.Tracing{
Backend: "jaeger",
Jaeger: &jaeger.Config{
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
TraceContextHeaderName: "uber-trace-id",
},
Zipkin: nil,
},
@@ -155,10 +157,11 @@ func TestSetEffectiveConfigurationTracing(t *testing.T) {
tracing: &tracing.Tracing{
Backend: "zipkin",
Jaeger: &jaeger.Config{
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
TraceContextHeaderName: "uber-trace-id",
},
},
expected: &tracing.Tracing{
@@ -177,10 +180,11 @@ func TestSetEffectiveConfigurationTracing(t *testing.T) {
tracing: &tracing.Tracing{
Backend: "zipkin",
Jaeger: &jaeger.Config{
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
SamplingServerURL: "http://localhost:5778/sampling",
SamplingType: "const",
SamplingParam: 1.0,
LocalAgentHostPort: "127.0.0.1:6831",
TraceContextHeaderName: "uber-trace-id",
},
Zipkin: &zipkin.Config{
HTTPEndpoint: "http://powpow:9411/api/v1/spans",
@@ -266,3 +270,67 @@ func TestInitACMEProvider(t *testing.T) {
})
}
}
func TestSetEffectiveConfigurationTLSMinVersion(t *testing.T) {
testCases := []struct {
desc string
provided EntryPoint
expected EntryPoint
}{
{
desc: "Entrypoint with no TLS",
provided: EntryPoint{
Address: ":80",
},
expected: EntryPoint{
Address: ":80",
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
},
},
{
desc: "Entrypoint with TLS Specifying MinVersion",
provided: EntryPoint{
Address: ":443",
TLS: &tls.TLS{
MinVersion: "VersionTLS12",
},
},
expected: EntryPoint{
Address: ":443",
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
TLS: &tls.TLS{
MinVersion: "VersionTLS12",
},
},
},
{
desc: "Entrypoint with TLS without Specifying MinVersion",
provided: EntryPoint{
Address: ":443",
TLS: &tls.TLS{},
},
expected: EntryPoint{
Address: ":443",
ForwardedHeaders: &ForwardedHeaders{Insecure: true},
TLS: &tls.TLS{},
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
gc := &GlobalConfiguration{
EntryPoints: map[string]*EntryPoint{
"foo": &test.provided,
},
}
gc.SetEffectiveConfiguration(defaultConfigFile)
assert.Equal(t, &test.expected, gc.EntryPoints["foo"])
})
}
}

View File

@@ -4,9 +4,9 @@ import (
"fmt"
"strings"
"github.com/containous/traefik/log"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/tls"
"github.com/traefik/traefik/types"
)
// EntryPoint holds an entry point configuration of the reverse proxy (ip, port, TLS...)

View File

@@ -3,10 +3,10 @@ package configuration
import (
"testing"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/tls"
"github.com/traefik/traefik/types"
)
func Test_parseEntryPointsConfiguration(t *testing.T) {

View File

@@ -3,10 +3,10 @@ package configuration
import (
"encoding/json"
"github.com/containous/traefik/log"
"github.com/containous/traefik/provider"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/provider"
"github.com/traefik/traefik/safe"
"github.com/traefik/traefik/types"
)
// ProviderAggregator aggregate providers

View File

@@ -2,12 +2,12 @@ package router
import (
"github.com/containous/mux"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/log"
"github.com/containous/traefik/metrics"
"github.com/containous/traefik/middlewares"
mauth "github.com/containous/traefik/middlewares/auth"
"github.com/containous/traefik/types"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/metrics"
"github.com/traefik/traefik/middlewares"
mauth "github.com/traefik/traefik/middlewares/auth"
"github.com/traefik/traefik/types"
"github.com/urfave/negroni"
)

View File

@@ -6,14 +6,14 @@ import (
"testing"
"github.com/containous/mux"
"github.com/containous/traefik/acme"
"github.com/containous/traefik/api"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/ping"
acmeprovider "github.com/containous/traefik/provider/acme"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/traefik/traefik/acme"
"github.com/traefik/traefik/api"
"github.com/traefik/traefik/configuration"
"github.com/traefik/traefik/ping"
acmeprovider "github.com/traefik/traefik/provider/acme"
"github.com/traefik/traefik/safe"
"github.com/traefik/traefik/types"
"github.com/urfave/negroni"
)

View File

@@ -155,7 +155,8 @@ echo -e "-----BEGIN RSA PRIVATE KEY-----\n${priv}\n-----END RSA PRIVATE KEY-----
| openssl rsa -inform pem -out "${pdir}/letsencrypt.key"
# Process the certificates for each of the domains in acme.json
for domain in $(jq -r '.Certificates[].Domain.Main' ${acmefile}); do
domains=$(jq -r '.Certificates[].Domain.Main' ${acmefile}) || bad_acme
for domain in $domains; do
# Traefik stores a cert bundle for each domain. Within this cert
# bundle there is both proper the certificate and the Let's Encrypt CA
echo "Extracting cert bundle for ${domain}"

View File

@@ -1,11 +1,41 @@
[Unit]
Description=Traefik
Documentation=https://doc.traefik.io/traefik/v1.7
#After=network-online.target
#AssertFileIsExecutable=/usr/bin/traefik
#AssertPathExists=/etc/traefik/traefik.toml
[Service]
# Run traefik as its own user (create new user with: useradd -r -s /bin/false -U -M traefik)
#User=traefik
#AmbientCapabilities=CAP_NET_BIND_SERVICE
# configure service behavior
Type=notify
ExecStart=/usr/bin/traefik --configFile=/etc/traefik.toml
#ExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.toml
Restart=always
WatchdogSec=1s
# lock down system access
# prohibit any operating system and configuration modification
#ProtectSystem=strict
# create separate, new (and empty) /tmp and /var/tmp filesystems
#PrivateTmp=true
# make /home directories inaccessible
#ProtectHome=true
# turns off access to physical devices (/dev/...)
#PrivateDevices=true
# make kernel settings (procfs and sysfs) read-only
#ProtectKernelTunables=true
# make cgroups /sys/fs/cgroup read-only
#ProtectControlGroups=true
# allow writing of acme.json
#ReadWritePaths=/etc/traefik/acme.json
# depending on log and entrypoint configuration, you may need to allow writing to other paths, too
# limit number of processes in this unit
#LimitNPROC=1
[Install]
WantedBy=multi-user.target

View File

@@ -1 +0,0 @@
docs.traefik.io

View File

@@ -72,7 +72,7 @@ And here is another example with client certificate authentication:
- We enable SSL on `https` by giving a certificate and a key.
- One or several files containing Certificate Authorities in PEM format are added.
- It is possible to have multiple CA:s in the same file or keep them in separate files.
- It is possible to have multiple CA's in the same file or keep them in separate files.
### Frontends
@@ -94,10 +94,13 @@ Following is the list of existing modifier rules:
Matcher rules determine if a particular request should be forwarded to a backend.
Separate multiple rule values by `,` (comma) in order to enable ANY semantics (i.e., forward a request if any rule matches).
Does not work for `Headers` and `HeadersRegexp`.
The associativity rule is the following:
Separate multiple rule values by `;` (semicolon) in order to enable ALL semantics (i.e., forward a request if all rules match).
- `,` is the `OR` operator (works **only inside a matcher**, ex: `Host:foo.com,bar.com`).
- i.e., forward a request if any rule matches.
- Does not work for `Headers` and `HeadersRegexp`.
- `;` is the `AND` operator (works **only between matchers**, ex: `Host:foo.com;Path:/bar`)
- i.e., forward a request if all rules match
Following is the list of existing matcher rules along with examples:
@@ -234,7 +237,8 @@ The following rules are both `Matchers` and `Modifiers`, so the `Matcher` portio
#### Priorities
By default, routes will be sorted (in descending order) using rules length (to avoid path overlap):
`PathPrefix:/foo;Host:foo.com` (length == 28) will be matched before `PathPrefixStrip:/foobar` (length == 23) will be matched before `PathPrefix:/foo,/bar` (length == 20).
- `PathPrefix:/foo;Host:foo.com` (length == 28) will be matched before `PathPrefixStrip:/foobar` (length == 23) will be matched before `PathPrefix:/foo,/bar` (length == 20).
- A priority value of 0 will be ignored, so the default value will be calculated (rules length).
You can customize priority by frontend. The priority value override the rule length during sorting:
@@ -448,6 +452,27 @@ If not, a new backend will be assigned.
# Default: a sha1 (6 chars)
#
# cookieName = "my_cookie"
# Customize secure option
#
# Optional
# Default: false
#
# secure = true
# Customize http only option
#
# Optional
# Default: false
#
# httpOnly = true
# Customize same site option.
# Can be: "none", "lax", "strict"
#
# Optional
#
# sameSite = "none"
```
The deprecated way:
@@ -627,7 +652,7 @@ docker run traefik[:version] --help
### Command: bug
Here is the easiest way to submit a pre-filled issue on [Traefik GitHub](https://github.com/containous/traefik).
Here is the easiest way to submit a pre-filled issue on [Traefik GitHub](https://github.com/traefik/traefik).
```bash
traefik bug
@@ -656,7 +681,7 @@ OK: http://:8082/ping
**This feature is disabled by default.**
You can read the public proposal on this topic [here](https://github.com/containous/traefik/issues/2369).
You can read the public proposal on this topic [here](https://github.com/traefik/traefik/issues/2369).
### Why ?
@@ -742,12 +767,10 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col
### Show me the code !
If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/containous/traefik/blob/master/collector/collector.go)
If you want to dig into more details, here is the source code of the collecting system: [collector.go](https://github.com/traefik/traefik/blob/v1.7/collector/collector.go)
By default we anonymize all configuration fields, except fields tagged with `export=true`.
You can check all fields in the [godoc](https://godoc.org/github.com/containous/traefik/configuration#GlobalConfiguration).
### How to enable this ?
You can enable the collecting system by:

View File

@@ -15,7 +15,7 @@ I used 4 VMs for the tests with the following configuration:
1. One VM used to launch the benchmarking tool [wrk](https://github.com/wg/wrk)
2. One VM for Traefik (v1.0.0-beta.416) / nginx (v1.4.6)
3. Two VMs for 2 backend servers in go [whoami](https://github.com/containous/whoami/)
3. Two VMs for 2 backend servers in go [whoami](https://github.com/traefik/whoami/)
Each VM has been tuned using the following limits:

View File

@@ -271,58 +271,90 @@ Useful if internal networks block external DNS queries.
##### `provider`
Here is a list of supported `provider`s, that can automate the DNS verification, along with the required environment variables and their [wildcard & root domain support](/configuration/acme/#wildcard-domains) for each. Do not hesitate to complete it.
Here is a list of supported `provider`s, that can automate the DNS verification, along with the required environment variables and their [wildcard & root domain support](/configuration/acme/#wildcard-domains) for each.
Do not hesitate to complete it.
Every lego environment variable can be overridden by their respective `_FILE` counterpart, which should have a filepath to a file that contains the secret as its value.
For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used to provide a Cloudflare API email address as a Docker secret named `traefik_cf-api-email`.
| Provider Name | Provider Code | Environment Variables | Wildcard & Root Domain Support |
|--------------------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acmedns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | Not tested yet |
| [Alibaba Cloud](https://www.vultr.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | Not tested yet |
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | Not tested yet |
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet |
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | Not tested yet |
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | YES |
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | Not tested yet |
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | YES |
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | Not tested yet |
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
| [DNSPod](http://www.dnspod.net/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES |
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | No |
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
| External Program | `exec` | `EXEC_PATH` | Not tested yet |
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | Not tested yet |
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet |
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES |
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | Not tested yet |
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | Not tested yet |
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, `GCE_SERVICE_ACCOUNT_FILE` | YES |
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | Not tested yet |
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | Not tested yet |
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | Not tested yet |
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | Not tested yet |
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | Not tested yet |
| manual | - | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>. | YES |
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | YES |
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | Not tested yet |
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | Not tested yet |
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | Not tested yet |
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | Not tested yet |
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | Not tested yet |
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | YES |
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | Not tested yet |
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | Not tested yet |
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | Not tested yet |
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | YES |
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | Not tested yet |
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | Not tested yet |
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet |
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet |
| Provider Name | Provider Code | Environment Variables | Wildcard & Root Domain Support |
|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | Not tested yet |
| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | Not tested yet |
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | Not tested yet |
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet |
| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | YES |
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | Not tested yet |
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | YES |
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | YES |
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | Not tested yet |
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | YES |
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | YES |
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | YES |
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | YES |
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES |
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | YES |
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | YES |
| External Program | `exec` | `EXEC_PATH` | YES |
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | YES |
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet |
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES |
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | Not tested yet |
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | Not tested yet |
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials (2) (3), [`GCE_SERVICE_ACCOUNT_FILE`] | YES |
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | YES |
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` (1) | YES |
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | Not tested yet |
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | YES |
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | YES |
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | Not tested yet |
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | Not tested yet |
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | Not tested yet |
| manual | `manual` | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>. | YES |
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | YES |
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | YES |
| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | YES |
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | Not tested yet |
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | Not tested yet |
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | Not tested yet |
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | Not tested yet |
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | Not tested yet |
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | YES |
| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | YES |
| [Oracle Cloud](https://cloud.oracle.com/home) | `oraclecloud` | `OCI_COMPARTMENT_OCID`, `OCI_PRIVKEY_FILE`, `OCI_PRIVKEY_PASS`, `OCI_PUBKEY_FINGERPRINT`, `OCI_REGION`, `OCI_TENANCY_OCID`, `OCI_USER_OCID` | YES |
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | Not tested yet |
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | Not tested yet |
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | Not tested yet |
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | YES |
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | Not tested yet |
| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | YES |
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | Not tested yet |
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | YES |
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet |
| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | YES |
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | YES |
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | YES |
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | YES |
- (1): more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/)
- (2): https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
- (3): https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76
#### `resolvers`
Use custom DNS servers to resolve the FQDN authority.
```toml
[acme]
# ...
[acme.dnsChallenge]
# ...
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
```
### `domains`
You can provide SANs (alternative domains) to each main domain.
@@ -367,11 +399,10 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
```
It is not possible to request a double wildcard certificate for a domain (for example `*.*.local.com`).
Due to ACME limitation it is not possible to define wildcards in SANs (alternative domains). Thus, the wildcard domain has to be defined as a main domain.
Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed.
In this case the generated DNS TXT record for both domains is the same.
Even though this behaviour is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, it can lead to problems as all DNS providers keep DNS records cached for a certain time (TTL) and this TTL can be superior to the challenge timeout making the `DNS-01` challenge fail.
The Traefik ACME client library [LEGO](https://github.com/xenolf/lego) supports some but not all DNS providers to work around this issue.
The Traefik ACME client library [LEGO](https://github.com/go-acme/lego) supports some but not all DNS providers to work around this issue.
The [`provider` table](/configuration/acme/#provider) indicates if they allow generating certificates for a wildcard domain and its root domain.
### `onDemand` (Deprecated)

View File

@@ -35,7 +35,7 @@
For more customization, see [entry points](/configuration/entrypoints/) documentation and the examples below.
## Web UI
## Dashboard (Web UI)
![Web UI Providers](/img/web.frontend.png)
@@ -106,10 +106,10 @@ entryPoint = "foo"
entryPoint = "bar"
```
In the above example, you would access a regular path, administration panel, and health-check as follows:
In the above example, you would access a regular path, dashboard, and health-check as follows:
* Regular path: `http://hostname:80/path`
* Admin Panel: `http://hostname:8083/`
* Dashboard: `http://hostname:8083/`
* Ping URL: `http://hostname:8082/ping`
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
@@ -301,7 +301,7 @@ curl -s "http://localhost:8080/health" | jq .
// average response time in seconds
"average_response_time_sec": 0.8648016000000001,
// request statistics [requires --statistics to be set]
// request statistics [requires --api.statistics to be set]
// ten most recent requests with 4xx and 5xx status codes
"recent_errors": [
{
@@ -322,9 +322,12 @@ curl -s "http://localhost:8080/health" | jq .
}
```
## Metrics
## Dashboard Statistics
You can enable Traefik to export internal metrics to different monitoring systems.
You can control how the Traefik's internal metrics are shown in the Dashboard.
If you want to export internal metrics to different monitoring systems,
please check the page [Metrics](./metrics.md).
```toml
[api]

View File

@@ -37,6 +37,15 @@ stale = false
#
domain = "consul.localhost"
# Keep a Consul node only if all checks status are passing
# If true, only the Consul nodes with checks status 'passing' will be kept.
# if false, only the Consul nodes with checks status 'passing' or 'warning' will be kept.
#
# Optional
# Default: true
#
strictChecks = true
# Prefix for Consul catalog tags.
#
# Optional
@@ -94,74 +103,85 @@ Additional settings can be defined using Consul Catalog tags.
!!! note
The default prefix is `traefik`.
| Label | Description |
|----------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `<prefix>.enable=false` | Disables this container in Traefik. |
| `<prefix>.protocol=https` | Overrides the default `http` protocol. |
| `<prefix>.weight=10` | Assigns this weight to the container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `<prefix>.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` |
| `<prefix>.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `<prefix>.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `<prefix>.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `<prefix>.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `<prefix>.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `<prefix>.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `<prefix>.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm. |
| `<prefix>.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions. |
| `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions. |
| `<prefix>.backend.loadbalancer.sticky=true` | Enables backend sticky sessions. (DEPRECATED) |
| `<prefix>.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `<prefix>.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `<prefix>.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `<prefix>.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `<prefix>.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `<prefix>.frontend.auth.basic.usersfile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `<prefix>.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `<prefix>.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `<prefix>.frontend.auth.digest.usersfile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `<prefix>.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `<prefix>.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `<prefix>.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `<prefix>.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `<prefix>.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `<prefix>.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `<prefix>.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `<prefix>.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `<prefix>.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `<prefix>.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `<prefix>.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `<prefix>.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `<prefix>.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `<prefix>.frontend.priority=10` | Overrides default frontend priority. |
| `<prefix>.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS). |
| `<prefix>.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `<prefix>.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `<prefix>.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `<prefix>.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`. |
| `<prefix>.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `<prefix>.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
| Label | Description |
|--------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `<prefix>.enable=false` | Disables this container in Traefik. |
| `<prefix>.protocol=https` | Overrides the default `http` protocol. |
| `<prefix>.weight=10` | Assigns this weight to the container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `<prefix>.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend. ex: `NetworkErrorRatio() > 0.` |
| `<prefix>.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `<prefix>.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `<prefix>.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `<prefix>.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `<prefix>.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `<prefix>.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `<prefix>.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm. |
| `<prefix>.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions. |
| `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions. |
| `<prefix>.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `<prefix>.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions. |
| `<prefix>.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `<prefix>.backend.loadbalancer.sticky=true` | Enables backend sticky sessions. (DEPRECATED) |
| `<prefix>.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `<prefix>.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `<prefix>.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `<prefix>.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `<prefix>.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `<prefix>.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `<prefix>.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `<prefix>.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `<prefix>.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `<prefix>.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `<prefix>.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `<prefix>.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `<prefix>.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `<prefix>.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `<prefix>.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `<prefix>.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `<prefix>.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `<prefix>.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `<prefix>.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `<prefix>.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `<prefix>.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `<prefix>.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `<prefix>.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `<prefix>.frontend.priority=10` | Overrides default frontend priority. |
| `<prefix>.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `<prefix>.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS). |
| `<prefix>.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `<prefix>.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `<prefix>.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `<prefix>.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{{.ServiceName}}.{{.Domain}}`. |
| `<prefix>.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `<prefix>.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
### Multiple frontends for a single service
@@ -207,7 +227,7 @@ If you need to support multiple frontends for a service, for example when having
| `<prefix>.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `<prefix>.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `<prefix>.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. |
| `<prefix>.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `<prefix>.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `<prefix>.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `<prefix>.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `<prefix>.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |

View File

@@ -57,7 +57,7 @@ watch = true
exposedByDefault = true
# Use the IP address from the binded port instead of the inner network one.
#
#
# In case no IP address is attached to the binded port (or in case
# there is no bind), the inner network one will be used as a fallback.
#
@@ -73,6 +73,13 @@ usebindportip = true
#
swarmMode = false
# Polling interval (in seconds) for Swarm Mode.
#
# Optional
# Default: 15
#
swarmModeRefreshSeconds = 15
# Define a default docker network to use for connections to all containers.
# Can be overridden by the traefik.docker.network label.
#
@@ -93,7 +100,6 @@ network = "web"
To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific).
## Docker Swarm Mode
```toml
@@ -110,7 +116,10 @@ To enable constraints see [provider-specific constraints section](/configuration
# Required
# Default: "unix:///var/run/docker.sock"
#
endpoint = "tcp://127.0.0.1:2375"
# swarm classic (1.12-)
# endpoint = "tcp://127.0.0.1:2375"
# docker swarm mode (1.12+)
endpoint = "tcp://127.0.0.1:2377"
# Default base domain used for the frontend rules.
# Can be overridden by setting the "traefik.domain" label on a services.
@@ -177,6 +186,61 @@ exposedByDefault = false
To enable constraints see [provider-specific constraints section](/configuration/commons/#provider-specific).
## Security Considerations
### Security Challenge with the Docker Socket
Traefik requires access to the docker socket to get its dynamic configuration,
by watching the Docker API through this socket.
!!! important
Depending on your context and your usage, accessing the Docker API without any restriction might be a security concern.
As explained on the Docker documentation: ([Docker Daemon Attack Surface page](https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface)):
`[...] only **trusted** users should be allowed to control your Docker daemon [...]`
If the Traefik processes (handling requests from the outside world) is attacked,
then the attacker can access the Docker (or Swarm Mode) backend.
Also, when using Swarm Mode, it is mandatory to schedule Traefik's containers on the Swarm manager nodes,
to let Traefik accessing the Docker Socket of the Swarm manager node.
More information about Docker's security:
- [KubeCon EU 2018 Keynote, Running with Scissors, from Liz Rice](https://www.youtube.com/watch?v=ltrV-Qmh3oY)
- [Don't expose the Docker socket (not even to a container)](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html)
- [A thread on Stack Overflow about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623)
- [To Dind or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html)
### Workarounds
!!! note "Improved Security"
[Traefik Enterprise](https://traefik.io/traefik-enterprise/) solves this problem by separating the control plane (connected to Docker) and the data plane (handling the requests).
Another possible workaround is to expose the Docker socket over TCP, instead of the default Unix socket file.
It allows different implementation levels of the [AAA (Authentication, Authorization, Accounting) concepts](https://en.wikipedia.org/wiki/AAA_(computer_security)), depending on your security assessment:
- Authentication with Client Certificates as described in [the "Protect the Docker daemon socket" page of Docker's documentation](https://docs.docker.com/engine/security/https/)
- Authorization with the [Docker Authorization Plugin Mechanism](https://docs.docker.com/engine/extend/plugins_authorization/)
- Accounting at networking level, by exposing the socket only inside a Docker private network, only available for Traefik.
- Accounting at container level, by exposing the socket on a another container than Traefik's.
With Swarm mode, it allows scheduling of Traefik on worker nodes, with only the "socket exposer" container on the manager nodes.
- Accounting at kernel level, by enforcing kernel calls with mechanisms like [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux),
to only allows an identified set of actions for Traefik's process (or the "socket exposer" process).
Use the following ressources to get started:
- [Traefik issue GH-4174 about security with Docker socket](https://github.com/traefik/traefik/issues/4174)
- [Inspecting Docker Activity with Socat](https://developers.redhat.com/blog/2015/02/25/inspecting-docker-activity-with-socat/)
- [Letting Traefik run on Worker Nodes](https://blog.mikesir87.io/2018/07/letting-traefik-run-on-worker-nodes/)
- [Docker Socket Proxy from Tecnativa](https://github.com/Tecnativa/docker-socket-proxy)
## Labels: overriding default behavior
### Using Docker with Swarm Mode
@@ -193,6 +257,20 @@ services:
traefik.docker.network: traefik
```
Required labels:
- `traefik.frontend.rule`
- `traefik.port` - Without this the debug logs will show this service is deliberately filtered out.
- `traefik.docker.network` - Without this a 504 may occur.
#### Troubleshooting
If service doesn't show up in the dashboard, check the debug logs to see if the port is missing:
`Filtering container without port, <SERVICE_NAME>: port label is missing, ...')`
If `504 Gateway Timeout` occurs and there are networks used, ensure that `traefik.docker.network` is defined.
The complete name is required, meaning if the network is internal the name needs to be `<project_name>_<network_name>`.
### Using Docker Compose
If you are intending to use only Docker Compose commands (e.g. `docker-compose up --scale whoami=2 -d`), labels should be under your service, otherwise they will be ignored.
@@ -209,97 +287,112 @@ services:
Labels can be used on containers to override default behavior.
| Label | Description |
|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.docker.network` | Overrides the default docker network to use for connections to the container. [1] |
| `traefik.domain` | Sets the default base domain for the frontend rules. For more information, check the [Container Labels section's of the user guide "Let's Encrypt & Docker"](/user-guide/docker-and-lets-encrypt/#container-labels) |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. |
| `traefik.tags=foo,bar,myTag` | Adds Traefik tags to the Docker container/service to be used in [constraints](/configuration/commons/#constraints). |
| `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.loadbalancer.swarm=true` | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode). |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2] (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2]. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header user to pass the authenticated user to the application. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend (DEPRECATED). |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
| Label | Description |
|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.docker.network` | Overrides the default docker network to use for connections to the container. [1] |
| `traefik.domain` | Sets the default base domain for the frontend rules. For more information, check the [Container Labels section's of the user guide "Let's Encrypt & Docker"](/user-guide/docker-and-lets-encrypt/#container-labels) |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. |
| `traefik.tags=foo,bar,myTag` | Adds Traefik tags to the Docker container/service to be used in [constraints](/configuration/commons/#constraints). |
| `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Overrides the container name by `foo` in the generated name of the backend. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.loadbalancer.swarm=true` | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode) [3]. |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2] (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` [2]. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header user to pass the authenticated user to the application. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend (DEPRECATED). |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
[1] `traefik.docker.network`:
If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them).
[1] `traefik.docker.network`:
If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them).
For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name.
Or if your service references external network use it's name instead.
[2] `traefik.frontend.auth.basic.users=EXPR `:
[2] `traefik.frontend.auth.basic.users=EXPR`:
To create `user:password` pair, it's possible to use this command:
`echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g`.
The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additional symbol `$` makes escaping.
[3] `traefik.backend.loadbalancer.swarm`:
If you enable this option, Traefik will use the virtual IP provided by docker swarm instead of the containers IPs.
Which means that Traefik will not perform any kind of load balancing and will delegate this task to swarm.
It also means that Traefik will manipulate only one backend, not one backend per container.
#### Custom Headers
| Label | Description |
|-------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container.<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.customRequestHeaders=EXPR` | Provides the container with custom request headers that will be appended to each request forwarded to the container.<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client.<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
#### Security Headers
@@ -314,7 +407,7 @@ The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additio
| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. |
| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. |
| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. |
| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored.<br>Format: `HEADER1,HEADER2` |
| `traefik.frontend.headers.hostsProxyHeaders=EXPR` | Provides a list of headers that the proxied hostname may be stored.<br>Format: `HEADER1,HEADER2` |
| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.<br>When deploying to production, be sure to set this to false. |
| `traefik.frontend.headers.publicKey=VALUE` | Adds HPKP header. |
| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. |
@@ -322,7 +415,7 @@ The result will be `user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/`, note additio
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
@@ -335,63 +428,71 @@ You can define as many segments as ports exposed in a container.
Segment labels override the default behavior.
| Label | Description |
|------------------------------------------------------------------------------------|------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`|
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`|
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
| Label | Description |
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
#### Custom Headers
| Label | Description |
|----------------------------------------------------------------------|----------------------------------------------------------|
| `traefik.<segment_name>.frontend.headers.customRequestHeaders=EXPR ` | Same as `traefik.frontend.headers.customRequestHeaders` |
| `traefik.<segment_name>.frontend.headers.customRequestHeaders=EXPR` | Same as `traefik.frontend.headers.customRequestHeaders` |
| `traefik.<segment_name>.frontend.headers.customResponseHeaders=EXPR` | Same as `traefik.frontend.headers.customResponseHeaders` |
#### Security Headers

View File

@@ -136,78 +136,89 @@ Traefik needs the following policy to read ECS information:
Labels can be used on task containers to override default behaviour:
| Label | Description |
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain for frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container |
| `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{instance_name}.{domain}`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
| Label | Description |
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain for frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Overrides the default `port` value. Overrides `NetworkBindings` from Docker Container |
| `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Overrides the service name by `foo` in the generated name of the backend. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{instance_name}.{domain}`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
### Custom Headers
@@ -249,58 +260,66 @@ You can define as many segments as ports exposed in an application.
Segment labels override the default behavior.
| Label | Description |
|-------------------------------------------------------------------------------------|-------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
| Label | Description |
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
#### Custom Headers

View File

@@ -31,6 +31,9 @@ Traefik can be configured with a file.
method = "drr"
[backends.backend1.loadBalancer.stickiness]
cookieName = "foobar"
secure = true
httpOnly = true
sameSite = "foobar"
[backends.backend1.maxConn]
amount = 10
@@ -64,16 +67,21 @@ Traefik can be configured with a file.
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
[frontends.frontend1.passTLSClientCert]
# Pass the escaped pem in a `X-Forwarded-Ssl-Client-Cert` header
pem = true
# Pass the escaped client cert infos selected below in a `X-Forwarded-Ssl-Client-Cert-Infos` header
# The unescaped header is like `Subject="C=%s,ST=%s,L=%s,O=%s,CN=%s",NB=%d,NA=%d,SAN=%s`
# It there is more than one certificates, their are separated by a `;`
[frontends.frontend-server.passTLSClientCert.infos]
[frontends.frontend1.passTLSClientCert.infos]
notBefore = true
notAfter = true
[frontends.frontend-server.passTLSClientCert.infos.subject]
[frontends.frontend1.passTLSClientCert.infos.subject]
country = true
domainComponent = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
[frontends.frontend1.passTLSClientCert.infos.issuer]
country = true
domainComponent = true
province = true
locality = true
organization = true

View File

@@ -73,6 +73,14 @@ See also [Kubernetes user guide](/user-guide/kubernetes).
#
# enablePassTLSCert = true
# Throttle how frequently we refresh our configuration from Ingresses when there
# are frequent changes.
#
# Optional
# Default: 0 (no throttling)
#
# throttleDuration = 10s
# Override default configuration template.
#
# Optional
@@ -128,10 +136,11 @@ This will give more flexibility in cloud/dynamic environments.
Traefik automatically requests endpoint information based on the service provided in the ingress spec.
Although traefik will connect directly to the endpoints (pods), it still checks the service port to see if TLS communication is required.
There are 2 ways to configure Traefik to use https to communicate with backend pods:
There are 3 ways to configure Traefik to use https to communicate with backend pods:
1. If the service port defined in the ingress spec is 443 (note that you can still use `targetPort` to use a different port on your pod).
2. If the service port defined in the ingress spec has a name that starts with `https` (such as `https-api`, `https-web` or just `https`).
3. If the ingress spec includes the annotation `ingress.kubernetes.io/protocol: https`.
If either of those configuration options exist, then the backend communication protocol is assumed to be TLS, and will connect via TLS automatically.
@@ -166,7 +175,7 @@ The following general annotations are applicable on the Ingress object:
| `traefik.ingress.kubernetes.io/service-weights: <YML>` | Set ingress backend weights specified as percentage or decimal numbers in YAML. (6) |
| `traefik.ingress.kubernetes.io/whitelist-source-range: "1.2.3.0/24, fe80::/16"` | A comma-separated list of IP ranges permitted for access (7). |
| `ingress.kubernetes.io/whitelist-x-forwarded-for: "true"` | Use `X-Forwarded-For` header as valid source of IP for the white list. |
| `ingress.kubernetes.io/protocol: <NAME>` | Set the protocol Traefik will use to communicate with pods. |
| `ingress.kubernetes.io/protocol:<NAME>` | Set the protocol Traefik will use to communicate with pods. Acceptable protocols: http,https,h2c |
<1> `traefik.ingress.kubernetes.io/app-root`:
Non-root paths will not be affected by this annotation and handled normally.
@@ -209,10 +218,14 @@ infos:
serialnumber: true
```
If `pem` is set, it will add a `X-Forwarded-Tls-Client-Cert` header that contains the escaped pem as value.
If `pem` is set, it will add a `X-Forwarded-Tls-Client-Cert` header that contains the escaped pem as value.
If at least one flag of the `infos` part is set, it will add a `X-Forwarded-Tls-Client-Cert-Infos` header that contains an escaped string composed of the client certificate data selected by the infos flags.
This infos part is composed like the following example (not escaped):
```Subject="C=FR,ST=SomeState,L=Lyon,O=Cheese,CN=*.cheese.org",NB=1531900816,NA=1563436816,SAN=*.cheese.org,*.cheese.net,cheese.in,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2```
```
Subject="C=FR,ST=SomeState,L=Lyon,O=Cheese,CN=*.cheese.org",NB=1531900816,NA=1563436816,SAN=*.cheese.org,*.cheese.net,cheese.in,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2
```
Note these options work only with certificates issued by CAs included in the applicable [EntryPoint ClientCA section](/configuration/entrypoints/#tls-mutual-authentication); certificates from other CAs are not parsed or passed through as-is.
<4> `traefik.ingress.kubernetes.io/rate-limit` example:
@@ -230,7 +243,7 @@ rateset:
```
<5> `traefik.ingress.kubernetes.io/rule-type`
Note: `ReplacePath` is deprecated in this annotation, use the `traefik.ingress.kubernetes.io/request-modifier` annotation instead. Default: `PathPrefix`.
Note: `ReplacePath` is deprecated in this annotation, use the `traefik.ingress.kubernetes.io/request-modifier` annotation instead. Default: `PathPrefix`.
<6> `traefik.ingress.kubernetes.io/service-weights`:
Service weights enable to split traffic across multiple backing services in a fine-grained manner.
@@ -316,7 +329,7 @@ The following security annotations are applicable on the Ingress object:
| `ingress.kubernetes.io/custom-browser-xss-value: VALUE` | Set custom value for X-XSS-Protection header. This overrides the BrowserXssFilter option. |
| `ingress.kubernetes.io/custom-frame-options-value: VALUE` | Overrides the `X-Frame-Options` header with the custom value. |
| `ingress.kubernetes.io/force-hsts: "false"` | Adds the STS header to non-SSL requests. |
| `ingress.kubernetes.io/frame-deny: "false"` | Adds the `X-Frame-Options` header with the value of `DENY`. |
| `ingress.kubernetes.io/frame-deny: "true"` | Adds the `X-Frame-Options` header with the value of `DENY`. |
| `ingress.kubernetes.io/hsts-max-age: "315360000"` | Sets the max-age of the HSTS header. |
| `ingress.kubernetes.io/hsts-include-subdomains: "true"` | Adds the IncludeSubdomains section of the STS header. |
| `ingress.kubernetes.io/hsts-preload: "true"` | Adds the preload flag to the HSTS header. |
@@ -328,7 +341,7 @@ The following security annotations are applicable on the Ingress object:
| `ingress.kubernetes.io/ssl-temporary-redirect: "true"` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `ingress.kubernetes.io/ssl-host: HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `ingress.kubernetes.io/ssl-force-host: "true"` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. |
| `ingress.kubernetes.io/ssl-proxy-headers: EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`). Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `ingress.kubernetes.io/ssl-proxy-headers: EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`). Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
### Authentication

View File

@@ -193,79 +193,90 @@ They may be specified on one of two levels: Application or service.
The following labels can be defined on Marathon applications. They adjust the behavior for the entire application.
| Label | Description |
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain used for the frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. |
| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. |
| `traefik.protocol=https` | Overrides the default `http` protocol. |
| `traefik.weight=10` | Assigns this weight to the container. |
| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{sub_domain}.{domain}`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
| Label | Description |
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain used for the frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the container exposes multiples ports. |
| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. |
| `traefik.protocol=https` | Overrides the default `http` protocol. |
| `traefik.weight=10` | Assigns this weight to the container. |
| `traefik.backend=foo` | Overrides the application name by `foo` in the generated name of the backend. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{sub_domain}.{domain}`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
#### Custom Headers
@@ -295,7 +306,7 @@ The following labels can be defined on Marathon applications. They adjust the be
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
@@ -308,59 +319,67 @@ You can define as many segments as ports exposed in an application.
Segment labels override the default behavior.
| Label | Description |
|------------------------------------------------------------------------------------|------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.portIndex=1` | Same as `traefik.portIndex` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`|
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`|
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
| Label | Description |
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.portIndex=1` | Same as `traefik.portIndex` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.auth.removeHeader=true` | Same as `traefik.frontend.auth.removeHeader` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
#### Custom Headers

View File

@@ -106,79 +106,90 @@ domain = "mesos.localhost"
The following labels can be defined on Mesos tasks. They adjust the behavior for the entire application.
| Label | Description |
|---------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain for the frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the application exposes multiple ports. |
| `traefik.portName=web` | Registers port by name in the application's ports array. Useful when the application exposes multiple ports. |
| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. |
| `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{discovery_name}.{domain}`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
| Label | Description |
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain for the frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the application exposes multiple ports. |
| `traefik.portName=web` | Registers port by name in the application's ports array. Useful when the application exposes multiple ports. |
| `traefik.portIndex=1` | Registers port by index in the application's ports array. Useful when the application exposes multiple ports. |
| `traefik.protocol=https` | Overrides the default `http` protocol |
| `traefik.weight=10` | Assigns this weight to the container |
| `traefik.backend=foo` | Overrides the task name by `foo` in the generated name of the backend. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. (Default: 30s) |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.users=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.auth.removeHeader=true` | If set to true, removes the Authorization header. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{discovery_name}.{domain}`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
### Custom Headers
@@ -207,7 +218,7 @@ The following labels can be defined on Mesos tasks. They adjust the behavior for
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |

View File

@@ -2,6 +2,11 @@
Traefik can be configured to use Rancher as a provider.
!!! important
This provider is specific to Rancher 1.x.
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 provider](./kubernetes.md) directly.
## Global Configuration
```toml
@@ -138,77 +143,88 @@ secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Labels can be used on task containers to override default behavior:
| Label | Description |
|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain for the frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the container exposes multiple ports. |
| `traefik.protocol=https` | Overrides the default `http` protocol. |
| `traefik.weight=10` | Assigns this weight to the container. |
| `traefik.backend=foo` | Gives the name `foo` to the generated backend for this container. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` . |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true`| Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
| Label | Description |
|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.domain` | Sets the default base domain for the frontend rules. |
| `traefik.enable=false` | Disables this container in Traefik. |
| `traefik.port=80` | Registers this port. Useful when the container exposes multiple ports. |
| `traefik.protocol=https` | Overrides the default `http` protocol. |
| `traefik.weight=10` | Assigns this weight to the container. |
| `traefik.backend=foo` | Overrides the service name by `foo` in the generated name of the backend. |
| `traefik.backend.buffering.maxRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.maxResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memRequestBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.memResponseBodyBytes=0` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.buffering.retryExpression=EXPR` | See [buffering](/configuration/commons/#buffering) section. |
| `traefik.backend.circuitbreaker.expression=EXPR` | Creates a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.responseForwarding.flushInterval=10ms` | Defines the interval between two flushes when forwarding response from backend to client. |
| `traefik.backend.healthcheck.path=/health` | Enables health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.interval=1s` | Defines the health check interval. |
| `traefik.backend.healthcheck.port=8080` | Sets a different port for the health check. |
| `traefik.backend.healthcheck.scheme=http` | Overrides the server URL scheme. |
| `traefik.backend.healthcheck.hostname=foobar.com` | Defines the health check hostname. |
| `traefik.backend.healthcheck.headers=EXPR` | Defines the health check request headers <br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
| `traefik.frontend.auth.basic.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.basic.users=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` . |
| `traefik.frontend.auth.basic.usersFile=/path/.htpasswd` | Sets the basic authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.digest.removeHeader=true` | If set to `true`, removes the `Authorization` header. |
| `traefik.frontend.auth.digest.users=EXPR` | Sets the digest authentication to this frontend in CSV format: `User:Realm:Hash,User:Realm:Hash`. |
| `traefik.frontend.auth.digest.usersFile=/path/.htdigest` | Sets the digest authentication with an external file; if users and usersFile are provided, both are merged, with external file contents having precedence. |
| `traefik.frontend.auth.forward.address=https://example.com` | Sets the URL of the authentication server. |
| `traefik.frontend.auth.forward.authResponseHeaders=EXPR` | Sets the forward authentication authResponseHeaders in CSV format: `X-Auth-User,X-Auth-Header` |
| `traefik.frontend.auth.forward.tls.ca=/path/ca.pem` | Sets the Certificate Authority (CA) for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.caOptional=true` | Checks the certificates if present but do not force to be signed by a specified Certificate Authority (CA). |
| `traefik.frontend.auth.forward.tls.cert=/path/server.pem` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.tls.insecureSkipVerify=true` | If set to true invalid SSL certificates are accepted. |
| `traefik.frontend.auth.forward.tls.key=/path/server.key` | Sets the Certificate for the TLS connection with the authentication server. |
| `traefik.frontend.auth.forward.trustForwardHeader=true` | Trusts X-Forwarded-* headers. |
| `traefik.frontend.auth.headerField=X-WebAuth-User` | Sets the header used to pass the authenticated user to the application. |
| `traefik.frontend.entryPoints=http,https` | Assigns this frontend to entry points `http` and `https`.<br>Overrides `defaultEntryPoints` |
| `traefik.frontend.errors.<name>.backend=NAME` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.query=PATH` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.errors.<name>.status=RANGE` | See [custom error pages](/configuration/commons/#custom-error-pages) section. |
| `traefik.frontend.passHostHeader=true` | Forwards client `Host` header to the backend. |
| `traefik.frontend.passTLSClientCert.infos.issuer.commonName=true` | Add the issuer.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.country=true` | Add the issuer.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Add the issuer.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.locality=true` | Add the issuer.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.organization=true` | Add the issuer.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.province=true` | Add the issuer.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Add the issuer.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notAfter=true` | Add the noAfter field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.notBefore=true` | Add the noBefore field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.sans=true` | Add the sans field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.commonName=true` | Add the subject.commonName field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.country=true` | Add the subject.country field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Add the subject.domainComponent field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.locality=true` | Add the subject.locality field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.organization=true` | Add the subject.organization field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.province=true` | Add the subject.province field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Add the subject.serialNumber field in a escaped client infos in the `X-Forwarded-Ssl-Client-Cert-Infos` header. |
| `traefik.frontend.passTLSClientCert.pem=true` | Pass the escaped pem in the `X-Forwarded-Ssl-Client-Cert` header. |
| `traefik.frontend.passTLSCert=true` | Forwards TLS Client certificates to the backend. |
| `traefik.frontend.priority=10` | Overrides default frontend priority |
| `traefik.frontend.rateLimit.extractorFunc=EXP` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.period=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.average=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.rateLimit.rateSet.<name>.burst=6` | See [rate limiting](/configuration/commons/#rate-limiting) section. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint to this frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirects to another URL to this frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.frontend.redirect.permanent=true` | Returns 301 instead of 302. |
| `traefik.frontend.rule=EXPR` | Overrides the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. |
| `traefik.frontend.whiteList.sourceRange=RANGE` | Sets a list of IP-Ranges which are allowed to access.<br>An unset or empty list allows all Source-IPs to access.<br>If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.frontend.whiteList.useXForwardedFor=true` | Uses `X-Forwarded-For` header as valid source of IP for the white list. |
#### Custom Headers
@@ -237,7 +253,7 @@ Labels can be used on task containers to override default behavior:
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLForceHost=true` | If `SSLForceHost` is `true` and `SSLHost` is set, requests will be forced to use `SSLHost` even the ones that are already using SSL. Default is false. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
@@ -250,57 +266,65 @@ You can define as many segments as ports exposed in a container.
Segment labels override the default behavior.
| Label | Description |
|------------------------------------------------------------------------------------|------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.organization`|
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true`| Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber`|
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
| Label | Description |
|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------|
| `traefik.<segment_name>.backend=BACKEND` | Same as `traefik.backend` |
| `traefik.<segment_name>.domain=DOMAIN` | Same as `traefik.domain` |
| `traefik.<segment_name>.port=PORT` | Same as `traefik.port` |
| `traefik.<segment_name>.protocol=http` | Same as `traefik.protocol` |
| `traefik.<segment_name>.weight=10` | Same as `traefik.weight` |
| `traefik.<segment_name>.frontend.auth.basic=EXPR` | Same as `traefik.frontend.auth.basic` |
| `traefik.<segment_name>.frontend.auth.basic.removeHeader=true` | Same as `traefik.frontend.auth.basic.removeHeader` |
| `traefik.<segment_name>.frontend.auth.basic.users=EXPR` | Same as `traefik.frontend.auth.basic.users` |
| `traefik.<segment_name>.frontend.auth.basic.usersFile=/path/.htpasswd` | Same as `traefik.frontend.auth.basic.usersFile` |
| `traefik.<segment_name>.frontend.auth.digest.removeHeader=true` | Same as `traefik.frontend.auth.digest.removeHeader` |
| `traefik.<segment_name>.frontend.auth.digest.users=EXPR` | Same as `traefik.frontend.auth.digest.users` |
| `traefik.<segment_name>.frontend.auth.digest.usersFile=/path/.htdigest` | Same as `traefik.frontend.auth.digest.usersFile` |
| `traefik.<segment_name>.frontend.auth.forward.address=https://example.com` | Same as `traefik.frontend.auth.forward.address` |
| `traefik.<segment_name>.frontend.auth.forward.authResponseHeaders=EXPR` | Same as `traefik.frontend.auth.forward.authResponseHeaders` |
| `traefik.<segment_name>.frontend.auth.forward.tls.ca=/path/ca.pem` | Same as `traefik.frontend.auth.forward.tls.ca` |
| `traefik.<segment_name>.frontend.auth.forward.tls.caOptional=true` | Same as `traefik.frontend.auth.forward.tls.caOptional` |
| `traefik.<segment_name>.frontend.auth.forward.tls.cert=/path/server.pem` | Same as `traefik.frontend.auth.forward.tls.cert` |
| `traefik.<segment_name>.frontend.auth.forward.tls.insecureSkipVerify=true` | Same as `traefik.frontend.auth.forward.tls.insecureSkipVerify` |
| `traefik.<segment_name>.frontend.auth.forward.tls.key=/path/server.key` | Same as `traefik.frontend.auth.forward.tls.key` |
| `traefik.<segment_name>.frontend.auth.forward.trustForwardHeader=true` | Same as `traefik.frontend.auth.forward.trustForwardHeader` |
| `traefik.<segment_name>.frontend.auth.headerField=X-WebAuth-User` | Same as `traefik.frontend.auth.headerField` |
| `traefik.<segment_name>.frontend.entryPoints=https` | Same as `traefik.frontend.entryPoints` |
| `traefik.<segment_name>.frontend.errors.<name>.backend=NAME` | Same as `traefik.frontend.errors.<name>.backend` |
| `traefik.<segment_name>.frontend.errors.<name>.query=PATH` | Same as `traefik.frontend.errors.<name>.query` |
| `traefik.<segment_name>.frontend.errors.<name>.status=RANGE` | Same as `traefik.frontend.errors.<name>.status` |
| `traefik.<segment_name>.frontend.passHostHeader=true` | Same as `traefik.frontend.passHostHeader` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.issuer.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.issuer.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notAfter=true` | Same as `traefik.frontend.passTLSClientCert.infos.notAfter` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.notBefore=true` | Same as `traefik.frontend.passTLSClientCert.infos.notBefore` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.sans=true` | Same as `traefik.frontend.passTLSClientCert.infos.sans` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.commonName=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.commonName` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.country=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.country` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.domainComponent=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.domainComponent` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.locality=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.locality` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.organization=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.organization` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.province=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.province` |
| `traefik.<segment_name>.frontend.passTLSClientCert.infos.subject.serialNumber=true` | Same as `traefik.frontend.passTLSClientCert.infos.subject.serialNumber` |
| `traefik.<segment_name>.frontend.passTLSClientCert.pem=true` | Same as `traefik.frontend.passTLSClientCert.infos.pem` |
| `traefik.<segment_name>.frontend.passTLSCert=true` | Same as `traefik.frontend.passTLSCert` |
| `traefik.<segment_name>.frontend.priority=10` | Same as `traefik.frontend.priority` |
| `traefik.<segment_name>.frontend.rateLimit.extractorFunc=EXP` | Same as `traefik.frontend.rateLimit.extractorFunc` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.period=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.period` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.average=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.average` |
| `traefik.<segment_name>.frontend.rateLimit.rateSet.<name>.burst=6` | Same as `traefik.frontend.rateLimit.rateSet.<name>.burst` |
| `traefik.<segment_name>.frontend.redirect.entryPoint=https` | Same as `traefik.frontend.redirect.entryPoint` |
| `traefik.<segment_name>.frontend.redirect.regex=^http://localhost/(.*)` | Same as `traefik.frontend.redirect.regex` |
| `traefik.<segment_name>.frontend.redirect.replacement=http://mydomain/$1` | Same as `traefik.frontend.redirect.replacement` |
| `traefik.<segment_name>.frontend.redirect.permanent=true` | Same as `traefik.frontend.redirect.permanent` |
| `traefik.<segment_name>.frontend.rule=EXP` | Same as `traefik.frontend.rule` |
| `traefik.<segment_name>.frontend.whiteList.sourceRange=RANGE` | Same as `traefik.frontend.whiteList.sourceRange` |
| `traefik.<segment_name>.frontend.whiteList.useXForwardedFor=true` | Same as `traefik.frontend.whiteList.useXForwardedFor` |
#### Custom Headers

View File

@@ -29,7 +29,7 @@ Traefik can be configured:
```shell
curl -XPUT @file "http://localhost:8080/api/providers/rest"
curl -XPUT -d @file "http://localhost:8080/api/providers/rest"
```
with `@file`:

View File

@@ -69,6 +69,8 @@ Here is an example of an extension setting Traefik labels:
</StatelessServiceType>
```
> **Note**: The `Label` tag and its `Key` attribute are case sensitive. That is, if you use `label` instead of `Label` or `key` instead of `Key`, they will be silently ignored.
#### Property Manager
Set Labels with the property manager API to overwrite and add labels, while your service is running.
@@ -96,11 +98,12 @@ Labels, set through extensions or the property manager, can be used on services
| Label | Description |
|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.enable=false` | Disable this container in Traefik |
| `traefik.enable=false` | Disable this container in Traefik |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.servicefabric.groupname` | Group all services with the same name into a single backend in Traefik |
| `traefik.servicefabric.groupweight` | Set the weighting of the current services nodes in the backend group |
| `traefik.servicefabric.enablelabeloverrides` | Toggle whether labels can be overridden using the Service Fabric Property Manager API |
| `traefik.servicefabric.groupname` | Group all services with the same name into a single backend in Traefik |
| `traefik.servicefabric.groupweight` | Set the weighting of the current services nodes in the backend group |
| `traefik.servicefabric.enablelabeloverrides` | Toggle whether labels can be overridden using the Service Fabric Property Manager API |
| `traefik.servicefabric.endpointname` | Specify the name of the endpoint |
| `traefik.backend.healthcheck.path=/health` | Enable health check for the backend, hitting the container at `path`. |
| `traefik.backend.healthcheck.port=8080` | Allow to use a different port for the health check. |
| `traefik.backend.healthcheck.interval=1s` | Define the health check interval. |
@@ -109,6 +112,9 @@ Labels, set through extensions or the property manager, can be used on services
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.secure=true` | Sets secure cookie option for sticky sessions. |
| `traefik.backend.loadbalancer.stickiness.httpOnly=true` | Sets http only cookie option for sticky sessions |
| `traefik.backend.loadbalancer.stickiness.sameSite=none` | Sets same site cookie option for sticky sessions. (`none`, `lax`, `strict`) |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
@@ -142,7 +148,7 @@ Labels, set through extensions or the property manager, can be used on services
| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. |
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-Proto:https`).<br>Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |

View File

@@ -249,8 +249,19 @@ Multiple sets of rates can be added to each frontend, but the time periods must
```
In the above example, frontend1 is configured to limit requests by the client's ip address.
An average of 5 requests every 3 seconds is allowed and an average of 100 requests every 10 seconds.
These can "burst" up to 10 and 200 in each period respectively.
A sustained rate of 100 requests every 10 seconds (10 req/s) is allowed for rateset1, and 5 requests every 3 seconds (~1.67 req/s) for rateset2.
In addition, these can "burst" up to 200 and 10 in each period respectively.
Another way to describe the above parameters, is to use the [leaky bucket](https://en.wikipedia.org/wiki/Leaky_bucket) analogy:
for rateset1, the size of the bucket is 200 drops, and it is leaking at a rate of 10 drop/s.
If the incoming rate of drops falling into the bucket gets high enough that the bucket gets filled,
any subsequent drop overflows out of the bucket (i.e. the request is discarded).
This situation holds until the incoming rate gets low enough again, and remains that way, for the water level in the bucket to go down.
Valid values for `extractorfunc` are:
* `client.ip`
* `request.host`
* `request.header.<header name>`
## Buffering
@@ -528,3 +539,40 @@ Example:
backend = "{{$backend}}"
{{end}}
```
## Pass TLS Client Cert
```toml
# Pass the escaped client cert infos selected below in a `X-Forwarded-Ssl-Client-Cert-Infos` header.
[frontends.frontend1.passTLSClientCert]
pem = true
[frontends.frontend1.passTLSClientCert.infos]
notBefore = true
notAfter = true
[frontends.frontend1.passTLSClientCert.infos.subject]
country = true
domainComponent = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
[frontends.frontend1.passTLSClientCert.infos.issuer]
country = true
domainComponent = true
province = true
locality = true
organization = true
commonName = true
serialNumber = true
```
Pass TLS Client Cert `pem` defines if the escaped pem is added to a `X-Forwarded-Ssl-Client-Cert` header.
Pass TLS Client Cert `infos` defines how the certificate data are added to a `X-Forwarded-Ssl-Client-Cert-Infos` header.
The following example shows an unescaped result that uses all the available fields:
If there are more than one certificate, they are separated by a `;`
```
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=*.cheese.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=*.cheese.org,*.cheese.net,*.cheese.com,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2
```

View File

@@ -93,11 +93,11 @@ For more information about the CLI, see the documentation about [Traefik command
Whitespace is used as option separator and `,` is used as value separator for the list.
The names of the options are case-insensitive.
In compose file the entrypoint syntax is different:
In compose file the entrypoint syntax is different. Notice how quotes are used:
```yaml
traefik:
image: traefik
image: traefik:v1.7
command:
- --defaultentrypoints=powpow
- "--entryPoints=Name:powpow Address::42 Compress:true"
@@ -105,7 +105,7 @@ traefik:
or
```yaml
traefik:
image: traefik
image: traefik:v1.7
command: --defaultentrypoints=powpow --entryPoints='Name:powpow Address::42 Compress:true'
```
@@ -235,13 +235,18 @@ If you need to add or remove TLS certificates while Traefik is started, Dynamic
## TLS Mutual Authentication
TLS Mutual Authentication can be `optional` or not.
If it's `optional`, Traefik will authorize connection with certificates not signed by a specified Certificate Authority (CA).
Otherwise, Traefik will only accept clients that present a certificate signed by a specified Certificate Authority (CA).
* If `optional = true`, if a certificate is provided, verifies if it is signed by a specified Certificate Authority (CA). Otherwise proceeds without any certificate.
* If `optional = false`, Traefik will only accept clients that present a certificate signed by a specified Certificate Authority (CA).
!!! warning
While the TLS [1.1](https://tools.ietf.org/html/rfc4346#section-7.4.6) and [1.2](https://tools.ietf.org/html/rfc5246#section-7.4.6) RFCs specify that clients should proceed with handshaking by sending an empty list should they have no certs for the CAs specified by the server, not all do so in practice.
Use this feature with caution should you require maximum compatibility with a wide variety of client user agents which may not strictly implement these specs.
`ClientCAFiles` can be configured with multiple `CA:s` in the same file or use multiple files containing one or several `CA:s`.
The `CA:s` has to be in PEM format.
By default, `ClientCAFiles` is not optional, all clients will be required to present a valid cert.
The requirement will apply to all server certs in the entrypoint.
By default, `ClientCAFiles` is not optional, all clients will be required to present a valid cert. The requirement will apply to all server certs in the entrypoint.
In the example below both `snitest.com` and `snitest.org` will require client certs
@@ -480,6 +485,13 @@ To enable IP white listing at the entry point level.
# useXForwardedFor = true
```
By setting the `useXForwardedFor` option, the `sourceRange` addresses will be matched against the request header `X-Forwarded-For` address list, from left to right.
!!! danger
When using Traefik behind another load-balancer, its own internal address will be appended in the `X-Forwarded-For` header.
Be sure to carefully configure the `sourceRange` as adding the internal network CIDR,
or the load-balancer address directly, will cause all requests coming from it to pass through.
## ProxyProtocol
To enable [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) support.

View File

@@ -39,7 +39,7 @@ logLevel = "INFO"
For more information about the CLI, see the documentation about [Traefik command](/basics/#traefik).
```shell
```bash
--logLevel="DEBUG"
--traefikLog.filePath="/path/to/traefik.log"
--traefikLog.format="json"
@@ -54,7 +54,6 @@ For more information about the CLI, see the documentation about [Traefik command
--accessLog.fields.headers.names="User-Agent=redact Authorization=drop Content-Type=keep"
```
## Traefik Logs
By default the Traefik log is written to stdout in text format.
@@ -66,7 +65,7 @@ To write the logs into a log file specify the `filePath`:
filePath = "/path/to/traefik.log"
```
To write JSON format logs, specify `json` as the format:
To switch to JSON format instead of standard format (`common`), specify `json` as the format:
```toml
[traefikLog]
@@ -74,7 +73,6 @@ To write JSON format logs, specify `json` as the format:
format = "json"
```
Deprecated way (before 1.4):
!!! danger "DEPRECATED"
@@ -105,13 +103,12 @@ To customize the log level:
logLevel = "ERROR"
```
## Access Logs
Access logs are written when `[accessLog]` is defined.
By default it will write to stdout and produce logs in the textual Common Log Format (CLF), extended with additional fields.
Access logs are written when the entry `[accessLog]` is defined (or the command line flag `--accesslog`).
By default it writes to stdout and produces logs in the textual [Common Log Format (CLF)](#clf-common-log-format), extended with additional fields.
To enable access logs using the default settings just add the `[accessLog]` entry:
To enable access logs using the default settings, add the `[accessLog]` entry in your `traefik.toml` configuration file:
```toml
[accessLog]
@@ -124,12 +121,12 @@ To write the logs into a log file specify the `filePath`:
filePath = "/path/to/access.log"
```
To write JSON format logs, specify `json` as the format:
To switch to JSON format instead of [Common Log Format (CLF)](#clf-common-log-format), specify `json` as the format:
```toml
[accessLog]
filePath = "/path/to/access.log"
format = "json"
format = "json" # Default: "common"
```
To write the logs in async, specify `bufferingSize` as the format (must be >0):
@@ -152,7 +149,7 @@ To filter logs you can specify a set of filters which are logically "OR-connecte
```toml
[accessLog]
filePath = "/path/to/access.log"
format = "json"
format = "json" # Default: "common"
[accessLog.filters]
@@ -178,22 +175,42 @@ format = "json"
minDuration = "10ms"
```
To customize logs format:
### CLF - Common Log Format
By default, Traefik use the CLF (`common`) as access log format.
```html
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <origin_server_HTTP_status> <origin_server_content_size> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_frontend_name>" "<Traefik_backend_URL>" <request_duration_in_ms>ms
```
### Customize Fields
You can customize the fields written in the access logs.
The list of available fields is found below: [List of All Available Fields](#list-of-all-available-fields).
Each field has a "mode" which defines if it is written or not in the access log lines.
The possible values for the mode are:
* `keep`: the field and its value are written on the access log line. This is the default behavior.
* `drop`: the field is not written at all on the access log.
To customize the fields, you must:
* Switch to the JSON format (mandatory)
* Define the "default mode" for all fields (default is `keep`)
* OR Define the fields which does not follow the default mode
```toml
[accessLog]
filePath = "/path/to/access.log"
# Access Log Format
#
# Optional
# Default: "common"
#
# Accepted values "common", "json"
#
format = "json"
[accessLog.filters]
# statusCodes keep only access logs with status codes in the specified range
#
# Optional
# Default: []
#
statusCodes = ["200", "300-302"]
[accessLog.fields]
# defaultMode
@@ -209,6 +226,43 @@ format = "json"
[accessLog.fields.names]
"ClientUsername" = "drop"
# ...
```
### Customize Headers
Access logs prints the headers of each request, as fields of the access log line.
You can customize which and how the headers are printed, likewise the other fields (see ["Customize Fields" section](#customize-fields)).
Each header has a "mode" which defines how it is written in the access log lines.
The possible values for the mode are:
* `keep`: the header and its value are written on the access log line. This is the default behavior.
* `drop`: the header is not written at all on the access log.
* `redacted`: the header is written, but its value is redacted to avoid leaking sensitive information.
To customize the headers, you must:
* Switch to the JSON format (mandatory)
* Define the "default mode" for all headers (default is `keep`)
* OR Define the headers which does not follow the default mode
!!! important
The headers are written with the prefix `request_` in the access log.
This prefix must not be included when specifying a header in the TOML configuration.
* Do: `"User-Agent" = "drop"`
* Don't: `"redacted_User-Agent" = "drop"`
```toml
[accessLog]
# Access Log Format
#
# Optional
# Default: "common"
#
# Accepted values "common", "json"
#
format = "json"
[accessLog.fields.headers]
# defaultMode
@@ -227,41 +281,42 @@ format = "json"
# ...
```
### List of All Available Fields
### List of all 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 by processing the response, including the origin server's time but not the log writing time. |
| `FrontendName` | The name of the Traefik frontend. |
| `BackendName` | The name of the Traefik backend. |
| `BackendURL` | The URL of the Traefik backend. |
| `BackendAddr` | The IP:port of the Traefik backend (extracted from `BackendURL`) |
| `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. |
| `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 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. |
| `OriginStatusLine` | `OriginStatus` + Status code explanation |
| `DownstreamStatus` | The HTTP status code returned to the client. |
| `DownstreamStatusLine` | `DownstreamStatus` + Status code explanation |
| `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 caused by Traefik. |
| `RetryAttempts` | The amount of attempts the request was retried. |
```ini
StartUTC
StartLocal
Duration
FrontendName
BackendName
BackendURL
BackendAddr
ClientAddr
ClientHost
ClientPort
ClientUsername
RequestAddr
RequestHost
RequestPort
RequestMethod
RequestPath
RequestProtocol
RequestLine
RequestContentSize
OriginDuration
OriginContentSize
OriginStatus
OriginStatusLine
DownstreamStatus
DownstreamStatusLine
DownstreamContentSize
RequestCount
GzipRatio
Overhead
RetryAttempts
```
### Depreciation Notice
Deprecated way (before 1.4):
@@ -276,15 +331,6 @@ Deprecated way (before 1.4):
accessLogsFile = "log/access.log"
```
### CLF - Common Log Format
By default, Traefik use the CLF (`common`) as access log format.
```html
<remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <origin_server_HTTP_status> <origin_server_content_size> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_frontend_name>" "<Traefik_backend_URL>" <request_duration_in_ms>ms
```
## Log Rotation
Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal.
@@ -292,3 +338,34 @@ This allows the logs to be rotated and processed by an external program, such as
!!! note
This does not work on Windows due to the lack of USR signals.
## Time Zones
The timestamp of each log line is in UTC time by default.
If you want to use local timezone, you need to ensure the 3 following elements:
1. Provide the timezone data into /usr/share/zoneinfo
2. Set the environement variable TZ to the timezone to be used
3. Specify the field StartLocal instead of StartUTC (works on default Common Log Format (CLF) as well as JSON)
Example using docker-compose:
```yml
version: '3'
services:
traefik:
image: traefik/traefik:[latest stable version]
ports:
- "80:80"
environment:
- "TZ=US/Alaska"
command:
- --docker
- --accesslog
- --accesslog.fields.names="StartUTC=drop"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "/usr/share/zoneinfo:/usr/share/zoneinfo:ro"
```

View File

@@ -20,7 +20,7 @@
# Buckets for latency metrics
#
# Optional
# Default: [0.1, 0.3, 1.2, 5]
# Default: [0.1, 0.3, 1.2, 5.0]
#
buckets = [0.1,0.3,1.2,5.0]

View File

@@ -30,7 +30,7 @@ Thus, if you have a regular path for `/foo` and an entrypoint on `:80`, you woul
* Admin panel: `http://hostname:8080/`
* Ping URL: `http://hostname:8080/ping`
However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your administration panel's port.
However, for security reasons, you may want to be able to expose the `/ping` health-check URL to outside health-checkers, e.g. an Internet service or cloud load-balancer, _without_ exposing your dashboard's port.
In many environments, the security staff may not _allow_ you to expose it.
You have two options:
@@ -40,7 +40,7 @@ You have two options:
### Ping health check on a regular entry point
To proxy `/ping` from a regular entry point to the administration one without exposing the panel, do the following:
To proxy `/ping` from a regular entry point to the administration one without exposing the dashboard, do the following:
```toml
defaultEntryPoints = ["http"]

View File

@@ -58,6 +58,13 @@ Traefik supports three tracing backends: Jaeger, Zipkin and DataDog.
# Default: "127.0.0.1:6831"
#
localAgentHostPort = "127.0.0.1:6831"
# Trace Context Header Name is the http header name used to propagate tracing context.
# This must be in lower-case to avoid mismatches when decoding incoming headers.
#
# Default: "uber-trace-id"
#
traceContextHeaderName = "uber-trace-id"
```
!!! warning
@@ -156,4 +163,10 @@ Traefik supports three tracing backends: Jaeger, Zipkin and DataDog.
#
globalTag = ""
# Enable priority sampling. When using distributed tracing, this option must be enabled in order
# to get all the parts of a distributed trace sampled.
#
# Default: false
#
prioritySampling = false
```

View File

@@ -4,9 +4,9 @@
[![Build Status SemaphoreCI](https://semaphoreci.com/api/v1/containous/traefik/branches/master/shields_badge.svg)](https://semaphoreci.com/containous/traefik)
[![Docs](https://img.shields.io/badge/docs-current-brightgreen.svg)](/)
[![Go Report Card](https://goreportcard.com/badge/github.com/containous/traefik)](https://goreportcard.com/report/github.com/containous/traefik)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/containous/traefik/blob/master/LICENSE.md)
[![Join the chat at https://slack.traefik.io](https://img.shields.io/badge/style-register-green.svg?style=social&label=Slack)](https://slack.traefik.io)
[![Go Report Card](https://goreportcard.com/badge/github.com/traefik/traefik)](https://goreportcard.com/report/github.com/traefik/traefik)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/traefik/traefik/blob/master/LICENSE.md)
[![Join the community support forum at https://community.traefik.io/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.traefik.io/)
[![Twitter](https://img.shields.io/twitter/follow/traefik.svg?style=social)](https://twitter.com/intent/follow?screen_name=traefik)
@@ -66,7 +66,7 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t
In this quickstart, we'll use [Docker compose](https://docs.docker.com/compose) to create our demo infrastructure.
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/master/examples/quickstart/) directory.
To save some time, you can clone [Traefik's repository](https://github.com/traefik/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/traefik/traefik/tree/v1.7/examples/quickstart/) directory.
### 1 — Launch Traefik — Tell It to Listen to Docker
@@ -77,7 +77,7 @@ version: '3'
services:
reverse-proxy:
image: traefik # The official Traefik docker image
image: traefik:v1.7 # The official Traefik docker image
command: --api --docker # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
@@ -109,7 +109,7 @@ Edit your `docker-compose.yml` file and add the following at the end of your fil
```yaml
# ...
whoami:
image: containous/whoami # A container that exposes an API to show its IP address
image: traefik/whoami # A container that exposes an API to show its IP address
labels:
- "traefik.frontend.rule=Host:whoami.docker.localhost"
```
@@ -176,7 +176,7 @@ Our recommendation would be to see for yourself how simple it is to enable HTTPS
## Resources
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at [GopherCon 2017](https://gophercon.com).
Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at GopherCon 2017.
You will learn Traefik basics in less than 10 minutes.
[![Traefik GopherCon 2017](https://img.youtube.com/vi/RgudiksfL-k/0.jpg)](https://www.youtube.com/watch?v=RgudiksfL-k)
@@ -190,7 +190,7 @@ You will learn fundamental Traefik features and see some demos with Kubernetes.
### The Official Binary File
You can grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page and just run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml):
You can grab the latest binary from the [releases](https://github.com/traefik/traefik/releases) page and just run it with the [sample configuration file](https://raw.githubusercontent.com/traefik/traefik/v1.7/traefik.sample.toml):
```shell
./traefik -c traefik.toml

View File

@@ -88,9 +88,9 @@
</div>
{% endif %}
powered by
<a href="http://www.mkdocs.org" title="MkDocs">MkDocs</a>
<a href="https://www.mkdocs.org" title="MkDocs">MkDocs</a>
and
<a href="http://squidfunk.github.io/mkdocs-material/"
<a href="https://squidfunk.github.io/mkdocs-material/"
title="Material for MkDocs">
Material for MkDocs</a>
</div>

View File

@@ -0,0 +1,7 @@
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-NMWC63S');</script>
<!-- End Google Tag Manager -->

View File

@@ -9,7 +9,7 @@ If you want to use Let's Encrypt with Traefik, sharing configuration or TLS cert
Ok, could we mount a shared volume used by all my instances? Yes, you can, but it will not work.
When you use Let's Encrypt, you need to store certificates, but not only.
When Traefik generates a new certificate, it configures a challenge and once Let's Encrypt will verify the ownership of the domain, it will ping back the challenge.
If the challenge is not known by other Traefik instances, the validation will fail.
If the challenge is not recognized by other Traefik instances, the validation will fail.
For more information about the challenge: [Automatic Certificate Management Environment (ACME)](https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http-challenge)
@@ -91,7 +91,7 @@ To watch docker events, add `--docker.watch`.
version: "3"
services:
traefik:
image: traefik:1.5
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
command:
- "--api"
- "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
@@ -156,7 +156,7 @@ The initializer in a docker-compose file will be:
```yaml
traefik_init:
image: traefik:1.5
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
command:
- "storeconfig"
- "--api"
@@ -177,7 +177,7 @@ And now, the Traefik part will only have the Consul configuration.
```yaml
traefik:
image: traefik:1.5
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
depends_on:
- traefik_init
- consul
@@ -200,7 +200,7 @@ The new configuration will be stored in Consul, and you need to restart the Trae
version: "3.4"
services:
traefik_init:
image: traefik:1.5
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
command:
- "storeconfig"
- "--api"
@@ -229,7 +229,7 @@ services:
depends_on:
- consul
traefik:
image: traefik:1.5
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
depends_on:
- traefik_init
- consul

View File

@@ -50,7 +50,7 @@ version: '2'
services:
traefik:
image: traefik:1.5.4
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
restart: always
ports:
- 80:80
@@ -108,6 +108,28 @@ onHostRule = true
entryPoint = "http"
```
Alternatively, the `TOML` file above can also be translated into command line switches.
This is the `command` value of the `traefik` service in the `docker-compose.yml` manifest:
```yaml
command:
- --debug=false
- --logLevel=ERROR
- --defaultentrypoints=https,http
- --entryPoints=Name:http Address::80 Redirect.EntryPoint:https
- --entryPoints=Name:https Address::443 TLS
- --retry
- --docker.endpoint=unix:///var/run/docker.sock
- --docker.domain=my-awesome-app.org
- --docker.watch=true
- --docker.exposedbydefault=false
- --acme.email=your-email-here@my-awesome-app.org
- --acme.storage=acme.json
- --acme.entryPoint=https
- --acme.onHostRule=true
- --acme.httpchallenge.entrypoint=http
```
This is the minimum configuration required to do the following:
- Log `ERROR`-level messages (or more severe) to the console, but silence `DEBUG`-level messages
@@ -213,13 +235,11 @@ Let's take a look at the labels themselves for the `app` service, which is a HTT
- "traefik.admin.port=9443"
```
We use both `container labels` and `service labels`.
We use both `container labels` and `segment labels`.
#### Container labels
First, we specify the `backend` name which corresponds to the actual service we're routing **to**.
We also tell Traefik to use the `web` network to route HTTP traffic to this container.
We tell Traefik to use the `web` network to route HTTP traffic to this container.
With the `traefik.enable` label, we tell Traefik to include this container in its internal configuration.
With the `frontend.rule` label, we tell Traefik that we want to route to this container if the incoming HTTP request contains the `Host` `app.my-awesome-app.org`.
@@ -227,20 +247,20 @@ Essentially, this is the actual rule used for Layer-7 load balancing.
Finally but not unimportantly, we tell Traefik to route **to** port `9000`, since that is the actual TCP/IP port the container actually listens on.
### Service labels
#### Segment labels
`Service labels` allow managing many routes for the same container.
`Segment labels` allow managing many routes for the same container.
When both `container labels` and `service labels` are defined, `container labels` are just used as default values for missing `service labels` but no frontend/backend are going to be defined only with these labels.
Obviously, labels `traefik.frontend.rule` and `traefik.port` described above, will only be used to complete information set in `service labels` during the container frontends/backends creation.
When both `container labels` and `segment labels` are defined, `container labels` are just used as default values for missing `segment labels` but no frontend/backend are going to be defined only with these labels.
Obviously, labels `traefik.frontend.rule` and `traefik.port` described above, will only be used to complete information set in `segment labels` during the container frontends/backends creation.
In the example, two service names are defined : `basic` and `admin`.
In the example, two segment names are defined : `basic` and `admin`.
They allow creating two frontends and two backends.
- `basic` has only one `service label` : `traefik.basic.protocol`.
- `basic` has only one `segment label` : `traefik.basic.protocol`.
Traefik will use values set in `traefik.frontend.rule` and `traefik.port` to create the `basic` frontend and backend.
The frontend listens to incoming HTTP requests which contain the `Host` `app.my-awesome-app.org` and redirect them in `HTTP` to the port `9000` of the backend.
- `admin` has all the `services labels` needed to create the `admin` frontend and backend (`traefik.admin.frontend.rule`, `traefik.admin.protocol`, `traefik.admin.port`).
- `admin` has all the `segment labels` needed to create the `admin` frontend and backend (`traefik.admin.frontend.rule`, `traefik.admin.protocol`, `traefik.admin.port`).
Traefik will create a frontend to listen to incoming HTTP requests which contain the `Host` `admin-app.my-awesome-app.org` and redirect them in `HTTPS` to the port `9443` of the backend.
#### Gotchas and tips

View File

@@ -336,80 +336,80 @@ Pay attention to the **labels** section:
```
home:
image: abiosoft/caddy:0.10.14
networks:
- ntw_front
volumes:
- ./www/home/srv/:/srv/
deploy:
mode: replicated
replicas: 2
#placement:
# constraints: [node.role==manager]
restart_policy:
condition: on-failure
max_attempts: 5
resources:
limits:
cpus: '0.20'
memory: 9M
reservations:
cpus: '0.05'
memory: 9M
labels:
- "traefik.frontend.rule=PathPrefixStrip:/"
- "traefik.backend=home"
- "traefik.port=2015"
- "traefik.weight=10"
- "traefik.enable=true"
- "traefik.passHostHeader=true"
- "traefik.docker.network=ntw_front"
- "traefik.frontend.entryPoints=http"
- "traefik.backend.loadbalancer.swarm=true"
- "traefik.backend.loadbalancer.method=drr"
image: abiosoft/caddy:0.10.14
networks:
- ntw_front
volumes:
- ./www/home/srv/:/srv/
deploy:
mode: replicated
replicas: 2
#placement:
# constraints: [node.role==manager]
restart_policy:
condition: on-failure
max_attempts: 5
resources:
limits:
cpus: '0.20'
memory: 9M
reservations:
cpus: '0.05'
memory: 9M
labels:
- "traefik.frontend.rule=PathPrefixStrip:/"
- "traefik.backend=home"
- "traefik.port=2015"
- "traefik.weight=10"
- "traefik.enable=true"
- "traefik.passHostHeader=true"
- "traefik.docker.network=ntw_front"
- "traefik.frontend.entryPoints=http"
- "traefik.backend.loadbalancer.swarm=true"
- "traefik.backend.loadbalancer.method=drr"
```
Something more tricky using `regex`.
In this case a slash is added to `siteexample.io/portainer` and redirect to `siteexample.io/portainer/`. For more details: https://github.com/containous/traefik/issues/563
In this case a slash is added to `siteexample.io/portainer` and redirect to `siteexample.io/portainer/`. For more details: https://github.com/traefik/traefik/issues/563
The double sign `$$` are variables managed by the docker compose file ([documentation](https://docs.docker.com/compose/compose-file/#variable-substitution)).
```
portainer:
image: portainer/portainer:1.16.5
networks:
- ntw_front
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role==manager]
restart_policy:
condition: on-failure
max_attempts: 5
resources:
limits:
cpus: '0.33'
memory: 20M
reservations:
cpus: '0.05'
memory: 10M
labels:
- "traefik.frontend.rule=PathPrefixStrip:/portainer"
- "traefik.backend=portainer"
- "traefik.port=9000"
- "traefik.weight=10"
- "traefik.enable=true"
- "traefik.passHostHeader=true"
- "traefik.docker.network=ntw_front"
- "traefik.frontend.entryPoints=http"
- "traefik.backend.loadbalancer.swarm=true"
- "traefik.backend.loadbalancer.method=drr"
# https://github.com/containous/traefik/issues/563#issuecomment-421360934
- "traefik.frontend.redirect.regex=^(.*)/portainer$$"
- "traefik.frontend.redirect.replacement=$$1/portainer/"
- "traefik.frontend.rule=PathPrefix:/portainer;ReplacePathRegex: ^/portainer/(.*) /$$1"
image: portainer/portainer:1.16.5
networks:
- ntw_front
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: replicated
replicas: 1
placement:
constraints: [node.role==manager]
restart_policy:
condition: on-failure
max_attempts: 5
resources:
limits:
cpus: '0.33'
memory: 20M
reservations:
cpus: '0.05'
memory: 10M
labels:
- "traefik.frontend.rule=PathPrefixStrip:/portainer"
- "traefik.backend=portainer"
- "traefik.port=9000"
- "traefik.weight=10"
- "traefik.enable=true"
- "traefik.passHostHeader=true"
- "traefik.docker.network=ntw_front"
- "traefik.frontend.entryPoints=http"
- "traefik.backend.loadbalancer.swarm=true"
- "traefik.backend.loadbalancer.method=drr"
# https://github.com/traefik/traefik/issues/563#issuecomment-421360934
- "traefik.frontend.redirect.regex=^(.*)/portainer$$"
- "traefik.frontend.redirect.replacement=$$1/portainer/"
- "traefik.frontend.rule=PathPrefix:/portainer;ReplacePathRegex: ^/portainer/(.*) /$$1"
```

View File

@@ -14,7 +14,6 @@ defaultEntryPoints = ["https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http]
[api]

View File

@@ -4,16 +4,20 @@ This guide explains how to use Traefik as an Ingress controller for a Kubernetes
If you are not familiar with Ingresses in Kubernetes you might want to read the [Kubernetes user guide](https://kubernetes.io/docs/concepts/services-networking/ingress/)
The config files used in this guide can be found in the [examples directory](https://github.com/containous/traefik/tree/master/examples/k8s)
The config files used in this guide can be found in the [examples directory](https://github.com/traefik/traefik/tree/v1.7/examples/k8s)
## Prerequisites
1. A working Kubernetes cluster. If you want to follow along with this guide, you should setup [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/) on your machine, as it is the quickest way to get a local Kubernetes cluster setup for experimentation and development.
2. Setup ingress as an add-on. It can be enabled by the following command:
`minikube addons enable ingress`
!!! note
The guide is likely not fully adequate for a production-ready setup.
2. The `kubectl` binary should be [installed on your workstation](https://kubernetes.io/docs/getting-started-guides/minikube/#download-kubectl).
3. The `kubectl` binary should be [installed on your workstation](https://kubernetes.io/docs/getting-started-guides/minikube/#download-kubectl).
### Role Based Access Control configuration (Kubernetes 1.6+ only)
@@ -53,6 +57,12 @@ rules:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
@@ -68,10 +78,10 @@ subjects:
namespace: kube-system
```
[examples/k8s/traefik-rbac.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-rbac.yaml)
[examples/k8s/traefik-rbac.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/traefik-rbac.yaml)
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/traefik-rbac.yaml
```
For namespaced restrictions, one RoleBinding is required per watched namespace along with a corresponding configuration of Traefik's `kubernetes.namespaces` parameter.
@@ -98,7 +108,7 @@ metadata:
namespace: kube-system
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: kube-system
@@ -118,7 +128,7 @@ spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http
@@ -148,7 +158,7 @@ spec:
type: NodePort
```
[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-deployment.yaml)
[examples/k8s/traefik-deployment.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/traefik-deployment.yaml)
!!! note
The Service will expose two NodePorts which allow access to the ingress and the web interface.
@@ -164,13 +174,17 @@ metadata:
namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
selector:
matchLabels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
template:
metadata:
labels:
@@ -180,7 +194,7 @@ spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http
@@ -188,6 +202,7 @@ spec:
hostPort: 80
- name: admin
containerPort: 8080
hostPort: 8080
securityContext:
capabilities:
drop:
@@ -216,7 +231,7 @@ spec:
name: admin
```
[examples/k8s/traefik-ds.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-ds.yaml)
[examples/k8s/traefik-ds.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/traefik-ds.yaml)
!!! note
This will create a Daemonset that uses privileged ports 80/8080 on the host. This may not work on all providers, but illustrates the static (non-NodePort) hostPort binding. The `traefik-ingress-service` can still be used inside the cluster to access the DaemonSet pods.
@@ -224,11 +239,11 @@ spec:
To deploy Traefik to your cluster start by submitting one of the YAML files to the cluster with `kubectl`:
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/traefik-deployment.yaml
```
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-ds.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/traefik-ds.yaml
```
There are some significant differences between using Deployments and DaemonSets:
@@ -320,7 +335,7 @@ For more information, check out [the documentation](https://github.com/kubernete
## Submitting an Ingress to the Cluster
Lets start by creating a Service and an Ingress that will expose the [Traefik Web UI](https://github.com/containous/traefik#web-ui).
Lets start by creating a Service and an Ingress that will expose the [Traefik Web UI](https://github.com/traefik/traefik#web-ui).
```yaml
apiVersion: v1
@@ -352,13 +367,13 @@ spec:
servicePort: web
```
[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/ui.yaml)
[examples/k8s/ui.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/ui.yaml)
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/ui.yaml
```
Now lets setup an entry in our `/etc/hosts` file to route `traefik-ui.minikube` to our cluster.
Now let's setup an entry in our `/etc/hosts` file to route `traefik-ui.minikube` to our cluster.
In production you would want to set up real DNS entries.
You can get the IP address of your minikube instance by running `minikube ip`:
@@ -375,6 +390,31 @@ We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube)
For this example to work you need a TLS entrypoint. You don't have to provide a TLS certificate at this point.
For more details see [here](/configuration/entrypoints/).
You can add a TLS entrypoint by adding the following `args` to the container spec:
```yaml
--defaultentrypoints=http,https
--entrypoints=Name:https Address::443 TLS
--entrypoints=Name:http Address::80
```
Now let's add the TLS port either to the deployment:
```
ports:
- name: https
containerPort: 443
```
or to the daemon set:
```
ports:
- name: https
containerPort: 443
hostPort: 443
```
To setup an HTTPS-protected ingress, you can leverage the TLS feature of the ingress resource.
```yaml
@@ -495,7 +535,7 @@ First lets start by launching the pods for the cheese websites.
```yaml
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: stilton
labels:
@@ -521,7 +561,7 @@ spec:
- containerPort: 80
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: cheddar
labels:
@@ -547,7 +587,7 @@ spec:
- containerPort: 80
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: wensleydale
labels:
@@ -573,10 +613,10 @@ spec:
- containerPort: 80
```
[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-deployments.yaml)
[examples/k8s/cheese-deployments.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/cheese-deployments.yaml)
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-deployments.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/cheese-deployments.yaml
```
Next we need to setup a Service for each of the cheese pods.
@@ -628,10 +668,10 @@ spec:
!!! note
We also set a [circuit breaker expression](/basics/#backends) for one of the backends by setting the `traefik.backend.circuitbreaker` annotation on the service.
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml)
[examples/k8s/cheese-services.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/cheese-services.yaml)
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-services.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/cheese-services.yaml
```
Now we can submit an ingress for the cheese websites.
@@ -668,13 +708,13 @@ spec:
servicePort: http
```
[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-ingress.yaml)
[examples/k8s/cheese-ingress.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/cheese-ingress.yaml)
!!! note
we list each hostname, and add a backend service.
We list each hostname, and add a backend service.
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/cheese-ingress.yaml
```
Now visit the [Traefik dashboard](http://traefik-ui.minikube/) and you should see a frontend for each host.
@@ -723,13 +763,13 @@ spec:
servicePort: http
```
[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheeses-ingress.yaml)
[examples/k8s/cheeses-ingress.yaml](https://github.com/traefik/traefik/tree/v1.7/examples/k8s/cheeses-ingress.yaml)
!!! note
We are configuring Traefik to strip the prefix from the url path with the `traefik.frontend.rule.type` annotation so that we can use the containers from the previous example without modification.
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheeses-ingress.yaml
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/cheeses-ingress.yaml
```
```shell
@@ -775,11 +815,11 @@ Traefik will now look for cheddar service endpoints (ports on healthy pods) in b
Deploying cheddar into the cheese namespace and afterwards shutting down cheddar in the default namespace is enough to migrate the traffic.
!!! note
The kubernetes documentation does not specify this merging behavior.
The kubernetes documentation does not specify this merging behavior.
!!! note
Merging ingress definitions can cause problems if the annotations differ or if the services handle requests differently.
Be careful and extra cautious when running multiple overlapping ingress definitions.
Merging ingress definitions can cause problems if the annotations differ or if the services handle requests differently.
Be careful and extra cautious when running multiple overlapping ingress definitions.
## Specifying Routing Priorities

View File

@@ -24,7 +24,7 @@ The Traefik global configuration will be retrieved from a [Consul](https://consu
First we have to launch Consul in a container.
The [docker-compose file](https://docs.docker.com/compose/compose-file/) allows us to launch Consul and four instances of the trivial app [containous/whoami](https://github.com/containous/whoami) :
The [docker-compose file](https://docs.docker.com/compose/compose-file/) allows us to launch Consul and four instances of the trivial app [traefik/whoami](https://github.com/traefik/whoami) :
```yaml
consul:
@@ -42,16 +42,16 @@ consul:
- "8302/udp"
whoami1:
image: containous/whoami
image: traefik/whoami
whoami2:
image: containous/whoami
image: traefik/whoami
whoami3:
image: containous/whoami
image: traefik/whoami
whoami4:
image: containous/whoami
image: traefik/whoami
```
### Upload the configuration in the Key-value store
@@ -139,7 +139,7 @@ Here is the [docker-compose file](https://docs.docker.com/compose/compose-file/)
```yaml
traefik:
image: traefik
image: traefik:<stable v1.7 from https://hub.docker.com/_/traefik>
command: --consul --consul.endpoint=127.0.0.1:8500
ports:
- "80:80"

View File

@@ -129,7 +129,7 @@ As such, there is no way to handle this situation deterministically.
Finally, Marathon health checks are not mandatory (the default is to use the task state as reported by Mesos), so requiring them for Traefik would raise the entry barrier for Marathon users.
Traefik used to use the health check results as a strict requirement but moved away from it as [users reported the dramatic consequences](https://github.com/containous/traefik/issues/653).
Traefik used to use the health check results as a strict requirement but moved away from it as [users reported the dramatic consequences](https://github.com/traefik/traefik/issues/653).
#### Draining
@@ -141,4 +141,4 @@ However, implementing this fully within Traefik seems like a non-trivial underta
Additionally, the approach is less flexible compared to a custom termination handler since only the latter allows for the implementation of custom termination sequences that go beyond simple request draining (e.g., persisting a snapshot state to disk prior to terminating).
The feature is currently not implemented; a request for draining in general is at [issue 41](https://github.com/containous/traefik/issues/41).
The feature is currently not implemented; a request for draining in general is at [issue 41](https://github.com/traefik/traefik/issues/41).

View File

@@ -7,7 +7,7 @@ The cluster consists of:
- 3 servers
- 1 manager
- 2 workers
- 1 [overlay](https://docs.docker.com/engine/userguide/networking/dockernetworks/#an-overlay-network) network (multi-host networking)
- 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking)
## Prerequisites
@@ -76,7 +76,7 @@ docker-machine ssh manager "docker network create --driver=overlay traefik-net"
## Deploy Traefik
Let's deploy Traefik as a docker service in our cluster.
The only requirement for Traefik to work with swarm mode is that it needs to run on a manager node - we are going to use a [constraint](https://docs.docker.com/engine/reference/commandline/service_create/#/specify-service-constraints-constraint) for that.
The only requirement for Traefik to work with swarm mode is that it needs to run on a manager node - we are going to use a [constraint](https://docs.docker.com/engine/reference/commandline/service_create/#specify-service-constraints---constraint) for that.
```shell
docker-machine ssh manager "docker service create \
@@ -85,7 +85,7 @@ docker-machine ssh manager "docker service create \
--publish 80:80 --publish 8080:8080 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--network traefik-net \
traefik \
traefik:<stable version from https://hub.docker.com/_/traefik> \
--docker \
--docker.swarmMode \
--docker.domain=traefik \
@@ -107,7 +107,7 @@ Let's explain this command:
## Deploy your apps
We can now deploy our app on the cluster, here [whoami](https://github.com/containous/whoami), a simple web server in Go.
We can now deploy our app on the cluster, here [whoami](https://github.com/traefik/whoami), a simple web server in Go.
We start 2 services, on the `traefik-net` network.
```shell
@@ -115,14 +115,14 @@ docker-machine ssh manager "docker service create \
--name whoami0 \
--label traefik.port=80 \
--network traefik-net \
containous/whoami"
traefik/whoami"
docker-machine ssh manager "docker service create \
--name whoami1 \
--label traefik.port=80 \
--network traefik-net \
--label traefik.backend.loadbalancer.sticky=true \
containous/whoami"
traefik/whoami"
```
!!! note
@@ -130,7 +130,7 @@ docker-machine ssh manager "docker service create \
We'll demonstrate that later.
!!! note
If using `docker stack deploy`, there is [a specific way that the labels must be defined in the docker-compose file](https://github.com/containous/traefik/issues/994#issuecomment-269095109).
If using `docker stack deploy`, there is [a specific way that the labels must be defined in the docker-compose file](https://github.com/traefik/traefik/issues/994#issuecomment-269095109).
Check that everything is scheduled and started:
@@ -140,8 +140,8 @@ docker-machine ssh manager "docker service ls"
```
ID NAME MODE REPLICAS IMAGE PORTS
moq3dq4xqv6t traefik replicated 1/1 traefik:latest *:80->80/tcp,*:8080->8080/tcp
ysil6oto1wim whoami0 replicated 1/1 containous/whoami:latest
z9re2mnl34k4 whoami1 replicated 1/1 containous/whoami:latest
ysil6oto1wim whoami0 replicated 1/1 traefik/whoami:latest
z9re2mnl34k4 whoami1 replicated 1/1 traefik/whoami:latest
```
@@ -243,8 +243,8 @@ docker-machine ssh manager "docker service ls"
```
ID NAME MODE REPLICAS IMAGE PORTS
moq3dq4xqv6t traefik replicated 1/1 traefik:latest *:80->80/tcp,*:8080->8080/tcp
ysil6oto1wim whoami0 replicated 5/5 containous/whoami:latest
z9re2mnl34k4 whoami1 replicated 5/5 containous/whoami:latest
ysil6oto1wim whoami0 replicated 5/5 traefik/whoami:latest
z9re2mnl34k4 whoami1 replicated 5/5 traefik/whoami:latest
```
## Access to your `whoami0` through Traefik multiple times.

View File

@@ -7,7 +7,7 @@ The cluster consists of:
- 2 servers
- 1 swarm master
- 2 swarm nodes
- 1 [overlay](https://docs.docker.com/engine/userguide/networking/dockernetworks/#an-overlay-network) network (multi-host networking)
- 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking)
## Prerequisites
@@ -81,7 +81,7 @@ docker $(docker-machine config mhs-demo0) run \
-p 80:80 -p 8080:8080 \
--net=my-net \
-v /var/lib/boot2docker/:/ssl \
traefik \
traefik:<stable version from https://hub.docker.com/_/traefik> \
-l DEBUG \
-c /dev/null \
--docker \
@@ -112,12 +112,12 @@ Let's explain this command:
## Deploy your apps
We can now deploy our app on the cluster, here [whoami](https://github.com/containous/whoami), a simple web server in GO, on the network `my-net`:
We can now deploy our app on the cluster, here [whoami](https://github.com/traefik/whoami), a simple web server in GO, on the network `my-net`:
```shell
eval $(docker-machine env --swarm mhs-demo0)
docker run -d --name=whoami0 --net=my-net --env="constraint:node==mhs-demo0" containous/whoami
docker run -d --name=whoami1 --net=my-net --env="constraint:node==mhs-demo1" containous/whoami
docker run -d --name=whoami0 --net=my-net --env="constraint:node==mhs-demo0" traefik/whoami
docker run -d --name=whoami1 --net=my-net --env="constraint:node==mhs-demo1" traefik/whoami
```
Check that everything is started:
@@ -127,8 +127,8 @@ docker ps
```
```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba2c21488299 containous/whoami "/whoamI" 8 seconds ago Up 9 seconds 80/tcp mhs-demo1/whoami1
8147a7746e7a containous/whoami "/whoamI" 19 seconds ago Up 20 seconds 80/tcp mhs-demo0/whoami0
ba2c21488299 traefik/whoami "/whoamI" 8 seconds ago Up 9 seconds 80/tcp mhs-demo1/whoami1
8147a7746e7a traefik/whoami "/whoamI" 19 seconds ago Up 20 seconds 80/tcp mhs-demo0/whoami0
8fbc39271b4c traefik "/traefik -l DEBUG -c" 36 seconds ago Up 37 seconds 192.168.99.101:80->80/tcp, 192.168.99.101:8080->8080/tcp mhs-demo0/serene_bhabha
```

View File

@@ -72,7 +72,7 @@ services :
traefik:
build:
context: ../..
image: containous/traefik:latest
image: traefik/traefik:latest
command: --configFile=/etc/traefik/conf/acme.toml
restart: unless-stopped
extra_hosts:

View File

@@ -119,7 +119,7 @@ services:
storeconfig:
build:
context: ../..
image: containous/traefik
image: traefik/traefik
volumes:
- "./traefik.toml:/traefik.toml:ro"
command: storeconfig --debug
@@ -129,7 +129,7 @@ services:
traefik01:
build:
context: ../..
image: containous/traefik
image: traefik/traefik
command: ${TRAEFIK_CMD}
extra_hosts:
- traefik.boulder.com:172.17.0.1
@@ -152,7 +152,7 @@ services:
traefik02:
build:
context: ../..
image: containous/traefik
image: traefik/traefik
command: ${TRAEFIK_CMD}
extra_hosts:
- traefik.boulder.com:172.17.0.1

View File

@@ -1,5 +1,5 @@
traefik:
image: traefik
image: traefik:v1.7
command: --api --rancher --rancher.domain=rancher.localhost --rancher.endpoint=http://example.com --rancher.accesskey=XXXXXXX --rancher.secretkey=YYYYYY --logLevel=DEBUG
ports:
- "80:80"

View File

@@ -1,5 +1,5 @@
traefik:
image: traefik
image: traefik:v1.7
command: -c /dev/null --api --docker --docker.domain=docker.localhost --logLevel=DEBUG
ports:
- "80:80"

View File

@@ -1,6 +1,6 @@
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: stilton
labels:
@@ -33,7 +33,7 @@ spec:
- containerPort: 80
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: cheddar
labels:
@@ -66,7 +66,7 @@ spec:
- containerPort: 80
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: wensleydale
labels:

View File

@@ -6,7 +6,7 @@ metadata:
namespace: kube-system
---
kind: Deployment
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: kube-system
@@ -26,7 +26,7 @@ spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http

View File

@@ -6,13 +6,17 @@ metadata:
namespace: kube-system
---
kind: DaemonSet
apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
selector:
matchLabels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
template:
metadata:
labels:
@@ -22,7 +26,7 @@ spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http

View File

@@ -22,6 +22,12 @@ rules:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1

View File

@@ -2,7 +2,7 @@
In this quickstart, we'll use [Docker compose](https://docs.docker.com/compose) to create our demo infrastructure.
To save some time, you can clone [Traefik's repository](https://github.com/containous/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/containous/traefik/tree/master/examples/quickstart/) directory.
To save some time, you can clone [Traefik's repository](https://github.com/traefik/traefik) and use the quickstart files located in the [examples/quickstart](https://github.com/traefik/traefik/tree/v1.7/examples/quickstart/) directory.
### 1 — Launch Traefik — Tell It to Listen to Docker
@@ -13,7 +13,7 @@ version: '3'
services:
reverse-proxy:
image: traefik # The official Traefik docker image
image: traefik:v1.7 # The official Traefik docker image
command: --api --docker # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
@@ -101,7 +101,7 @@ IP: 172.27.0.4
### 4 — Enjoy Traefik's Magic
Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it might be time to dive into [the documentation](https://docs.traefik.io/) and let Traefik work for you!
Whatever your infrastructure is, there is probably [an available Traefik backend](https://docs.traefik.io/#supported-backends) that will do the job.
Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it might be time to dive into [the documentation](https://doc.traefik.io/traefik/v1.7/) and let Traefik work for you!
Whatever your infrastructure is, there is probably [an available Traefik backend](https://doc.traefik.io/traefik/v1.7/#supported-backends) that will do the job.
Our recommendation would be to see for yourself how simple it is to enable HTTPS with [Traefik's let's encrypt integration](https://docs.traefik.io/user-guide/examples/#lets-encrypt-support) using the dedicated [user guide](https://docs.traefik.io/user-guide/docker-and-lets-encrypt/).
Our recommendation would be to see for yourself how simple it is to enable HTTPS with [Traefik's let's encrypt integration](https://doc.traefik.io/traefik/v1.7/user-guide/examples/#lets-encrypt-support) using the dedicated [user guide](https://doc.traefik.io/traefik/v1.7/user-guide/docker-and-lets-encrypt/).

View File

@@ -3,7 +3,7 @@ version: '3'
services:
# The reverse proxy service (Traefik)
reverse-proxy:
image: traefik # The official Traefik docker image
image: traefik:v1.7 # The official Traefik docker image
command: --api --docker # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
@@ -13,6 +13,6 @@ services:
# A container that exposes a simple API
whoami:
image: emilevauge/whoami # A container that exposes an API to show it's IP address
image: emilevauge/whoami # A container that exposes an API to show its IP address
labels:
- "traefik.frontend.rule=Host:whoami.docker.localhost"

50
exp.Dockerfile Normal file
View File

@@ -0,0 +1,50 @@
# WEBUI
FROM node:8.15.0 as webui
ENV WEBUI_DIR /src/webui
RUN mkdir -p $WEBUI_DIR
COPY ./webui/ $WEBUI_DIR/
WORKDIR $WEBUI_DIR
RUN yarn install
RUN npm run build
# BUILD
FROM golang:1.16-alpine as gobuild
RUN apk --update upgrade \
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
&& update-ca-certificates \
&& rm -rf /var/cache/apk/*
RUN mkdir -p /usr/local/bin \
&& curl -fsSL -o /usr/local/bin/go-bindata https://github.com/containous/go-bindata/releases/download/v1.0.0/go-bindata \
&& chmod +x /usr/local/bin/go-bindata
WORKDIR /go/src/github.com/traefik/traefik
# Download go modules
COPY go.mod .
COPY go.sum .
RUN GO111MODULE=on GOPROXY=https://proxy.golang.org go mod download
COPY . /go/src/github.com/traefik/traefik
RUN rm -rf /go/src/github.com/traefik/traefik/static/
COPY --from=webui /src/static/ /go/src/github.com/traefik/traefik/static/
RUN ./script/make.sh generate binary
## IMAGE
FROM scratch
COPY --from=gobuild /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=gobuild /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=gobuild /go/src/github.com/traefik/traefik/dist/traefik /
EXPOSE 80
VOLUME ["/tmp"]
ENTRYPOINT ["/traefik"]

141
go.mod Normal file
View File

@@ -0,0 +1,141 @@
module github.com/traefik/traefik
go 1.16
require (
github.com/ArthurHlt/go-eureka-client v0.0.0-20170403140305-9d0a49cbd39a
github.com/ArthurHlt/gominlog v0.0.0-20170402142412-72eebf980f46 // indirect
github.com/BurntSushi/toml v0.3.1
github.com/BurntSushi/ty v0.0.0-20140213233908-6add9cd6ad42
github.com/Masterminds/sprig v2.19.0+incompatible
github.com/Microsoft/go-winio v0.4.2 // indirect
github.com/NYTimes/gziphandler v1.0.1-0.20180125165240-289a3b81f5ae
github.com/PuerkitoBio/purell v1.0.0 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 // indirect
github.com/VividCortex/gohistogram v1.0.0 // indirect
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
github.com/abronan/valkeyrie v0.0.0-20171113095143-063d875e3c5f
github.com/armon/go-metrics v0.3.0 // indirect
github.com/armon/go-proxyproto v0.0.0-20170620220930-48572f11356f
github.com/aws/aws-sdk-go v1.23.0
github.com/cenk/backoff v2.1.1+incompatible
github.com/codahale/hdrhistogram v0.9.0 // indirect
github.com/containous/flaeg v1.4.1
github.com/containous/mux v0.0.0-20181024131434-c33f32e26898
github.com/containous/staert v3.1.2+incompatible
github.com/containous/traefik-extra-service-fabric v1.7.1-0.20210227093100-8dcd57b609a8
github.com/coreos/bbolt v1.3.1-coreos.5 // indirect
github.com/coreos/etcd v3.3.5+incompatible // indirect
github.com/coreos/go-semver v0.2.0 // indirect
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/davecgh/go-spew v1.1.1
github.com/docker/docker v1.4.2-0.20171023200535-7848b8beb9d3
github.com/docker/go-connections v0.3.0
github.com/docker/leadership v0.0.0-00010101000000-000000000000
github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9 // indirect
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect
github.com/eapache/channels v1.1.0
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect
github.com/elazarl/go-bindata-assetfs v1.0.0
github.com/emicklei/go-restful v1.1.4-0.20160814184150-89ef8af493ab // indirect
github.com/fatih/color v1.5.1-0.20170523202404-62e9147c64a1 // indirect
github.com/gambol99/go-marathon v0.7.2-0.20180614232016-99a156b96fb2
github.com/go-acme/lego/v3 v3.0.1
github.com/go-check/check v0.0.0-00010101000000-000000000000
github.com/go-kit/kit v0.8.0
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1 // indirect
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9 // indirect
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501 // indirect
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.3.2
github.com/google/go-github v9.0.0+incompatible
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.1.1
github.com/googleapis/gnostic v0.1.0 // indirect
github.com/gorilla/websocket v1.4.2
github.com/gravitational/trace v1.1.3 // indirect
github.com/gregjones/httpcache v0.0.0-20171119193500-2bcd89a1743f // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/hashicorp/consul v1.0.6
github.com/hashicorp/go-msgpack v1.1.5 // indirect
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031
github.com/hashicorp/memberlist v0.1.5 // indirect
github.com/hashicorp/serf v0.8.2-0.20170308193951-19f2c401e122 // indirect
github.com/influxdata/influxdb v1.3.7
github.com/jjcollinge/servicefabric v0.0.2-0.20180125130438-8eebe170fa1b
github.com/juju/ratelimit v1.0.1 // indirect
github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad
github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807
github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a // indirect
github.com/mattn/go-colorable v0.0.8-0.20170210172801-5411d3eea597 // indirect
github.com/mesos/mesos-go v0.0.3-0.20150930144802-068d5470506e
github.com/mesosphere/mesos-dns v0.0.0-00010101000000-000000000000
github.com/miekg/dns v1.1.26
github.com/mitchellh/copystructure v0.0.0-20170525013902-d23ffcb85de3
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/mapstructure v1.1.2
github.com/mitchellh/reflectwalk v0.0.0-20170726202117-63d60e9d0dbc // indirect
github.com/mvdan/xurls v1.1.1-0.20170309204242-db96455566f0
github.com/ogier/pflag v0.0.2-0.20160129220114-45c278ab3607
github.com/opencontainers/image-spec v1.0.0-rc5.0.20170515205857-f03dbe35d449 // indirect
github.com/opencontainers/runc v1.0.0-rc3.0.20170425215914-b6b70e534517 // indirect
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
github.com/opentracing/opentracing-go v1.0.2
github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/philhofer/fwd v1.0.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.1.0
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
github.com/rancher/go-rancher v0.1.1-0.20171004213057-52e2f4895340
github.com/rancher/go-rancher-metadata v0.0.0-00010101000000-000000000000
github.com/ryanuber/go-glob v1.0.0
github.com/samuel/go-zookeeper v0.0.0-20161028232340-1d7be4effb13 // indirect
github.com/shopspring/decimal v1.1.1-0.20191009025716-f1972eb1d1f5
github.com/sirupsen/logrus v1.4.2
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spf13/pflag v0.0.0-20160427162146-cb88ea77998c // indirect
github.com/stretchr/testify v1.5.1
github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13
github.com/thoas/stats v0.0.0-20190104110215-4975baf6a358
github.com/tinylib/msgp v1.0.2 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/tv42/zbase32 v0.0.0-20150911225513-03389da7e0bf // indirect
github.com/uber/jaeger-client-go v2.15.0+incompatible
github.com/uber/jaeger-lib v1.5.0
github.com/ugorji/go v1.1.1 // indirect
github.com/unrolled/render v0.0.0-20170109143244-50716a0a8537
github.com/unrolled/secure v1.0.5
github.com/urfave/negroni v0.2.1-0.20170426175938-490e6a555d47
github.com/vdemeester/shakers v0.1.0
github.com/vulcand/oxy v1.2.0
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
golang.org/x/net v0.0.0-20190923162816-aa69164e4478
golang.org/x/sys v0.0.0-20191115151921-52ab43148777 // indirect
google.golang.org/grpc v1.22.1
gopkg.in/DataDog/dd-trace-go.v1 v1.13.0
gopkg.in/fsnotify.v1 v1.4.7
gopkg.in/inf.v0 v0.9.0 // indirect
gopkg.in/yaml.v2 v2.2.5
k8s.io/api v0.0.0-20171214033149-af4bc157c3a2
k8s.io/apimachinery v0.0.0-20171207040834-180eddb345a5
k8s.io/client-go v6.0.0+incompatible
k8s.io/kube-openapi v0.0.0-20180201014056-275e2ce91dec // indirect
)
replace (
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20180112153951-65b0cdae8d7f
github.com/docker/docker => github.com/docker/engine v0.0.0-20190725163905-fa8dd90ceb7b
github.com/docker/leadership => github.com/containous/leadership v0.1.1-0.20180123135645-a2e096d9fe0a
github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a
github.com/mesosphere/mesos-dns => github.com/containous/mesos-dns v0.5.3-rc1.0.20160623212649-b47dc4c19f21
github.com/rancher/go-rancher-metadata => github.com/containous/go-rancher-metadata v0.0.0-20180116133453-e937e8308985
gopkg.in/fsnotify.v1 => github.com/fsnotify/fsnotify v1.4.2
)

732
go.sum Normal file
View File

@@ -0,0 +1,732 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
code.cloudfoundry.org/clock v1.0.0 h1:kFXWQM4bxYvdBw2X8BbBeXwQNgfoWv1vqAk2ZZyBN2o=
code.cloudfoundry.org/clock v1.0.0/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8=
contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc=
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
github.com/ArthurHlt/go-eureka-client v0.0.0-20170403140305-9d0a49cbd39a h1:Vrl1WHqCac7HPIxdWvqom9sDMbZ8lKlAO2JX7VeZcM4=
github.com/ArthurHlt/go-eureka-client v0.0.0-20170403140305-9d0a49cbd39a/go.mod h1:yOAMDH2SD2lzSxAgC3B/89nYfMQp9Z8gbfon2v8xbSw=
github.com/ArthurHlt/gominlog v0.0.0-20170402142412-72eebf980f46 h1:wa1Aba5rUE3Bt4kJYn44Jw3PeQr/0TooYRdKe55Hz3k=
github.com/ArthurHlt/gominlog v0.0.0-20170402142412-72eebf980f46/go.mod h1:1V+b/6E0XgMTStyFLfNJDUvTn1zsp5hkOU6+YowxRfU=
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible h1:1JP8SKfroEakYiQU2ZyPDosh8w2Tg9UopKt88VyQPt4=
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg=
github.com/Azure/go-autorest/autorest v0.5.0 h1:Mlm9qy2fpQ9MvfyI41G2Zf5B4CsgjjNbLOWszfK6KrY=
github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw=
github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
github.com/Azure/go-autorest/autorest/adal v0.2.0 h1:7IBDu1jgh+ADHXnEYExkV9RE/ztOOlxdACkkPRthGKw=
github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 h1:YgO/vSnJEc76NLw2ecIXvXa8bDWiqf1pOJzARAoZsYU=
github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM=
github.com/Azure/go-autorest/autorest/azure/cli v0.1.0 h1:YTtBrcb6mhA+PoSW8WxFDoIIyjp13XqJeX80ssQtri4=
github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/to v0.2.0 h1:nQOZzFCudTh+TvquAtCRjM01VEYx85e9qbwt5ncW4L8=
github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
github.com/Azure/go-autorest/autorest/validation v0.1.0 h1:ISSNzGUh+ZSzizJWOWzs8bwpXIePbGLW4z/AmUFGH5A=
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc=
github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/ty v0.0.0-20140213233908-6add9cd6ad42 h1:ic5cJNq4hRFkGueapY8qM0cCRcPJtBDXXqAVyBbYIoc=
github.com/BurntSushi/ty v0.0.0-20140213233908-6add9cd6ad42/go.mod h1:93VqBEPRhpQ5HzkrTGplVAFnKzimh9ADZh4IERk9tM8=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.2.2 h1:ptelpryog9A0pR4TGFvIAvw2c8SaNrYkFtfrxhSviss=
github.com/Masterminds/semver v1.2.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.19.0+incompatible h1:xTFLLXzR0JJGQe7M492jAOJ9F3jpYdNiWcL8h9JOV8Y=
github.com/Masterminds/sprig v2.19.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Microsoft/ApplicationInsights-Go v0.3.1-0.20171018060007-98ac7ca026c2 h1:6TXp5yLCwRNvwNcrrvKeNizJVgOvvZsaH6rdRNpcg8M=
github.com/Microsoft/ApplicationInsights-Go v0.3.1-0.20171018060007-98ac7ca026c2/go.mod h1:CukZ/G66zxXtI+h/VcVn3eVVDGDHfXM2zVILF7bMmsg=
github.com/Microsoft/go-winio v0.3.8/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.2 h1:ZJbCAgklAxf91aYmsiUHS7dIGCqw+EjpOg/oq/Groaw=
github.com/Microsoft/go-winio v0.4.2/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/NYTimes/gziphandler v1.0.1-0.20180125165240-289a3b81f5ae h1:ZATKbD8FIxn4DhD6pIqCmPbtxnm45iyddiAZliLp+nw=
github.com/NYTimes/gziphandler v1.0.1-0.20180125165240-289a3b81f5ae/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24=
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
github.com/PuerkitoBio/purell v1.0.0 h1:0GoNN3taZV6QI81IXgCbxMyEaJDXMSIjArYBCYzVVvs=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 h1:JCHLVE3B+kJde7bIEo5N4J+ZbLhp0J1Fs+ulyRws4gE=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/sarama v1.19.0 h1:9oksLxC6uxVPHPVYUmq6xhr1BOF/hHobWH2UzO67z1s=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/abronan/valkeyrie v0.0.0-20171113095143-063d875e3c5f h1:HTH6xC5RMbjwE+u9TqCXmVZT+1wLq/mwWKIS0QJ0t3w=
github.com/abronan/valkeyrie v0.0.0-20171113095143-063d875e3c5f/go.mod h1:oqs1pp6MTXt4fov7I9OsfvD+jn4n9Q74Yt/oRGMakDM=
github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0 h1:rXPPPxDA4GCPN0YWwyVHMzcxVpVg8gai2uGhJ3VqOSs=
github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0/go.mod h1:zpDJeKyp9ScW4NNrbdr+Eyxvry3ilGPewKoXw3XGN1k=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee h1:NYqDBPkhVYt68W3yoGoRRi32i3MLx2ey7SFkJ1v/UI0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ=
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU=
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
github.com/armon/go-proxyproto v0.0.0-20170620220930-48572f11356f h1:5FTBPzFrJqeKm10UPWvw8qU8/CLrS0OAX87PyGkycIc=
github.com/armon/go-proxyproto v0.0.0-20170620220930-48572f11356f/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
github.com/aws/aws-sdk-go v1.23.0 h1:ilfJN/vJtFo1XDFxB2YMBYGeOvGZl6Qow17oyD4+Z9A=
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cenk/backoff v2.1.1+incompatible h1:gaShhlJc32b7ht9cwld/ti0z7tJOf69oUEA8jJNYV48=
github.com/cenk/backoff v2.1.1+incompatible/go.mod h1:7FtoeaSnHoZnmZzz47cM35Y9nSW7tNyaidugnHTaFDE=
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.10.0 h1:wJPNqfrQO0w3fCiQcf/2T4lR2y6Q2fAwRszllljgb8I=
github.com/cloudflare/cloudflare-go v0.10.0/go.mod h1:fOESqHl/jzAmCtEyjceLkw3v0rVjzl8V9iehxZPynXY=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codahale/hdrhistogram v0.9.0 h1:9GjrtRI+mLEFPtTfR/AZhcxp+Ii8NZYWq5104FbZQY0=
github.com/codahale/hdrhistogram v0.9.0/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY=
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containous/check v0.0.0-20170915194414-ca0bf163426a h1:8esAQaPKjfntQR1bag/mAOvWJd5HqSX5nsa+0KT63zo=
github.com/containous/check v0.0.0-20170915194414-ca0bf163426a/go.mod h1:eQOqZ7GoFsLxI7jFKLs7+Nv2Rm1x4FyK8d2NV+yGjwQ=
github.com/containous/flaeg v1.4.1 h1:VTouP7EF2JeowNvknpP3fJAJLUDsQ1lDHq/QQTQc1xc=
github.com/containous/flaeg v1.4.1/go.mod h1:wgw6PDtRURXHKFFV6HOqQxWhUc3k3Hmq22jw+n2qDro=
github.com/containous/go-http-auth v0.4.1-0.20180112153951-65b0cdae8d7f h1:AgXgJSqQmsiNFW268OGe/y7Mn4jiCWaMUk05qser3Bo=
github.com/containous/go-http-auth v0.4.1-0.20180112153951-65b0cdae8d7f/go.mod h1:dCmRGidPSLagL8D/2u7yIO6Y/8D/yuYX9EdKrnrhpCA=
github.com/containous/go-rancher-metadata v0.0.0-20180116133453-e937e8308985 h1:te46GKaNL+FBRE4weHNHiK0OW0+LrNlmnlRgJ3WWH7o=
github.com/containous/go-rancher-metadata v0.0.0-20180116133453-e937e8308985/go.mod h1:YTAhdMF+tmHPGF7v0uZJ22+XNY/jz1ZYdBCeTZnsrYU=
github.com/containous/leadership v0.1.1-0.20180123135645-a2e096d9fe0a h1:uO1UhN+1Sa2naTIMR2gxPVzSOVaXvx6WDLJrEFIL7pA=
github.com/containous/leadership v0.1.1-0.20180123135645-a2e096d9fe0a/go.mod h1:zPmt8vlwi1dmWClYNM6YDf4LVbZ2i/3ghpkshPO4zzU=
github.com/containous/mesos-dns v0.5.3-rc1.0.20160623212649-b47dc4c19f21 h1:3MGyzW61u7RpqMCBgZ3hdY0zr3TOfoaBnV8Vk95sdPM=
github.com/containous/mesos-dns v0.5.3-rc1.0.20160623212649-b47dc4c19f21/go.mod h1:NoK9LZGn7B49a5/VglEq2Sb5TTkaJpn2QeJq2c8Xc9w=
github.com/containous/mux v0.0.0-20181024131434-c33f32e26898 h1:1srn9voikJGofblBhWy3WuZWqo14Ou7NaswNG/I2yWc=
github.com/containous/mux v0.0.0-20181024131434-c33f32e26898/go.mod h1:z8WW7n06n8/1xF9Jl9WmuDeZuHAhfL+bwarNjsciwwg=
github.com/containous/staert v3.1.2+incompatible h1:jgi4ndHADhTJLgEDny3VRsAytMYKNeSUw8QRAxpLCn4=
github.com/containous/staert v3.1.2+incompatible/go.mod h1:LtjlnVpIrL+koUgIAwMBPcH2071WmoS6bor2vDSAwVE=
github.com/containous/traefik-extra-service-fabric v1.7.1-0.20210227093100-8dcd57b609a8 h1:RbkUzumMhjRUE19u1Dsxy9WmdL4eiCnEE6QQgZTNc60=
github.com/containous/traefik-extra-service-fabric v1.7.1-0.20210227093100-8dcd57b609a8/go.mod h1:qRv3Vc/pL5w2TCXuP54tH5pVFA+MbxA8Ijs5R49De4M=
github.com/coreos/bbolt v1.3.1-coreos.5 h1:e1dvLp11PaS48015lANrxa1aest1AkpEi4Hx/eLQQ3U=
github.com/coreos/bbolt v1.3.1-coreos.5/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.5+incompatible h1:0qcOHgI5inKvd8lfaOD3KDC8QH2JQC86a1n81KXkRS4=
github.com/coreos/etcd v3.3.5+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b h1:+mtZ0WjVZwTX0RVrXMXDwuYVaNeHGvWBW1UwJeMR+2M=
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpu/goacmedns v0.0.1 h1:GeIU5chKys9zmHgOAgP+bstRaLqcGQ6HJh/hLw9hrus=
github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decker502/dnspod-go v0.2.0 h1:6dwhUFCYbC5bgpebLKn7PrI43e/5mn9tpUL9YcYCdTU=
github.com/decker502/dnspod-go v0.2.0/go.mod h1:qsurYu1FgxcDwfSwXJdLt4kRsBLZeosEb9uq4Sy+08g=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2 h1:G9/PqfhOrt8JXnw0DGTfVoOkKHDhOlEZqhE/cu+NvQM=
github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dnsimple/dnsimple-go v0.30.0 h1:IBIrn9jMKRMwporIRwdFyKdnHXVmwy6obnguB+ZMDIY=
github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/docker/cli v0.0.0-20190711175710-5b38d82aa076 h1:bYvTMcZVIsw5l+uhPIPBI8VCVPKXgyQhP63+xXfM8bw=
github.com/docker/cli v0.0.0-20190711175710-5b38d82aa076/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/engine v0.0.0-20190725163905-fa8dd90ceb7b h1:rN+GLmgWe6Yb5E8yfvGmgKfksvla7QyvqFCUKWTD8Qo=
github.com/docker/engine v0.0.0-20190725163905-fa8dd90ceb7b/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 h1:X0fj836zx99zFu83v/M79DuBn84IL/Syx1SY6Y5ZEMA=
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9 h1:Z+aRYtQXR6iFSAnoaAq/dUTcZvL1ph8uWlsrmfIP8Bs=
github.com/docker/libcompose v0.4.1-0.20190808084053-143e0f3f1ab9/go.mod h1:YZ/h8H7gZ7/SOoviPEvSYgHomvbB82iyHvGXLVTNFwQ=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e h1:rMOGp6HPeMHbdLrZkX2nD+94uqDunc27tXVuS+ey4mQ=
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw=
github.com/eapache/channels v1.1.0 h1:F1taHcn7/F0i8DYqKXJnyhJcVpp2kgFcNePxXtnyu4k=
github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0=
github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/emicklei/go-restful v1.1.4-0.20160814184150-89ef8af493ab h1:xgu6tEZDKL98r0vSckOPDm3M4fAvKeFB4GAvC0Tm2IU=
github.com/emicklei/go-restful v1.1.4-0.20160814184150-89ef8af493ab/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI=
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
github.com/fatih/color v1.5.1-0.20170523202404-62e9147c64a1 h1:q/f2xTvS5mNOIa0IXpjy/Q58OygEAjnslXWU3arEE58=
github.com/fatih/color v1.5.1-0.20170523202404-62e9147c64a1/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.2 h1:v5tKwtf2hNhBV24eNYfQ5UmvFOGlOCmRqk7/P1olxtk=
github.com/fsnotify/fsnotify v1.4.2/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gambol99/go-marathon v0.7.2-0.20180614232016-99a156b96fb2 h1:lr9e2691cDx1cnlANcdFI9ENHFqoK8sffp/Lh1zU/Vg=
github.com/gambol99/go-marathon v0.7.2-0.20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v3 v3.0.1 h1:SqT5s8QAC91mKnICjHmExv0dWnHTKzZs9IGExJWwOVw=
github.com/go-acme/lego/v3 v3.0.1/go.mod h1:sMoLjf8BUo4Jexg+6Xw5KeFx98KVZ7Nfczh9tzLyhJU=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-ini/ini v1.44.0 h1:8+SRbfpRFlIunpSum4BEf1ClTtVjOgKzgBv9pHFkI6w=
github.com/go-ini/ini v1.44.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1 h1:wSt/4CYxs70xbATrGXhokKF1i0tZjENLOo1ioIO13zk=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9 h1:tF+augKRWlWx0J0B7ZyyKSiTyV6E1zZe+7b3qQlcEf8=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501 h1:C1JKChikHGpXwT5UQDFaryIpDtyyGL/CR6C2kB7F1oc=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87 h1:zP3nY8Tk2E6RTkqGYrarZXuzh+ffyLDljLxCy1iJw80=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-github v9.0.0+incompatible h1:US9GklxPFtBOBUz+pdGJ5Gy6zKkUc+/bDc0ZD/7cSDk=
github.com/google/go-github v9.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gophercloud/gophercloud v0.3.0 h1:6sjpKIpVwRIIwmcEGp+WwNovNsem+c+2vm6oxshRpL8=
github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v0.0.0-20160317213430-0eeaf8392f5b/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI=
github.com/gravitational/trace v1.1.3 h1:ijH16/Y+AXa+znTdJfpqbUmThdFqdzRAsLjaw0aWc18=
github.com/gravitational/trace v1.1.3/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI=
github.com/gregjones/httpcache v0.0.0-20171119193500-2bcd89a1743f h1:kOkUP6rcVVqC+KlKKENKtgfFfJyDySYhqL9srXooghY=
github.com/gregjones/httpcache v0.0.0-20171119193500-2bcd89a1743f/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/consul v1.0.6 h1:N5444NVNdT/FZddKtLqlYVyY47RmoSrBMxaAdtMgvRc=
github.com/hashicorp/consul v1.0.6/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=
github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E=
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg=
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031 h1:c3Xdf5fTpk+hqhxqCO+ymqjfUXV9+GZqNgTtlnVzDos=
github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/memberlist v0.1.5 h1:AYBsgJOW9gab/toO5tEB8lWetVgDKZycqkebJ8xxpqM=
github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2-0.20170308193951-19f2c401e122 h1:PK6ok2N+mlys1Gn4Lp9Vp+UAozMTmCp4kjbr4tyNgIY=
github.com/hashicorp/serf v0.8.2-0.20170308193951-19f2c401e122/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E=
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/influxdata/influxdb v1.3.7 h1:CU7Ks9h4KZnoatC8Y+U4Xldw+CVbw6OoXquapsn0Liw=
github.com/influxdata/influxdb v1.3.7/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/jjcollinge/logrus-appinsights v0.0.0-20180126100925-9b66602d496a h1:dbh2uh0H872DdONaYeaKbpqVCmrlDZu5w9GvT8k7xi4=
github.com/jjcollinge/logrus-appinsights v0.0.0-20180126100925-9b66602d496a/go.mod h1:QYM9INeGvFuos5WMzdEWstBFDFV8UMRYVTMi19CFLLA=
github.com/jjcollinge/servicefabric v0.0.2-0.20180125130438-8eebe170fa1b h1:7uVeTMd+3V33Hl/ON+7/br/x+aDsJhNXkpjMAiy+sRc=
github.com/jjcollinge/servicefabric v0.0.2-0.20180125130438-8eebe170fa1b/go.mod h1:B1V4fd6vKwSO6pQq0mcBnxcbwjpeNu1y6fDworxmNvY=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY=
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181 h1:TrxPzApUukas24OMMVDUMlCs1XCExJtnGaDEiIAR4oQ=
github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v0.0.0-20150511174710-5cf931ef8f76/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/labbsr0x/bindman-dns-webhook v1.0.0 h1:gooRvyQtVOCtV/l9ZCI4CManZeVN/kUWG/vugRqHqv4=
github.com/labbsr0x/bindman-dns-webhook v1.0.0/go.mod h1:pn4jcNjxSywRWDPDyGkFzgSnwty18OFdiUFc6S6fpgc=
github.com/labbsr0x/goh v0.0.0-20190417202808-8b16b4848295 h1:5hXo89CXm3J5yyggBT3FJL4dN2gcfwxWwg0vXKiErSk=
github.com/labbsr0x/goh v0.0.0-20190417202808-8b16b4848295/go.mod h1:RBxeaayaaMmp7GxwHiKANjkg9e+rxjOm4mB5vD5rt/I=
github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad h1:nTyRWZ864mnHUnusBCVA628AZFgfGHwRUpbHqGhRQr8=
github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad/go.mod h1:GyCk/ifDcqsU1tsRMMWqXANnTtxzcwEWscb7j5qmblM=
github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807 h1:/7J1WDQd6Xn1Pr8KtE2I/7/cKw66AV3hBUOyxqyXo84=
github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807/go.mod h1:std11u6pTaNwryy0Hy1dTQNdHKka1jNpflEieKtv5VE=
github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591 h1:+zkZyvOyHZZUnITx0oJxAG/2+YLOjmy8YMMa1aWyrs4=
github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591/go.mod h1:EBQ0jeOrBpOTkquwjmJl4W6z5xqlf5oA2LZfTqRNcO0=
github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM=
github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA=
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f h1:aOqSQstfwSx9+tcM/xiKTio3IVjs7ZL2vU8kI9bI6bM=
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f/go.mod h1:V3EvCedtJTvUYzJF2GZMRB0JMlai+6cBu3VCTQz33GQ=
github.com/mailgun/multibuf v0.0.0-20150714184110-565402cd71fb h1:m2FGM8K2LC9Zyt/7zbQNn5Uvf/YV7vFWKtoMcC7hHU8=
github.com/mailgun/multibuf v0.0.0-20150714184110-565402cd71fb/go.mod h1:E0vRBBIQUHcRtmL/oR6w/jehh4FJqJFxe86gBnw9gXc=
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 h1:Kg/NPZLLC3aAFr1YToMs98dbCdhootQ1hZIvZU28hAQ=
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51/go.mod h1:RYmqHbhWwIz3z9eVmQ2rx82rulEMG0t+Q1bzfc9DYN4=
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f h1:ZZYhg16XocqSKPGNQAe0aeweNtFxuedbwwb4fSlg7h4=
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f/go.mod h1:8heskWJ5c0v5J9WH89ADhyal1DOZcayll8fSbhB+/9A=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a h1:TpvdAwDAt1K4ANVOfcihouRdvP+MgAfDWwBuct4l6ZY=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-colorable v0.0.8-0.20170210172801-5411d3eea597 h1:Zw9aNQ5CQ3SERpCiZrPh4vdWcBWogoEd5m8AFf2QWVs=
github.com/mattn/go-colorable v0.0.8-0.20170210172801-5411d3eea597/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mesos/mesos-go v0.0.3-0.20150930144802-068d5470506e h1:T6vlRQ7mbmHEkrkku4q++6VqFKJtOE3TnRoWMOOTFH4=
github.com/mesos/mesos-go v0.0.3-0.20150930144802-068d5470506e/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/mitchellh/copystructure v0.0.0-20170525013902-d23ffcb85de3 h1:dECZqiJYhKdj9QlLpiQaRDXHDXRTdiyZI3owdDGhlYY=
github.com/mitchellh/copystructure v0.0.0-20170525013902-d23ffcb85de3/go.mod h1:eOsF2yLPlBBJPvD+nhl5QMTBSOBbOph6N7j/IDUw7PY=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0=
github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y=
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v0.0.0-20170726202117-63d60e9d0dbc h1:gqYjvctjtX4GHzgfutJxZpvZ7XhGwQLGR5BASwhpO2o=
github.com/mitchellh/reflectwalk v0.0.0-20170726202117-63d60e9d0dbc/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mvdan/xurls v1.1.1-0.20170309204242-db96455566f0 h1:MPjK62TMl/A3uJ97yjcnolL02WEJ6DEysYL0s6jWp5g=
github.com/mvdan/xurls v1.1.1-0.20170309204242-db96455566f0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/nrdcg/auroradns v1.0.0 h1:b+NpSqNG6HzMqX2ohGQe4Q/G0WQq8pduWCiZ19vdLY8=
github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw=
github.com/nrdcg/goinwx v0.6.1 h1:AJnjoWPELyCtofhGcmzzcEMFd9YdF2JB/LgutWsWt/s=
github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ=
github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=
github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
github.com/ogier/pflag v0.0.2-0.20160129220114-45c278ab3607 h1:xZoOomu8/sOa+6Q469LrXeyq2YsmkhZo8wU6EzNWMDg=
github.com/ogier/pflag v0.0.2-0.20160129220114-45c278ab3607/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420 h1:Yu3681ykYHDfLoI6XVjL4JWmkE+3TX9yfIWwRCh1kFM=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v0.0.0-20170515205857-f03dbe35d449/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.0-rc5.0.20170515205857-f03dbe35d449 h1:tXY0/ibnbYVy/rgvjfCw/6NyofuQjCYfqdsxtAemiv0=
github.com/opencontainers/image-spec v1.0.0-rc5.0.20170515205857-f03dbe35d449/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20161109192122-51371867a01c/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc3.0.20170425215914-b6b70e534517 h1:wIKCRF3y2i8wRemmewC/Gg0k1ilDqLt/YdPb54oY8fg=
github.com/opencontainers/runc v1.0.0-rc3.0.20170425215914-b6b70e534517/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5 h1:82Tnq9OJpn+h5xgGpss5/mOv3KXdjtkdorFSOUusjM8=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5/go.mod h1:uVHyebswE1cCXr2A73cRM2frx5ld1RJUCJkFNZ90ZiI=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/oracle/oci-go-sdk v7.0.0+incompatible h1:oj5ESjXwwkFRdhZSnPlShvLWYdt/IZ65RQxveYM3maA=
github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c=
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
github.com/rancher/go-rancher v0.1.1-0.20171004213057-52e2f4895340 h1:IqDxW4t+F+mVyKGH97nZekXCMfIhrtLyyBovbYxkgMg=
github.com/rancher/go-rancher v0.1.1-0.20171004213057-52e2f4895340/go.mod h1:7oQvGNiJsGvrUgB+7AH8bmdzuR0uhULfwKb43Ht0hUk=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/sacloud/libsacloud v1.26.1 h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek=
github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ=
github.com/samuel/go-zookeeper v0.0.0-20161028232340-1d7be4effb13 h1:4AQBn5RJY4WH8t8TLEMZUsWeXHAUcoao42TCAfpEJJE=
github.com/samuel/go-zookeeper v0.0.0-20161028232340-1d7be4effb13/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shopspring/decimal v1.1.1-0.20191009025716-f1972eb1d1f5 h1:15xhmIPjPfNkWwAiC2aC9XTfrDYp9RZLiBBAgSfmmIg=
github.com/shopspring/decimal v1.1.1-0.20191009025716-f1972eb1d1f5/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spf13/pflag v0.0.0-20160427162146-cb88ea77998c h1:nKSqf1F72lP/EWecUpeCXINWfP8aAa5TXORk21x0xw8=
github.com/spf13/pflag v0.0.0-20160427162146-cb88ea77998c/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13 h1:WYRIgR83bWdH2zjqXalfLuQYtgBG1KKxDRxinx2ygMI=
github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
github.com/thoas/stats v0.0.0-20190104110215-4975baf6a358 h1:P8DnSvvEhpRce5GOLZEEUXjGloUBSA/2tNq43S1PY9k=
github.com/thoas/stats v0.0.0-20190104110215-4975baf6a358/go.mod h1:GkZsNBOco11YY68OnXUARbSl26IOXXAeYf6ZKmSZR2M=
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8=
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
github.com/tinylib/msgp v1.0.2 h1:DfdQrzQa7Yh2es9SuLkixqxuXS2SxsdYn0KbdrOGWD8=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/traefik/traefik v1.7.27/go.mod h1:hg3a++nufqJiwlthsJrhu6nTWODJO4ZwCZBQcpFhrbA=
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f h1:clyOmELPZd2LuFEyuo1mP6RXpbAW75PwD+RfDj4kBm0=
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/tv42/zbase32 v0.0.0-20150911225513-03389da7e0bf h1:YHk42qEP5q7T6kZMpqUW490XiEVPkJRfJw9uRncGXi4=
github.com/tv42/zbase32 v0.0.0-20150911225513-03389da7e0bf/go.mod h1:tHlrkM198S068ZqfrO6S8HsoJq2bF3ETfTL+kt4tInY=
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/uber/jaeger-client-go v2.15.0+incompatible h1:NP3qsSqNxh8VYr956ur1N/1C1PjvOJnJykCzcD5QHbk=
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.1 h1:gmervu+jDMvXTbcHQ0pd2wee85nEoE0BsVyEuzkfK8w=
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/unrolled/render v0.0.0-20170109143244-50716a0a8537 h1:+qjuebkLZyWmMxMBoafNS1Ey6GeUoRGdKx7Y38mDDhE=
github.com/unrolled/render v0.0.0-20170109143244-50716a0a8537/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg=
github.com/unrolled/secure v1.0.5 h1:KRGJ8DQC3jKpERjBKF3H6b3HcAsM/SRTVwfNJnWs25E=
github.com/unrolled/secure v1.0.5/go.mod h1:R6rugAuzh4TQpbFAq69oqZggyBQxFRFQIewtz5z7Jsc=
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
github.com/urfave/negroni v0.2.1-0.20170426175938-490e6a555d47 h1:a3kHyPExptH02+s1Zh0pKxqWB8vu4/HoA4p2vP5JmO8=
github.com/urfave/negroni v0.2.1-0.20170426175938-490e6a555d47/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/vdemeester/shakers v0.1.0 h1:K+n9sSyUCg2ywmZkv+3c7vsYZfivcfKhMh8kRxCrONM=
github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ=
github.com/vulcand/oxy v1.2.0 h1:Y2Wt1EgQddA/qMnp1+YXjehPsyw2Gy8CAfavkFF+fQk=
github.com/vulcand/oxy v1.2.0/go.mod h1:nGeNTWfyYQj3ghi3W8ok7vLSkw7Gkvr0x+G/v8Wk7vM=
github.com/vulcand/predicate v1.1.0 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg=
github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg=
github.com/vultr/govultr v0.1.4 h1:UnNMixYFVO0p80itc8PcweoVENyo1PasfvwKhoasR9U=
github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277 h1:d9qaMM+ODpCq+9We41//fu/sHsTnXcrqd1en3x+GKy4=
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777 h1:wejkGHRTr38uaKRqECZlsCsJ1/TGxIyFbH32x5zUdu4=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/DataDog/dd-trace-go.v1 v1.13.0 h1:8e4PNOH1Iq9ZwaY/IUjMIpzpsCweNNakKTiDsWc3ZJE=
gopkg.in/DataDog/dd-trace-go.v1 v1.13.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
gopkg.in/inf.v0 v0.9.0 h1:3zYtXIO92bvsdS3ggAdA8Gb4Azj0YU+TVY1uGYNFA8o=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc h1:GAcf+t0o8gdJAdSFYdE9wChu4bIyguMVqz0RHiFL5VY=
gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw=
gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc=
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20171214033149-af4bc157c3a2 h1:uT/np6AJPY4q10W6Jfae7vfqCeQ/Yx2knebTqkjWU8Y=
k8s.io/api v0.0.0-20171214033149-af4bc157c3a2/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
k8s.io/apimachinery v0.0.0-20171207040834-180eddb345a5 h1:ytrAODqD/wgvfJIzNUgaZmH/uZouVQe18p6Vru2HaIg=
k8s.io/apimachinery v0.0.0-20171207040834-180eddb345a5/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
k8s.io/client-go v6.0.0+incompatible h1:QVR0YsL5jUAs8IB2sHb7IANUK6FYv6CpNLpSPke7R2Q=
k8s.io/client-go v6.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
k8s.io/kube-openapi v0.0.0-20180201014056-275e2ce91dec h1:hexvez3LDSbYXCDqq1uHv+SW4FWn78TmVpVmvs7M5yY=
k8s.io/kube-openapi v0.0.0-20180201014056-275e2ce91dec/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -22,7 +22,7 @@ import (
"os"
"strings"
"github.com/containous/traefik/log"
"github.com/traefik/traefik/log"
"golang.org/x/net/http/httpguts"
"golang.org/x/net/http2"
@@ -57,20 +57,20 @@ func (s Server) Serve(l net.Listener) error {
if http2VerboseLogs {
log.Debugf("Attempting h2c with prior knowledge.")
}
conn, err := initH2CWithPriorKnowledge(w)
conn, err := initH2CWithPriorKnowledge(w, s.closeHijackedConnQuietly)
if err != nil {
if http2VerboseLogs {
log.Debugf("Error h2c with prior knowledge: %v", err)
}
return
}
defer conn.Close()
defer s.closeHijackedConnQuietly(conn)
h2cSrv := &http2.Server{}
h2cSrv.ServeConn(conn, &http2.ServeConnOpts{Handler: originalHandler})
return
}
if conn, err := h2cUpgrade(w, r); err == nil {
defer conn.Close()
if conn, err := h2cUpgrade(w, r, s.closeHijackedConnQuietly); err == nil {
defer s.closeHijackedConnQuietly(conn)
h2cSrv := &http2.Server{}
h2cSrv.ServeConn(conn, &http2.ServeConnOpts{Handler: originalHandler})
return
@@ -80,12 +80,24 @@ func (s Server) Serve(l net.Listener) error {
return s.Server.Serve(l)
}
func (s Server) closeHijackedConnQuietly(conn net.Conn) {
connStateKey := conn
if rwConn, ok := conn.(*rwConn); ok {
connStateKey = rwConn.Conn
}
s.ConnState(connStateKey, http.StateClosed)
if err := conn.Close(); err != nil {
log.Debugf("Error closing hijacked connection: %v", err)
}
}
// initH2CWithPriorKnowledge implements creating a h2c connection with prior
// knowledge (Section 3.4) and creates a net.Conn suitable for http2.ServeConn.
// All we have to do is look for the client preface that is suppose to be part
// of the body, and reforward the client preface on the net.Conn this function
// creates.
func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) {
func initH2CWithPriorKnowledge(w http.ResponseWriter, onFailureAfterHijack func(conn net.Conn)) (net.Conn, error) {
hijacker, ok := w.(http.Hijacker)
if !ok {
return nil, errors.New("hijack not supported")
@@ -100,6 +112,7 @@ func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) {
buf := make([]byte, len(expectedBody))
n, err := io.ReadFull(rw, buf)
if err != nil {
onFailureAfterHijack(conn)
return nil, fmt.Errorf("fail to read body: %v", err)
}
@@ -112,7 +125,7 @@ func initH2CWithPriorKnowledge(w http.ResponseWriter) (net.Conn, error) {
return c, nil
}
conn.Close()
onFailureAfterHijack(conn)
if http2VerboseLogs {
log.Printf(
"Missing the request body portion of the client preface. Wanted: %v Got: %v",
@@ -139,7 +152,7 @@ func drainClientPreface(r io.Reader) error {
}
// h2cUpgrade establishes a h2c connection using the HTTP/1 upgrade (Section 3.2).
func h2cUpgrade(w http.ResponseWriter, r *http.Request) (net.Conn, error) {
func h2cUpgrade(w http.ResponseWriter, r *http.Request, onFailureAfterHijack func(conn net.Conn)) (net.Conn, error) {
if !isH2CUpgrade(r.Header) {
return nil, errors.New("non-conforming h2c headers")
}
@@ -167,6 +180,7 @@ func h2cUpgrade(w http.ResponseWriter, r *http.Request) (net.Conn, error) {
// A conforming client will now send an H2 client preface which need to drain
// since we already sent this.
if err := drainClientPreface(rw); err != nil {
onFailureAfterHijack(conn)
return nil, err
}

View File

@@ -10,9 +10,9 @@ import (
"sync"
"time"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/go-kit/kit/metrics"
"github.com/traefik/traefik/log"
"github.com/traefik/traefik/safe"
"github.com/vulcand/oxy/roundrobin"
)
@@ -49,17 +49,24 @@ func (opt Options) String() string {
return fmt.Sprintf("[Hostname: %s Headers: %v Path: %s Port: %d Interval: %s]", opt.Hostname, opt.Headers, opt.Path, opt.Port, opt.Interval)
}
type backendURL struct {
url *url.URL
weight int
}
// BackendConfig HealthCheck configuration for a backend
type BackendConfig struct {
Options
name string
disabledURLs []*url.URL
disabledURLs []backendURL
requestTimeout time.Duration
}
func (b *BackendConfig) newRequest(serverURL *url.URL) (*http.Request, error) {
u := &url.URL{}
*u = *serverURL
u, err := serverURL.Parse(b.Path)
if err != nil {
return nil, err
}
if len(b.Scheme) > 0 {
u.Scheme = b.Scheme
@@ -69,8 +76,6 @@ func (b *BackendConfig) newRequest(serverURL *url.URL) (*http.Request, error) {
u.Host = net.JoinHostPort(u.Hostname(), strconv.Itoa(b.Port))
}
u.Path += b.Path
return http.NewRequest(http.MethodGet, u.String(), http.NoBody)
}
@@ -129,18 +134,18 @@ func (hc *HealthCheck) execute(ctx context.Context, backend *BackendConfig) {
func (hc *HealthCheck) checkBackend(backend *BackendConfig) {
enabledURLs := backend.LB.Servers()
var newDisabledURLs []*url.URL
for _, url := range backend.disabledURLs {
var newDisabledURLs []backendURL
for _, backendurl := range backend.disabledURLs {
serverUpMetricValue := float64(0)
if err := checkHealth(url, backend); err == nil {
log.Warnf("Health check up: Returning to server list. Backend: %q URL: %q", backend.name, url.String())
backend.LB.UpsertServer(url, roundrobin.Weight(1))
if err := checkHealth(backendurl.url, backend); err == nil {
log.Warnf("Health check up: Returning to server list. Backend: %q URL: %q Weight: %d", backend.name, backendurl.url.String(), backendurl.weight)
backend.LB.UpsertServer(backendurl.url, roundrobin.Weight(backendurl.weight))
serverUpMetricValue = 1
} else {
log.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, url.String(), err)
newDisabledURLs = append(newDisabledURLs, url)
log.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, backendurl.url.String(), err)
newDisabledURLs = append(newDisabledURLs, backendurl)
}
labelValues := []string{"backend", backend.name, "url", url.String()}
labelValues := []string{"backend", backend.name, "url", backendurl.url.String()}
hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue)
}
backend.disabledURLs = newDisabledURLs
@@ -148,9 +153,18 @@ func (hc *HealthCheck) checkBackend(backend *BackendConfig) {
for _, url := range enabledURLs {
serverUpMetricValue := float64(1)
if err := checkHealth(url, backend); err != nil {
log.Warnf("Health check failed: Remove from server list. Backend: %q URL: %q Reason: %s", backend.name, url.String(), err)
weight := 1
rr, ok := backend.LB.(*roundrobin.RoundRobin)
if ok {
var gotWeight bool
weight, gotWeight = rr.ServerWeight(url)
if !gotWeight {
weight = 1
}
}
log.Warnf("Health check failed: Remove from server list. Backend: %q URL: %q Weight: %d Reason: %s", backend.name, url.String(), weight, err)
backend.LB.RemoveServer(url)
backend.disabledURLs = append(backend.disabledURLs, url)
backend.disabledURLs = append(backend.disabledURLs, backendURL{url, weight})
serverUpMetricValue = 0
}
labelValues := []string{"backend", backend.name, "url", url.String()}

View File

@@ -9,9 +9,9 @@ import (
"testing"
"time"
"github.com/containous/traefik/testhelpers"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/traefik/traefik/testhelpers"
"github.com/vulcand/oxy/roundrobin"
)
@@ -112,7 +112,7 @@ func TestSetBackendsConfiguration(t *testing.T) {
if test.startHealthy {
lb.servers = append(lb.servers, serverURL)
} else {
backend.disabledURLs = append(backend.disabledURLs, serverURL)
backend.disabledURLs = append(backend.disabledURLs, backendURL{serverURL, 1})
}
collectingMetrics := testhelpers.NewCollectingHealthCheckMetrics()
@@ -150,11 +150,16 @@ func TestSetBackendsConfiguration(t *testing.T) {
}
func TestNewRequest(t *testing.T) {
type expected struct {
err bool
value string
}
testCases := []struct {
desc string
serverURL string
options Options
expected string
expected expected
}{
{
desc: "no port override",
@@ -163,7 +168,10 @@ func TestNewRequest(t *testing.T) {
Path: "/test",
Port: 0,
},
expected: "http://backend1:80/test",
expected: expected{
err: false,
value: "http://backend1:80/test",
},
},
{
desc: "port override",
@@ -172,7 +180,10 @@ func TestNewRequest(t *testing.T) {
Path: "/test",
Port: 8080,
},
expected: "http://backend2:8080/test",
expected: expected{
err: false,
value: "http://backend2:8080/test",
},
},
{
desc: "no port override with no port in server URL",
@@ -181,7 +192,10 @@ func TestNewRequest(t *testing.T) {
Path: "/health",
Port: 0,
},
expected: "http://backend1/health",
expected: expected{
err: false,
value: "http://backend1/health",
},
},
{
desc: "port override with no port in server URL",
@@ -190,7 +204,10 @@ func TestNewRequest(t *testing.T) {
Path: "/health",
Port: 8080,
},
expected: "http://backend2:8080/health",
expected: expected{
err: false,
value: "http://backend2:8080/health",
},
},
{
desc: "scheme override",
@@ -200,7 +217,46 @@ func TestNewRequest(t *testing.T) {
Path: "/test",
Port: 0,
},
expected: "http://backend1:80/test",
expected: expected{
err: false,
value: "http://backend1:80/test",
},
},
{
desc: "path with param",
serverURL: "http://backend1:80",
options: Options{
Path: "/health?powpow=do",
Port: 0,
},
expected: expected{
err: false,
value: "http://backend1:80/health?powpow=do",
},
},
{
desc: "path with params",
serverURL: "http://backend1:80",
options: Options{
Path: "/health?powpow=do&do=powpow",
Port: 0,
},
expected: expected{
err: false,
value: "http://backend1:80/health?powpow=do&do=powpow",
},
},
{
desc: "path with invalid path",
serverURL: "http://backend1:80",
options: Options{
Path: ":",
Port: 0,
},
expected: expected{
err: true,
value: "",
},
},
}
@@ -211,13 +267,18 @@ func TestNewRequest(t *testing.T) {
backend := NewBackendConfig(test.options, "backendName")
u, err := url.Parse(test.serverURL)
require.NoError(t, err)
u := testhelpers.MustParseURL(test.serverURL)
req, err := backend.newRequest(u)
require.NoError(t, err, "failed to create new backend request")
assert.Equal(t, test.expected, req.URL.String())
if test.expected.err {
require.Error(t, err)
assert.Nil(t, nil)
} else {
require.NoError(t, err, "failed to create new backend request")
require.NotNil(t, req)
assert.Equal(t, test.expected.value, req.URL.String())
}
})
}
}

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