mirror of
https://github.com/containous/traefik.git
synced 2025-09-08 13:44:22 +03:00
Compare commits
490 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
3e61d1f233 | ||
|
04c07227f2 | ||
|
2e8d99c5b8 | ||
|
c07301473b | ||
|
b1ba42410b | ||
|
b80f89e3db | ||
|
5c853766e8 | ||
|
d2435cf43b | ||
|
556f7608db | ||
|
a4df4b028e | ||
|
63683d35fc | ||
|
495344591f | ||
|
4e508499da | ||
|
e4a3df3516 | ||
|
3506cbd5e9 | ||
|
ab13019bde | ||
|
ddc663eac0 | ||
|
fc7002fbab | ||
|
c5b4e589ff | ||
|
c9bbfa1272 | ||
|
8ca0d804d8 | ||
|
54e5a3607e | ||
|
2477e18c87 | ||
|
ef08e8b8a0 | ||
|
f59bf16e82 | ||
|
118c31eb8d | ||
|
476f16f0aa | ||
|
b40d35b779 | ||
|
8e016cf672 | ||
|
7e482e9f8b | ||
|
6445befe87 | ||
|
79af433381 | ||
|
c0f1e74bed | ||
|
9df89e66e3 | ||
|
660375d6e4 | ||
|
230c2e5cc2 | ||
|
3e60863e2d | ||
|
4592626bbb | ||
|
b980c87eff | ||
|
0f7c322623 | ||
|
93b3d601d5 | ||
|
56329e89bb | ||
|
5c8b8149eb | ||
|
ddf53494f0 | ||
|
cd1f03d4f4 | ||
|
8474a61f21 | ||
|
4ad0ab5433 | ||
|
66d151df77 | ||
|
2045b250fd | ||
|
1dbee90d34 | ||
|
eb7a6d925b | ||
|
3678bd5a93 | ||
|
2d1a973ee5 | ||
|
322f7b2ad4 | ||
|
41aa2672cd | ||
|
f3090a452a | ||
|
52790d3c37 | ||
|
3677252e17 | ||
|
235d1d655d | ||
|
69c0f38305 | ||
|
0399d0c4d6 | ||
|
3e3b7238e0 | ||
|
532b5865de | ||
|
54b94f29e1 | ||
|
b67a7215f6 | ||
|
e424cc7608 | ||
|
229008e76a | ||
|
584f4bc596 | ||
|
1502d20def | ||
|
eecc2f4dd7 | ||
|
6fc110a71a | ||
|
ca6b46533a | ||
|
a1fe29347a | ||
|
6e5dd35ee3 | ||
|
0d5d14d41a | ||
|
3a42e457cf | ||
|
5b05c990b0 | ||
|
9df0a6208b | ||
|
3214904cc7 | ||
|
ec775a016a | ||
|
a2ca235fee | ||
|
3942962ef5 | ||
|
675655d437 | ||
|
dafb14ff37 | ||
|
fc52d1cfba | ||
|
fdf2a68a11 | ||
|
3908ef611a | ||
|
e63db782c1 | ||
|
a6c6127e33 | ||
|
207d0bec78 | ||
|
1443c8d4c6 | ||
|
a136c46148 | ||
|
bbbc18fd84 | ||
|
2c7f6e4def | ||
|
dcd0cda0c6 | ||
|
ff16925f63 | ||
|
0b7aaa3643 | ||
|
44a244b1cb | ||
|
1dc6f39b55 | ||
|
45f52ca29c | ||
|
fae2d93525 | ||
|
25b74ce1f3 | ||
|
4957e498af | ||
|
54ca1abd2b | ||
|
8f2951b275 | ||
|
720bef97e6 | ||
|
c42f1b7a50 | ||
|
0186c31d59 | ||
|
58bf1a2ca5 | ||
|
4a31544024 | ||
|
cb6ec507e2 | ||
|
1ef93fead7 | ||
|
285ded6e49 | ||
|
6e4f5821dc | ||
|
a3df5b9a94 | ||
|
04f0ebf776 | ||
|
0e97a3becd | ||
|
77a0cef9ce | ||
|
143e9b6f9c | ||
|
06dcf8d8aa | ||
|
c315b4e064 | ||
|
73ca7ad0c1 | ||
|
d7f517fbf5 | ||
|
b10cb84f33 | ||
|
a55f0cabdd | ||
|
d73c7ccf50 | ||
|
2b35397169 | ||
|
416c367778 | ||
|
a20e90aa17 | ||
|
d698eba1e7 | ||
|
fe8e9414cf | ||
|
ed216bea4d | ||
|
3350b56057 | ||
|
4d71f682b3 | ||
|
607cda779d | ||
|
b61de07ca0 | ||
|
295ed76a1a | ||
|
7669f41e8e | ||
|
8da051789f | ||
|
30e0778ed2 | ||
|
7b1a256546 | ||
|
cc4879fb76 | ||
|
7c54a45950 | ||
|
73513f8371 | ||
|
dabf69abc7 | ||
|
8d3d5c068c | ||
|
cb1d0441e9 | ||
|
8d827f98da | ||
|
e5e46bf4ed | ||
|
9f32292473 | ||
|
7affeae480 | ||
|
b0f7b71453 | ||
|
c0c540dc09 | ||
|
7694ff1761 | ||
|
0d902671e5 | ||
|
fb90a7889a | ||
|
48c73d6a34 | ||
|
12e462f383 | ||
|
b7fe55b6be | ||
|
a1270d6cc7 | ||
|
f874c389bd | ||
|
8c5846c478 | ||
|
dce807a329 | ||
|
7928e6d0cd | ||
|
a98b726263 | ||
|
42ec4e4e98 | ||
|
635e3fb9a8 | ||
|
5f0b6fde92 | ||
|
04257afab7 | ||
|
b673969a0f | ||
|
c52c40f061 | ||
|
abdb5cc6cb | ||
|
4a6817c64b | ||
|
328611c619 | ||
|
f12c27aa7c | ||
|
e22c62baba | ||
|
6b1158235e | ||
|
efcaf64a43 | ||
|
f120301bc8 | ||
|
4da63c9237 | ||
|
97294df84f | ||
|
de42fc10b5 | ||
|
e5c6b0d4ea | ||
|
7c7ca7ef2b | ||
|
a813d32c53 | ||
|
2f18e20cb0 | ||
|
2ce2d63bda | ||
|
367e797d5f | ||
|
4fcf7bf2de | ||
|
e1d51b51f2 | ||
|
40b4032ea0 | ||
|
756aa82aa9 | ||
|
fe5a4a26f8 | ||
|
2171cb7f3d | ||
|
f55a09862e | ||
|
d0b21efd36 | ||
|
daf4258472 | ||
|
619bc95b2b | ||
|
76c2fa6d9a | ||
|
77bf3ac6ce | ||
|
0d7761f097 | ||
|
6c08d0b20b | ||
|
148400ae0a | ||
|
ac1657d86e | ||
|
332c314d53 | ||
|
5c8d386881 | ||
|
6f749c6414 | ||
|
a6b6e1d101 | ||
|
aa68cc2e63 | ||
|
5560ab28f2 | ||
|
f624449ccb | ||
|
69de5bb828 | ||
|
b54412e82e | ||
|
dd19fc3f3e | ||
|
dd436a689f | ||
|
ee06778cc2 | ||
|
b0c7fad81b | ||
|
0c28630948 | ||
|
198320be8a | ||
|
da8451c637 | ||
|
f54b8d8847 | ||
|
f4fb758629 | ||
|
b40fa61783 | ||
|
94cd9e5337 | ||
|
15c9fc4051 | ||
|
2b28607a4e | ||
|
683d5d5a48 | ||
|
4f92ef5fa9 | ||
|
44221fba49 | ||
|
63d7ed74f1 | ||
|
9012f2d6b1 | ||
|
09224e4b04 | ||
|
668e6fd610 | ||
|
62c3025a76 | ||
|
6e92c20edb | ||
|
60de577a5f | ||
|
af58faafae | ||
|
5adf74e6ce | ||
|
f4007a342c | ||
|
672234aaea | ||
|
f19eebd3cc | ||
|
37fb5298a0 | ||
|
4280af4844 | ||
|
d67e06037e | ||
|
4ce90a7eb4 | ||
|
4408c634b0 | ||
|
df351511de | ||
|
3b85dc9618 | ||
|
e511cfe2e4 | ||
|
d0f8c1834d | ||
|
d02bb28920 | ||
|
99861ac808 | ||
|
13ebd2c4e4 | ||
|
16c4807162 | ||
|
11aa4a6be0 | ||
|
cf7f0f878a | ||
|
09c07f45ee | ||
|
b5d205b78c | ||
|
ad6bf936d5 | ||
|
a6040c623b | ||
|
93a7af270f | ||
|
082fb166a2 | ||
|
dccc075f2c | ||
|
5fdec48854 | ||
|
fb51ebcba6 | ||
|
67e17def56 | ||
|
353bd3d06f | ||
|
a7495f711b | ||
|
e9d0a16a3b | ||
|
5072735866 | ||
|
1746ed6e1c | ||
|
664cd940c5 | ||
|
389536aff0 | ||
|
f6c6c2b2c0 | ||
|
18d90ecd96 | ||
|
70fdfeb926 | ||
|
8c271cf40c | ||
|
665aeb34b2 | ||
|
98f304f8b0 | ||
|
7a5d2a3bd9 | ||
|
f4d62d3342 | ||
|
54df7b0a3c | ||
|
9795a7c4a9 | ||
|
1557fda588 | ||
|
1e7f34c271 | ||
|
d71e8ab7c9 | ||
|
3b4c8ba439 | ||
|
336dd1d5ba | ||
|
a474e196ea | ||
|
101aefbfe8 | ||
|
e04ebaa364 | ||
|
bb4de11c51 | ||
|
a20a5f1a44 | ||
|
aab7043d45 | ||
|
ee6d28b25e | ||
|
ef504f3eba | ||
|
86407871e6 | ||
|
76bb2ef60c | ||
|
beec65938e | ||
|
1c764052f7 | ||
|
d501c0786f | ||
|
322c329c6f | ||
|
7c430e5c9d | ||
|
94b2b6393f | ||
|
4a1d20e8a3 | ||
|
8762e5160d | ||
|
c33348e80c | ||
|
0c90f6afa2 | ||
|
115d42e0f0 | ||
|
6e43ab5897 | ||
|
8988c8f9af | ||
|
aa21351d0d | ||
|
97109db82b | ||
|
8bb625adb7 | ||
|
ea2d65f8bb | ||
|
1cf09d91bb | ||
|
cf2b97b656 | ||
|
2e8cbd81b4 | ||
|
b498c7bcbb | ||
|
e78843bdca | ||
|
2eaf3136f9 | ||
|
6b6ab9fe6d | ||
|
f35b9a4509 | ||
|
349ce004f8 | ||
|
1b63c95c4e | ||
|
c80d53e7e5 | ||
|
eb2028e0fa | ||
|
03689251c5 | ||
|
85c08312be | ||
|
16288d171c | ||
|
87044c54f4 | ||
|
a4e8d3cb36 | ||
|
dce6356d75 | ||
|
c24e74efe3 | ||
|
60e247862a | ||
|
c796cd2250 | ||
|
c296a4a967 | ||
|
24192a3797 | ||
|
f84d947115 | ||
|
9544dece07 | ||
|
6c4d7fd377 | ||
|
8d467ddd61 | ||
|
db28ee1ff7 | ||
|
e378cb410c | ||
|
144eee7fbf | ||
|
72e702a15a | ||
|
6b7be462b8 | ||
|
4329d393e6 | ||
|
4f52691f71 | ||
|
c132d71684 | ||
|
8410f61c73 | ||
|
cac76a182e | ||
|
5b0e93552c | ||
|
5eebd04d43 | ||
|
6f4aefffe7 | ||
|
377c219fd9 | ||
|
da3d814c8b | ||
|
4461ecfed1 | ||
|
bd676922c3 | ||
|
49356cadd4 | ||
|
c02f222005 | ||
|
d3977ce40e | ||
|
7283d7eb2f | ||
|
48252d284e | ||
|
807dc46ad0 | ||
|
0837ec9b70 | ||
|
b380522df8 | ||
|
c127d34d32 | ||
|
bc0b97d5d8 | ||
|
431abe79f3 | ||
|
125470f110 | ||
|
4f669bdd66 | ||
|
8930236396 | ||
|
b3c9a50ead | ||
|
4d0aee67be | ||
|
b501c6d5bf | ||
|
7dcee38b21 | ||
|
903c63ac13 | ||
|
a98c9f99d1 | ||
|
7f085df240 | ||
|
b5ae141fb6 | ||
|
7eb866ffee | ||
|
61e59d74e0 | ||
|
5f50d2e230 | ||
|
3f1484480e | ||
|
2d3fc613ec | ||
|
e2982185d6 | ||
|
bdf4c6723f | ||
|
1d4f10bead | ||
|
aac3e2d4fb | ||
|
87dd6badac | ||
|
1b6c7af3eb | ||
|
5c091a1871 | ||
|
fb3839e096 | ||
|
eef3ca0295 | ||
|
c9dc0226fd | ||
|
1a7a3a4233 | ||
|
d2e458f673 | ||
|
e0f265db15 | ||
|
39a3cefc21 | ||
|
89db08eb93 | ||
|
f40cf2cd8e | ||
|
50bb69b796 | ||
|
a7d7c2b98b | ||
|
8dfc0d9dda | ||
|
0e6dce7093 | ||
|
ddbf4470a1 | ||
|
829649e905 | ||
|
bc063ad773 | ||
|
ef38810425 | ||
|
5ccca8d708 | ||
|
89919dbe36 | ||
|
ecd51a1428 | ||
|
4cb9eec257 | ||
|
78097b96c9 | ||
|
2af8589afd | ||
|
cf1ace3a73 | ||
|
efcc9d51d4 | ||
|
9b9f4be6a4 | ||
|
a87c104172 | ||
|
028683666d | ||
|
b2c59be8de | ||
|
2685e06528 | ||
|
a99673122e | ||
|
ba49012447 | ||
|
fe8b090911 | ||
|
c4a38de007 | ||
|
407eda0ba0 | ||
|
5b1dc0bfbd | ||
|
772b260b37 | ||
|
bd75eddc8e | ||
|
00db3a0922 | ||
|
2bcc1b7fb4 | ||
|
433c848c8d | ||
|
abdb3b9475 | ||
|
9761161163 | ||
|
e5104021b1 | ||
|
9ef4f47ba0 | ||
|
3bbc88f89a | ||
|
bfa61c8f67 | ||
|
3bdeb75cc2 | ||
|
ca9eaf383a | ||
|
42a8d84a1f | ||
|
3fd330c2fb | ||
|
8f340afca1 | ||
|
e28d9426b9 | ||
|
b3078b75cd | ||
|
424b97994e | ||
|
f30a52c2dc | ||
|
1db22f4a1b | ||
|
424e2a9439 | ||
|
2ee2e29262 | ||
|
7afd2dbd20 | ||
|
cdb2446e32 | ||
|
ac8c9215cd | ||
|
dfca01e469 | ||
|
ca1d980746 | ||
|
587d3f9012 | ||
|
e30ab07439 | ||
|
e6e026f420 | ||
|
2036518813 | ||
|
7536f5e83c | ||
|
229402594f | ||
|
97873ddb5d | ||
|
dbf303d5d6 | ||
|
7346b3e326 | ||
|
93cf947e2a | ||
|
c37ad5c8bf | ||
|
5a3e325742 | ||
|
c5ec12cd56 | ||
|
3410541a2f | ||
|
80a68de91b | ||
|
1f39083555 | ||
|
5f8fb6c226 | ||
|
d66dd01438 | ||
|
6d3bad1ae0 | ||
|
14bdc0e57a | ||
|
7be2db6e86 | ||
|
d0ed814669 | ||
|
4e9166759d | ||
|
2471f893e7 | ||
|
56e0580aa5 | ||
|
e4e2a188c5 | ||
|
a20a6636b4 | ||
|
88ebac942e | ||
|
06df6017df | ||
|
15b5433f1a | ||
|
890d02638b | ||
|
11f04a453e | ||
|
7baa752a9d |
@@ -1,3 +1,5 @@
|
|||||||
dist/
|
dist/
|
||||||
!dist/traefik
|
!dist/traefik
|
||||||
site/
|
site/
|
||||||
|
vendor/
|
||||||
|
.idea/
|
||||||
|
24
.github/CODEOWNERS
vendored
24
.github/CODEOWNERS
vendored
@@ -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
|
|
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -17,7 +17,7 @@ Bug
|
|||||||
<!--
|
<!--
|
||||||
|
|
||||||
The configurations between 1.X and 2.X are NOT compatible.
|
The configurations between 1.X and 2.X are NOT compatible.
|
||||||
Please have a look here https://docs.traefik.io/v2.0/getting-started/configuration-overview/.
|
Please have a look here https://doc.traefik.io/traefik/getting-started/configuration-overview/.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -22,7 +22,7 @@ Bug
|
|||||||
<!--
|
<!--
|
||||||
|
|
||||||
The configurations between 1.X and 2.X are NOT compatible.
|
The configurations between 1.X and 2.X are NOT compatible.
|
||||||
Please have a look here https://docs.traefik.io/v2.0/getting-started/configuration-overview/.
|
Please have a look here https://doc.traefik.io/traefik/getting-started/configuration-overview/.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -3,17 +3,17 @@ PLEASE READ THIS MESSAGE.
|
|||||||
|
|
||||||
Documentation fixes or enhancements:
|
Documentation fixes or enhancements:
|
||||||
- for Traefik v1: use branch v1.7
|
- for Traefik v1: use branch v1.7
|
||||||
- for Traefik v2: use branch v2.0
|
- for Traefik v2: use branch v2.3
|
||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
- for Traefik v1: use branch v1.7
|
- for Traefik v1: use branch v1.7
|
||||||
- for Traefik v2: use branch v2.0
|
- for Traefik v2: use branch v2.3
|
||||||
|
|
||||||
Enhancements:
|
Enhancements:
|
||||||
- for Traefik v1: we only accept bug fixes
|
- for Traefik v1: we only accept bug fixes
|
||||||
- for Traefik v2: use branch master
|
- for Traefik v2: use branch master
|
||||||
|
|
||||||
HOW TO WRITE A GOOD PULL REQUEST? https://docs.traefik.io/contributing/submitting-pull-requests/
|
HOW TO WRITE A GOOD PULL REQUEST? https://doc.traefik.io/traefik/contributing/submitting-pull-requests/
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,3 +16,5 @@
|
|||||||
*.exe
|
*.exe
|
||||||
cover.out
|
cover.out
|
||||||
vendor/
|
vendor/
|
||||||
|
plugins-storage/
|
||||||
|
traefik_changelog.md
|
||||||
|
@@ -47,7 +47,14 @@
|
|||||||
"gocognit",
|
"gocognit",
|
||||||
"bodyclose", # Too many false-positive and panics.
|
"bodyclose", # Too many false-positive and panics.
|
||||||
"wsl", # Too strict
|
"wsl", # Too strict
|
||||||
|
"gomnd", # Too strict
|
||||||
"stylecheck", # skip because report issues related to some generated files.
|
"stylecheck", # skip because report issues related to some generated files.
|
||||||
|
"testpackage", # Too strict
|
||||||
|
"goerr113", # Too strict
|
||||||
|
"nestif", # Too many false-positive.
|
||||||
|
"noctx", # Too strict
|
||||||
|
"exhaustive", # Too strict
|
||||||
|
"nlreturn", # Too strict
|
||||||
]
|
]
|
||||||
|
|
||||||
[issues]
|
[issues]
|
||||||
@@ -61,7 +68,7 @@
|
|||||||
]
|
]
|
||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "(.+)_test.go"
|
path = "(.+)_test.go"
|
||||||
linters = ["goconst", "funlen"]
|
linters = ["goconst", "funlen", "godot"]
|
||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "integration/.+_test.go"
|
path = "integration/.+_test.go"
|
||||||
text = "Error return value of `cmd\\.Process\\.Kill` is not checked"
|
text = "Error return value of `cmd\\.Process\\.Kill` is not checked"
|
||||||
@@ -92,6 +99,18 @@
|
|||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "cmd/configuration.go"
|
path = "cmd/configuration.go"
|
||||||
text = "string `traefik` has (\\d) occurrences, make it a constant"
|
text = "string `traefik` has (\\d) occurrences, make it a constant"
|
||||||
|
[[issues.exclude-rules]]
|
||||||
|
path = "pkg/server/middleware/middlewares.go"
|
||||||
|
text = "Function 'buildConstructor' has too many statements"
|
||||||
[[issues.exclude-rules]] # FIXME must be fixed
|
[[issues.exclude-rules]] # FIXME must be fixed
|
||||||
path = "cmd/context.go"
|
path = "cmd/context.go"
|
||||||
text = "S1000: should use a simple channel send/receive instead of `select` with a single case"
|
text = "S1000: should use a simple channel send/receive instead of `select` with a single case"
|
||||||
|
[[issues.exclude-rules]]
|
||||||
|
path = "pkg/tracing/haystack/logger.go"
|
||||||
|
linters = ["goprintffuncname"]
|
||||||
|
[[issues.exclude-rules]]
|
||||||
|
path = "pkg/tracing/tracing.go"
|
||||||
|
text = "printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'"
|
||||||
|
[[issues.exclude-rules]]
|
||||||
|
path = "pkg/log/deprecated.go"
|
||||||
|
linters = ["godot"]
|
@@ -7,11 +7,11 @@ before:
|
|||||||
builds:
|
builds:
|
||||||
- binary: traefik
|
- binary: traefik
|
||||||
|
|
||||||
main: ./cmd/traefik/traefik.go
|
main: ./cmd/traefik/
|
||||||
env:
|
env:
|
||||||
- CGO_ENABLED=0
|
- CGO_ENABLED=0
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X github.com/containous/traefik/v2/pkg/version.Version={{.Version}} -X github.com/containous/traefik/v2/pkg/version.Codename={{.Env.CODENAME}} -X github.com/containous/traefik/v2/pkg/version.BuildDate={{.Date}}
|
- -s -w -X github.com/traefik/traefik/v2/pkg/version.Version={{.Version}} -X github.com/traefik/traefik/v2/pkg/version.Codename={{.Env.CODENAME}} -X github.com/traefik/traefik/v2/pkg/version.BuildDate={{.Date}}
|
||||||
|
|
||||||
goos:
|
goos:
|
||||||
- linux
|
- linux
|
||||||
@@ -34,8 +34,10 @@ builds:
|
|||||||
goarch: 386
|
goarch: 386
|
||||||
- goos: openbsd
|
- goos: openbsd
|
||||||
goarch: arm
|
goarch: arm
|
||||||
|
- goos: openbsd
|
||||||
|
goarch: arm64
|
||||||
- goos: freebsd
|
- goos: freebsd
|
||||||
goarch: arm
|
goarch: arm64
|
||||||
|
|
||||||
changelog:
|
changelog:
|
||||||
skip: true
|
skip: true
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# For personnal CI
|
# For personnal CI
|
||||||
# mv /home/runner/workspace/src/github.com/<username>/ /home/runner/workspace/src/github.com/containous/
|
# mv /home/runner/workspace/src/github.com/<username>/ /home/runner/workspace/src/github.com/traefik/
|
||||||
# cd /home/runner/workspace/src/github.com/containous/traefik/
|
# cd /home/runner/workspace/src/github.com/traefik/traefik/
|
||||||
for s in apache2 cassandra elasticsearch memcached mysql mongod postgresql sphinxsearch rethinkdb rabbitmq-server redis-server; do sudo service $s stop; done
|
for s in apache2 cassandra elasticsearch memcached mysql mongod postgresql sphinxsearch rethinkdb rabbitmq-server redis-server; do sudo service $s stop; done
|
||||||
sudo swapoff -a
|
sudo swapoff -a
|
||||||
sudo dd if=/dev/zero of=/swapfile bs=1M count=3072
|
sudo dd if=/dev/zero of=/swapfile bs=1M count=3072
|
||||||
@@ -10,7 +10,7 @@ sudo rm -rf /home/runner/.rbenv
|
|||||||
sudo rm -rf /usr/local/golang/{1.4.3,1.5.4,1.6.4,1.7.6,1.8.6,1.9.7,1.10.3,1.11}
|
sudo rm -rf /usr/local/golang/{1.4.3,1.5.4,1.6.4,1.7.6,1.8.6,1.9.7,1.10.3,1.11}
|
||||||
#export DOCKER_VERSION=18.06.3
|
#export DOCKER_VERSION=18.06.3
|
||||||
source .semaphoreci/vars
|
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 || true); 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 || true); fi
|
||||||
echo ${SHOULD_TEST}
|
echo ${SHOULD_TEST}
|
||||||
if [ -n "$TEMP_STORAGE" ]; then SHOULD_TEST=$(echo "$TEMP_STORAGE" | grep -Ev '(.md|.yaml|.yml)' || :); fi
|
if [ -n "$TEMP_STORAGE" ]; then SHOULD_TEST=$(echo "$TEMP_STORAGE" | grep -Ev '(.md|.yaml|.yml)' || :); fi
|
||||||
echo ${TEMP_STORAGE}
|
echo ${TEMP_STORAGE}
|
||||||
@@ -18,9 +18,9 @@ echo ${SHOULD_TEST}
|
|||||||
#if [ -n "$SHOULD_TEST" ]; then sudo -E apt-get -yq update; fi
|
#if [ -n "$SHOULD_TEST" ]; then sudo -E apt-get -yq update; fi
|
||||||
#if [ -n "$SHOULD_TEST" ]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install docker-ce=${DOCKER_VERSION}*; fi
|
#if [ -n "$SHOULD_TEST" ]; then sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install docker-ce=${DOCKER_VERSION}*; fi
|
||||||
if [ -n "$SHOULD_TEST" ]; then docker version; fi
|
if [ -n "$SHOULD_TEST" ]; then docker version; fi
|
||||||
export GO_VERSION=1.12
|
export GO_VERSION=1.13
|
||||||
if [ -f "./go.mod" ]; then GO_VERSION="$(grep '^go .*' go.mod | awk '{print $2}')"; export GO_VERSION; fi
|
if [ -f "./go.mod" ]; then GO_VERSION="$(grep '^go .*' go.mod | awk '{print $2}')"; export GO_VERSION; fi
|
||||||
#if [ "${GO_VERSION}" == '1.13' ]; then export GO_VERSION=1.13rc2; fi
|
#if [ "${GO_VERSION}" == '1.15' ]; then export GO_VERSION=1.15rc2; fi
|
||||||
echo "Selected Go version: ${GO_VERSION}"
|
echo "Selected Go version: ${GO_VERSION}"
|
||||||
|
|
||||||
if [ -f "./.semaphoreci/golang.sh" ]; then ./.semaphoreci/golang.sh; fi
|
if [ -f "./.semaphoreci/golang.sh" ]; then ./.semaphoreci/golang.sh; fi
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
export REPO='containous/traefik'
|
export REPO='traefik/traefik'
|
||||||
|
|
||||||
if VERSION=$(git describe --exact-match --abbrev=0 --tags);
|
if VERSION=$(git describe --exact-match --abbrev=0 --tags);
|
||||||
then
|
then
|
||||||
@@ -10,7 +10,7 @@ else
|
|||||||
export VERSION=''
|
export VERSION=''
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export CODENAME=montdor
|
export CODENAME=picodon
|
||||||
|
|
||||||
export N_MAKE_JOBS=2
|
export N_MAKE_JOBS=2
|
||||||
|
|
||||||
|
21
.travis.yml
21
.travis.yml
@@ -11,7 +11,7 @@ env:
|
|||||||
global:
|
global:
|
||||||
- REPO=$TRAVIS_REPO_SLUG
|
- REPO=$TRAVIS_REPO_SLUG
|
||||||
- VERSION=$TRAVIS_TAG
|
- VERSION=$TRAVIS_TAG
|
||||||
- CODENAME=montdor
|
- CODENAME=picodon
|
||||||
- GO111MODULE=on
|
- GO111MODULE=on
|
||||||
|
|
||||||
script:
|
script:
|
||||||
@@ -29,8 +29,9 @@ before_deploy:
|
|||||||
if [ "$TRAVIS_TAG" ]; then
|
if [ "$TRAVIS_TAG" ]; then
|
||||||
make release-packages;
|
make release-packages;
|
||||||
fi;
|
fi;
|
||||||
curl -sfL https://raw.githubusercontent.com/containous/structor/master/godownloader.sh | bash -s -- -b "${GOPATH}/bin" ${STRUCTOR_VERSION}
|
curl -sfL https://raw.githubusercontent.com/traefik/structor/master/godownloader.sh | bash -s -- -b "${GOPATH}/bin" ${STRUCTOR_VERSION}
|
||||||
structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/v1.7/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" --force-edit-url --exp-branch=master --debug;
|
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" --force-edit-url --exp-branch=master --debug;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
@@ -40,19 +41,17 @@ deploy:
|
|||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
file_glob: true
|
file_glob: true
|
||||||
on:
|
on:
|
||||||
repo: containous/traefik
|
repo: traefik/traefik
|
||||||
tags: true
|
tags: true
|
||||||
- provider: script
|
- provider: script
|
||||||
script: sh script/deploy.sh
|
script: sh script/deploy.sh
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
on:
|
on:
|
||||||
repo: containous/traefik
|
repo: traefik/traefik
|
||||||
tags: true
|
tags: true
|
||||||
- provider: pages
|
- provider: script
|
||||||
edge: false
|
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
|
||||||
github_token: ${GITHUB_TOKEN}
|
|
||||||
local_dir: site
|
|
||||||
skip_cleanup: true
|
skip_cleanup: true
|
||||||
on:
|
on:
|
||||||
repo: containous/traefik
|
repo: traefik/traefik
|
||||||
all_branches: true
|
all_branches: true
|
Binary file not shown.
7756
CHANGELOG.md
7756
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ Representation of a project may be further defined and clarified by project main
|
|||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@containo.us
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be 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.
|
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.
|
The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
Further details of specific enforcement policies may be posted separately.
|
Further details of specific enforcement policies may be posted separately.
|
||||||
@@ -48,4 +48,4 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
|
|||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
|
||||||
[homepage]: http://contributor-covenant.org
|
[homepage]: http://contributor-covenant.org
|
||||||
[version]: http://contributor-covenant.org/version/1/4/
|
[version]: http://contributor-covenant.org/version/1/4/
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
- https://docs.traefik.io/contributing/submitting-pull-requests/
|
- https://doc.traefik.io/traefik/contributing/submitting-pull-requests/
|
||||||
- https://docs.traefik.io/contributing/submitting-issues/
|
- https://doc.traefik.io/traefik/contributing/submitting-issues/
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016-2018 Containous SAS
|
Copyright (c) 2016-2020 Containous SAS; 2020 Traefik Labs
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
13
Makefile
13
Makefile
@@ -13,7 +13,7 @@ GIT_BRANCH := $(subst heads/,,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/nul
|
|||||||
TRAEFIK_DEV_IMAGE := traefik-dev$(if $(GIT_BRANCH),:$(subst /,-,$(GIT_BRANCH)))
|
TRAEFIK_DEV_IMAGE := traefik-dev$(if $(GIT_BRANCH),:$(subst /,-,$(GIT_BRANCH)))
|
||||||
|
|
||||||
REPONAME := $(shell echo $(REPO) | tr '[:upper:]' '[:lower:]')
|
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")
|
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")
|
||||||
DOCKER_BUILD_ARGS := $(if $(DOCKER_VERSION), "--build-arg=DOCKER_VERSION=$(DOCKER_VERSION)",)
|
DOCKER_BUILD_ARGS := $(if $(DOCKER_VERSION), "--build-arg=DOCKER_VERSION=$(DOCKER_VERSION)",)
|
||||||
@@ -29,13 +29,16 @@ TRAEFIK_ENVS := \
|
|||||||
-e CI \
|
-e CI \
|
||||||
-e CONTAINER=DOCKER # Indicator for integration tests that we are running inside a container.
|
-e CONTAINER=DOCKER # Indicator for integration tests that we are running inside a container.
|
||||||
|
|
||||||
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)"
|
||||||
DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)"
|
DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)"
|
||||||
DOCKER_RUN_TRAEFIK := docker run $(INTEGRATION_OPTS) -it $(DOCKER_RUN_OPTS)
|
DOCKER_NON_INTERACTIVE ?= false
|
||||||
DOCKER_RUN_TRAEFIK_NOTTY := docker run $(INTEGRATION_OPTS) -i $(DOCKER_RUN_OPTS)
|
DOCKER_RUN_TRAEFIK := docker run --add-host=host.docker.internal:127.0.0.1 $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS)
|
||||||
|
DOCKER_RUN_TRAEFIK_NOTTY := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -i) $(DOCKER_RUN_OPTS)
|
||||||
|
|
||||||
PRE_TARGET ?= build-dev-image
|
PRE_TARGET ?= build-dev-image
|
||||||
|
|
||||||
|
PLATFORM_URL := $(if $(PLATFORM_URL),$(PLATFORM_URL),"https://pilot.traefik.io")
|
||||||
|
|
||||||
default: binary
|
default: binary
|
||||||
|
|
||||||
## Build Dev Docker image
|
## Build Dev Docker image
|
||||||
@@ -52,7 +55,7 @@ dist:
|
|||||||
|
|
||||||
## Build WebUI Docker image
|
## Build WebUI Docker image
|
||||||
build-webui-image:
|
build-webui-image:
|
||||||
docker build -t traefik-webui -f webui/Dockerfile webui
|
docker build -t traefik-webui --build-arg ARG_PLATFORM_URL=$(PLATFORM_URL) -f webui/Dockerfile webui
|
||||||
|
|
||||||
## Generate WebUI
|
## Generate WebUI
|
||||||
generate-webui: build-webui-image
|
generate-webui: build-webui-image
|
||||||
|
58
README.md
58
README.md
@@ -4,11 +4,11 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
[](https://semaphoreci.com/containous/traefik)
|
[](https://semaphoreci.com/containous/traefik)
|
||||||
[](https://docs.traefik.io)
|
[](https://doc.traefik.io/traefik)
|
||||||
[](http://goreportcard.com/report/containous/traefik)
|
[](https://goreportcard.com/report/traefik/traefik)
|
||||||
[](https://microbadger.com/images/traefik)
|
[](https://microbadger.com/images/traefik)
|
||||||
[](https://github.com/containous/traefik/blob/master/LICENSE.md)
|
[](https://github.com/traefik/traefik/blob/master/LICENSE.md)
|
||||||
[](https://community.containo.us/)
|
[](https://community.traefik.io/)
|
||||||
[](https://twitter.com/intent/follow?screen_name=traefik)
|
[](https://twitter.com/intent/follow?screen_name=traefik)
|
||||||
|
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ Pointing Traefik at your orchestrator should be the _only_ configuration step yo
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
:warning: Please be aware that the old configurations for Traefik v1.x are NOT compatible with the v2.x config as of now. If you're running v2, please ensure you are using a [v2 configuration](https://docs.traefik.io/).
|
:warning: Please be aware that the old configurations for Traefik v1.x are NOT compatible with the v2.x config as of now. If you're running v2, please ensure you are using a [v2 configuration](https://doc.traefik.io/traefik/).
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -69,15 +69,15 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t
|
|||||||
|
|
||||||
## Supported Backends
|
## Supported Backends
|
||||||
|
|
||||||
- [Docker](https://docs.traefik.io/providers/docker/) / [Swarm mode](https://docs.traefik.io/providers/docker/)
|
- [Docker](https://doc.traefik.io/traefik/providers/docker/) / [Swarm mode](https://doc.traefik.io/traefik/providers/docker/)
|
||||||
- [Kubernetes](https://docs.traefik.io/providers/kubernetes-crd/)
|
- [Kubernetes](https://doc.traefik.io/traefik/providers/kubernetes-crd/)
|
||||||
- [Marathon](https://docs.traefik.io/providers/marathon/)
|
- [Marathon](https://doc.traefik.io/traefik/providers/marathon/)
|
||||||
- [Rancher](https://docs.traefik.io/providers/rancher/) (Metadata)
|
- [Rancher](https://doc.traefik.io/traefik/providers/rancher/) (Metadata)
|
||||||
- [File](https://docs.traefik.io/configuration/backends/file)
|
- [File](https://doc.traefik.io/traefik/providers/file/)
|
||||||
|
|
||||||
## Quickstart
|
## 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](https://doc.traefik.io/traefik/getting-started/quick-start/) in our documentation (you will need Docker).
|
||||||
|
|
||||||
## Web UI
|
## Web UI
|
||||||
|
|
||||||
@@ -87,28 +87,28 @@ You can access the simple HTML frontend of Traefik.
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
You can find the complete documentation of Traefik v2 at [https://docs.traefik.io](https://docs.traefik.io).
|
You can find the complete documentation of Traefik v2 at [https://doc.traefik.io/traefik/](https://doc.traefik.io/traefik/).
|
||||||
|
|
||||||
If you are using Traefik v1, you can find the complete documentation at [https://docs.traefik.io/v1.7/](https://docs.traefik.io/v1.7/)
|
If you are using Traefik v1, 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).
|
A collection of contributions around Traefik can be found at [https://awesome.traefik.io](https://awesome.traefik.io).
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
To get community support, you can:
|
To get community support, you can:
|
||||||
- join the Traefik community forum: [](https://community.containo.us/)
|
- join the Traefik community forum: [](https://community.traefik.io/)
|
||||||
|
|
||||||
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
|
## 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/master/traefik.sample.toml):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./traefik --configFile=traefik.toml
|
./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/master/traefik.sample.toml):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
|
docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
|
||||||
@@ -117,12 +117,12 @@ docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.toml:/etc/traefik/traefik.to
|
|||||||
- Or get the sources:
|
- Or get the sources:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone https://github.com/containous/traefik
|
git clone https://github.com/traefik/traefik
|
||||||
```
|
```
|
||||||
|
|
||||||
## Introductory Videos
|
## Introductory Videos
|
||||||
|
|
||||||
You can find high level and deep dive videos on [videos.containo.us](https://videos.containo.us)
|
You can find high level and deep dive videos on [videos.traefik.io](https://videos.traefik.io).
|
||||||
|
|
||||||
## Maintainers
|
## Maintainers
|
||||||
|
|
||||||
@@ -138,23 +138,23 @@ By participating in this project, you agree to abide by its terms.
|
|||||||
## Release Cycle
|
## Release Cycle
|
||||||
|
|
||||||
- We release a new version (e.g. 1.1.0, 1.2.0, 1.3.0) every other month.
|
- We release a new version (e.g. 1.1.0, 1.2.0, 1.3.0) every other month.
|
||||||
- Release Candidates are available before the release (e.g. 1.1.0-rc1, 1.1.0-rc2, 1.1.0-rc3, 1.1.0-rc4, before 1.1.0)
|
- Release Candidates are available before the release (e.g. 1.1.0-rc1, 1.1.0-rc2, 1.1.0-rc3, 1.1.0-rc4, before 1.1.0).
|
||||||
- Bug-fixes (e.g. 1.1.1, 1.1.2, 1.2.1, 1.2.3) are released as needed (no additional features are delivered in those versions, bug-fixes only)
|
- Bug-fixes (e.g. 1.1.1, 1.1.2, 1.2.1, 1.2.3) are released as needed (no additional features are delivered in those versions, bug-fixes only).
|
||||||
|
|
||||||
Each version is supported until the next one is released (e.g. 1.1.x will be supported until 1.2.0 is out)
|
Each version is supported until the next one is released (e.g. 1.1.x will be supported until 1.2.0 is out).
|
||||||
|
|
||||||
We use [Semantic Versioning](http://semver.org/)
|
We use [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
## Mailing lists
|
## Mailing Lists
|
||||||
|
|
||||||
- General announcements, new releases: mail at news+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/news)
|
- General announcements, new releases: mail at news+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/news).
|
||||||
- Security announcements: mail at security+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/security).
|
- Security announcements: mail at security+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/security).
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
Kudos to [Peka](http://peka.byethost11.com/photoblog/) for his awesome work on the logo .
|
Kudos to [Peka](http://peka.byethost11.com/photoblog/) for his awesome work on the gopher's logo!.
|
||||||
|
|
||||||
Traefik's logo is licensed under the Creative Commons 3.0 Attributions license.
|
The gopher's logo of Traefik is licensed under the Creative Commons 3.0 Attributions license.
|
||||||
|
|
||||||
Traefik's logo was inspired by the gopher stickers made by Takuya Ueda (https://twitter.com/tenntenn).
|
The gopher's logo of Traefik was inspired by the gopher stickers made by [Takuya Ueda](https://twitter.com/tenntenn).
|
||||||
The original Go gopher was designed by Renee French (http://reneefrench.blogspot.com/).
|
The original Go gopher was designed by [Renee French](https://reneefrench.blogspot.com/).
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.13-alpine
|
FROM golang:1.15-alpine
|
||||||
|
|
||||||
RUN apk --update upgrade \
|
RUN apk --update upgrade \
|
||||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
||||||
@@ -19,19 +19,19 @@ RUN mkdir -p /usr/local/bin \
|
|||||||
&& chmod +x /usr/local/bin/go-bindata
|
&& chmod +x /usr/local/bin/go-bindata
|
||||||
|
|
||||||
# Download golangci-lint binary to bin folder in $GOPATH
|
# Download golangci-lint binary to bin folder in $GOPATH
|
||||||
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.20.0
|
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.31.0
|
||||||
|
|
||||||
# Download golangci-lint and misspell binary to bin folder in $GOPATH
|
# Download misspell binary to bin folder in $GOPATH
|
||||||
RUN GO111MODULE=off go get github.com/client9/misspell/cmd/misspell
|
RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4
|
||||||
|
|
||||||
# Download goreleaser binary to bin folder in $GOPATH
|
# Download goreleaser binary to bin folder in $GOPATH
|
||||||
RUN curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | sh
|
RUN curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | sh
|
||||||
|
|
||||||
WORKDIR /go/src/github.com/containous/traefik
|
WORKDIR /go/src/github.com/traefik/traefik
|
||||||
|
|
||||||
# Download go modules
|
# Download go modules
|
||||||
COPY go.mod .
|
COPY go.mod .
|
||||||
COPY go.sum .
|
COPY go.sum .
|
||||||
RUN GO111MODULE=on GOPROXY=https://proxy.golang.org go mod download
|
RUN GO111MODULE=on GOPROXY=https://proxy.golang.org go mod download
|
||||||
|
|
||||||
COPY . /go/src/github.com/containous/traefik
|
COPY . /go/src/github.com/traefik/traefik
|
||||||
|
@@ -3,8 +3,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/static"
|
ptypes "github.com/traefik/paerser/types"
|
||||||
"github.com/containous/traefik/v2/pkg/types"
|
"github.com/traefik/traefik/v2/pkg/config/static"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TraefikCmdConfiguration wraps the static configuration and extra parameters.
|
// TraefikCmdConfiguration wraps the static configuration and extra parameters.
|
||||||
@@ -23,7 +23,7 @@ func NewTraefikConfiguration() *TraefikCmdConfiguration {
|
|||||||
},
|
},
|
||||||
EntryPoints: make(static.EntryPoints),
|
EntryPoints: make(static.EntryPoints),
|
||||||
Providers: &static.Providers{
|
Providers: &static.Providers{
|
||||||
ProvidersThrottleDuration: types.Duration(2 * time.Second),
|
ProvidersThrottleDuration: ptypes.Duration(2 * time.Second),
|
||||||
},
|
},
|
||||||
ServersTransport: &static.ServersTransport{
|
ServersTransport: &static.ServersTransport{
|
||||||
MaxIdleConnsPerHost: 200,
|
MaxIdleConnsPerHost: 200,
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContextWithSignal creates a context canceled when SIGINT or SIGTERM are notified
|
// ContextWithSignal creates a context canceled when SIGINT or SIGTERM are notified.
|
||||||
func ContextWithSignal(ctx context.Context) context.Context {
|
func ContextWithSignal(ctx context.Context) context.Context {
|
||||||
newCtx, cancel := context.WithCancel(ctx)
|
newCtx, cancel := context.WithCancel(ctx)
|
||||||
signals := make(chan os.Signal)
|
signals := make(chan os.Signal)
|
||||||
|
@@ -7,8 +7,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/cli"
|
"github.com/traefik/paerser/cli"
|
||||||
"github.com/containous/traefik/v2/pkg/config/static"
|
"github.com/traefik/traefik/v2/pkg/config/static"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmd builds a new HealthCheck command.
|
// NewCmd builds a new HealthCheck command.
|
||||||
@@ -45,15 +45,20 @@ func runCmd(traefikConfiguration *static.Configuration) func(_ []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do try to do a healthcheck
|
// Do try to do a healthcheck.
|
||||||
func Do(staticConfiguration static.Configuration) (*http.Response, error) {
|
func Do(staticConfiguration static.Configuration) (*http.Response, error) {
|
||||||
if staticConfiguration.Ping == nil {
|
if staticConfiguration.Ping == nil {
|
||||||
return nil, errors.New("please enable `ping` to use health check")
|
return nil, errors.New("please enable `ping` to use health check")
|
||||||
}
|
}
|
||||||
|
|
||||||
pingEntryPoint, ok := staticConfiguration.EntryPoints["traefik"]
|
ep := staticConfiguration.Ping.EntryPoint
|
||||||
|
if ep == "" {
|
||||||
|
ep = "traefik"
|
||||||
|
}
|
||||||
|
|
||||||
|
pingEntryPoint, ok := staticConfiguration.EntryPoints[ep]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("missing `ping` entrypoint")
|
return nil, fmt.Errorf("ping: missing %s entry point", ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
client := &http.Client{Timeout: 5 * time.Second}
|
client := &http.Client{Timeout: 5 * time.Second}
|
||||||
@@ -70,5 +75,5 @@ func Do(staticConfiguration static.Configuration) (*http.Response, error) {
|
|||||||
|
|
||||||
path := "/"
|
path := "/"
|
||||||
|
|
||||||
return client.Head(protocol + "://" + pingEntryPoint.Address + path + "ping")
|
return client.Head(protocol + "://" + pingEntryPoint.GetAddress() + path + "ping")
|
||||||
}
|
}
|
||||||
|
40
cmd/traefik/plugins.go
Normal file
40
cmd/traefik/plugins.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/static"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/plugins"
|
||||||
|
)
|
||||||
|
|
||||||
|
const outputDir = "./plugins-storage/"
|
||||||
|
|
||||||
|
func initPlugins(staticCfg *static.Configuration) (*plugins.Client, map[string]plugins.Descriptor, *plugins.DevPlugin, error) {
|
||||||
|
if !isPilotEnabled(staticCfg) || !hasPlugins(staticCfg) {
|
||||||
|
return nil, map[string]plugins.Descriptor{}, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := plugins.ClientOptions{
|
||||||
|
Output: outputDir,
|
||||||
|
Token: staticCfg.Pilot.Token,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := plugins.NewClient(opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = plugins.Setup(client, staticCfg.Experimental.Plugins, staticCfg.Experimental.DevPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, staticCfg.Experimental.Plugins, staticCfg.Experimental.DevPlugin, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isPilotEnabled(staticCfg *static.Configuration) bool {
|
||||||
|
return staticCfg.Pilot != nil && staticCfg.Pilot.Token != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasPlugins(staticCfg *static.Configuration) bool {
|
||||||
|
return staticCfg.Experimental != nil &&
|
||||||
|
(len(staticCfg.Experimental.Plugins) > 0 || staticCfg.Experimental.DevPlugin != nil)
|
||||||
|
}
|
@@ -3,33 +3,42 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
stdlog "log"
|
stdlog "log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/autogen/genstatic"
|
|
||||||
"github.com/containous/traefik/v2/cmd"
|
|
||||||
"github.com/containous/traefik/v2/cmd/healthcheck"
|
|
||||||
cmdVersion "github.com/containous/traefik/v2/cmd/version"
|
|
||||||
"github.com/containous/traefik/v2/pkg/cli"
|
|
||||||
"github.com/containous/traefik/v2/pkg/collector"
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
|
||||||
"github.com/containous/traefik/v2/pkg/config/static"
|
|
||||||
"github.com/containous/traefik/v2/pkg/log"
|
|
||||||
"github.com/containous/traefik/v2/pkg/provider/acme"
|
|
||||||
"github.com/containous/traefik/v2/pkg/provider/aggregator"
|
|
||||||
"github.com/containous/traefik/v2/pkg/safe"
|
|
||||||
"github.com/containous/traefik/v2/pkg/server"
|
|
||||||
"github.com/containous/traefik/v2/pkg/server/router"
|
|
||||||
traefiktls "github.com/containous/traefik/v2/pkg/tls"
|
|
||||||
"github.com/containous/traefik/v2/pkg/version"
|
|
||||||
"github.com/coreos/go-systemd/daemon"
|
"github.com/coreos/go-systemd/daemon"
|
||||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/traefik/paerser/cli"
|
||||||
|
"github.com/traefik/traefik/v2/autogen/genstatic"
|
||||||
|
"github.com/traefik/traefik/v2/cmd"
|
||||||
|
"github.com/traefik/traefik/v2/cmd/healthcheck"
|
||||||
|
cmdVersion "github.com/traefik/traefik/v2/cmd/version"
|
||||||
|
tcli "github.com/traefik/traefik/v2/pkg/cli"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/collector"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/runtime"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/config/static"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/metrics"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/middlewares/accesslog"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/pilot"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/plugins"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/provider/acme"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/provider/aggregator"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/provider/traefik"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/safe"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/server"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/server/middleware"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/server/service"
|
||||||
|
traefiktls "github.com/traefik/traefik/v2/pkg/tls"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/types"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/version"
|
||||||
"github.com/vulcand/oxy/roundrobin"
|
"github.com/vulcand/oxy/roundrobin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,7 +46,7 @@ func main() {
|
|||||||
// traefik config inits
|
// traefik config inits
|
||||||
tConfig := cmd.NewTraefikConfiguration()
|
tConfig := cmd.NewTraefikConfiguration()
|
||||||
|
|
||||||
loaders := []cli.ResourceLoader{&cli.FileLoader{}, &cli.FlagLoader{}, &cli.EnvLoader{}}
|
loaders := []cli.ResourceLoader{&tcli.FileLoader{}, &tcli.FlagLoader{}, &tcli.EnvLoader{}}
|
||||||
|
|
||||||
cmdTraefik := &cli.Command{
|
cmdTraefik := &cli.Command{
|
||||||
Name: "traefik",
|
Name: "traefik",
|
||||||
@@ -65,10 +74,10 @@ Complete documentation is available at https://traefik.io`,
|
|||||||
err = cli.Execute(cmdTraefik)
|
err = cli.Execute(cmdTraefik)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stdlog.Println(err)
|
stdlog.Println(err)
|
||||||
os.Exit(1)
|
logrus.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(0)
|
logrus.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCmd(staticConfiguration *static.Configuration) error {
|
func runCmd(staticConfiguration *static.Configuration) error {
|
||||||
@@ -77,7 +86,7 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
|||||||
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
||||||
|
|
||||||
if err := roundrobin.SetDefaultWeight(0); err != nil {
|
if err := roundrobin.SetDefaultWeight(0); err != nil {
|
||||||
log.WithoutContext().Errorf("Could not set roundrobin default weight: %v", err)
|
log.WithoutContext().Errorf("Could not set round robin default weight: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
staticConfiguration.SetEffectiveConfiguration()
|
staticConfiguration.SetEffectiveConfiguration()
|
||||||
@@ -105,45 +114,19 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
|||||||
|
|
||||||
stats(staticConfiguration)
|
stats(staticConfiguration)
|
||||||
|
|
||||||
providerAggregator := aggregator.NewProviderAggregator(*staticConfiguration.Providers)
|
svr, err := setupServer(staticConfiguration)
|
||||||
|
if err != nil {
|
||||||
tlsManager := traefiktls.NewManager()
|
return err
|
||||||
|
|
||||||
acmeProviders := initACMEProvider(staticConfiguration, &providerAggregator, tlsManager)
|
|
||||||
|
|
||||||
serverEntryPointsTCP := make(server.TCPEntryPoints)
|
|
||||||
for entryPointName, config := range staticConfiguration.EntryPoints {
|
|
||||||
ctx := log.With(context.Background(), log.Str(log.EntryPointName, entryPointName))
|
|
||||||
serverEntryPointsTCP[entryPointName], err = server.NewTCPEntryPoint(ctx, config)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error while building entryPoint %s: %v", entryPointName, err)
|
|
||||||
}
|
|
||||||
serverEntryPointsTCP[entryPointName].RouteAppenderFactory = router.NewRouteAppenderFactory(*staticConfiguration, entryPointName, acmeProviders)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
svr := server.NewServer(*staticConfiguration, providerAggregator, serverEntryPointsTCP, tlsManager)
|
|
||||||
|
|
||||||
resolverNames := map[string]struct{}{}
|
|
||||||
|
|
||||||
for _, p := range acmeProviders {
|
|
||||||
resolverNames[p.ResolverName] = struct{}{}
|
|
||||||
svr.AddListener(p.ListenConfiguration)
|
|
||||||
}
|
|
||||||
|
|
||||||
svr.AddListener(func(config dynamic.Configuration) {
|
|
||||||
for rtName, rt := range config.HTTP.Routers {
|
|
||||||
if rt.TLS == nil || rt.TLS.CertResolver == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := resolverNames[rt.TLS.CertResolver]; !ok {
|
|
||||||
log.WithoutContext().Errorf("the router %s uses a non-existent resolver: %s", rtName, rt.TLS.CertResolver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx := cmd.ContextWithSignal(context.Background())
|
ctx := cmd.ContextWithSignal(context.Background())
|
||||||
|
|
||||||
|
if staticConfiguration.Experimental != nil && staticConfiguration.Experimental.DevPlugin != nil {
|
||||||
|
var cancel context.CancelFunc
|
||||||
|
ctx, cancel = context.WithTimeout(ctx, 30*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
}
|
||||||
|
|
||||||
if staticConfiguration.Ping != nil {
|
if staticConfiguration.Ping != nil {
|
||||||
staticConfiguration.Ping.WithContext(ctx)
|
staticConfiguration.Ping.WithContext(ctx)
|
||||||
}
|
}
|
||||||
@@ -168,7 +151,7 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
|||||||
for range tick {
|
for range tick {
|
||||||
resp, errHealthCheck := healthcheck.Do(*staticConfiguration)
|
resp, errHealthCheck := healthcheck.Do(*staticConfiguration)
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
resp.Body.Close()
|
_ = resp.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if staticConfiguration.Ping == nil || errHealthCheck == nil {
|
if staticConfiguration.Ping == nil || errHealthCheck == nil {
|
||||||
@@ -184,11 +167,157 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
|||||||
|
|
||||||
svr.Wait()
|
svr.Wait()
|
||||||
log.WithoutContext().Info("Shutting down")
|
log.WithoutContext().Info("Shutting down")
|
||||||
logrus.Exit(0)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration
|
func setupServer(staticConfiguration *static.Configuration) (*server.Server, error) {
|
||||||
|
providerAggregator := aggregator.NewProviderAggregator(*staticConfiguration.Providers)
|
||||||
|
|
||||||
|
// adds internal provider
|
||||||
|
err := providerAggregator.AddProvider(traefik.New(*staticConfiguration))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsManager := traefiktls.NewManager()
|
||||||
|
|
||||||
|
acmeProviders := initACMEProvider(staticConfiguration, &providerAggregator, tlsManager)
|
||||||
|
|
||||||
|
serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
serverEntryPointsUDP, err := server.NewUDPEntryPoints(staticConfiguration.EntryPoints)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
routinesPool := safe.NewPool(ctx)
|
||||||
|
|
||||||
|
metricRegistries := registerMetricClients(staticConfiguration.Metrics)
|
||||||
|
|
||||||
|
var aviator *pilot.Pilot
|
||||||
|
if isPilotEnabled(staticConfiguration) {
|
||||||
|
pilotRegistry := metrics.RegisterPilot()
|
||||||
|
|
||||||
|
aviator = pilot.New(staticConfiguration.Pilot.Token, pilotRegistry, routinesPool)
|
||||||
|
routinesPool.GoCtx(func(ctx context.Context) {
|
||||||
|
aviator.Tick(ctx)
|
||||||
|
})
|
||||||
|
|
||||||
|
metricRegistries = append(metricRegistries, pilotRegistry)
|
||||||
|
}
|
||||||
|
|
||||||
|
metricsRegistry := metrics.NewMultiRegistry(metricRegistries)
|
||||||
|
accessLog := setupAccessLog(staticConfiguration.AccessLog)
|
||||||
|
chainBuilder := middleware.NewChainBuilder(*staticConfiguration, metricsRegistry, accessLog)
|
||||||
|
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry)
|
||||||
|
|
||||||
|
client, plgs, devPlugin, err := initPlugins(staticConfiguration)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginBuilder, err := plugins.NewBuilder(client, plgs, devPlugin)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder)
|
||||||
|
|
||||||
|
var defaultEntryPoints []string
|
||||||
|
for name, cfg := range staticConfiguration.EntryPoints {
|
||||||
|
protocol, err := cfg.GetProtocol()
|
||||||
|
if err != nil {
|
||||||
|
// Should never happen because Traefik should not start if protocol is invalid.
|
||||||
|
log.WithoutContext().Errorf("Invalid protocol: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if protocol != "udp" && name != static.DefaultInternalEntryPointName {
|
||||||
|
defaultEntryPoints = append(defaultEntryPoints, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(defaultEntryPoints)
|
||||||
|
|
||||||
|
watcher := server.NewConfigurationWatcher(
|
||||||
|
routinesPool,
|
||||||
|
providerAggregator,
|
||||||
|
time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration),
|
||||||
|
defaultEntryPoints,
|
||||||
|
)
|
||||||
|
|
||||||
|
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||||
|
ctx := context.Background()
|
||||||
|
tlsManager.UpdateConfigs(ctx, conf.TLS.Stores, conf.TLS.Options, conf.TLS.Certificates)
|
||||||
|
})
|
||||||
|
|
||||||
|
watcher.AddListener(func(_ dynamic.Configuration) {
|
||||||
|
metricsRegistry.ConfigReloadsCounter().Add(1)
|
||||||
|
metricsRegistry.LastConfigReloadSuccessGauge().Set(float64(time.Now().Unix()))
|
||||||
|
})
|
||||||
|
|
||||||
|
watcher.AddListener(switchRouter(routerFactory, acmeProviders, serverEntryPointsTCP, serverEntryPointsUDP, aviator))
|
||||||
|
|
||||||
|
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||||
|
if metricsRegistry.IsEpEnabled() || metricsRegistry.IsSvcEnabled() {
|
||||||
|
var eps []string
|
||||||
|
for key := range serverEntryPointsTCP {
|
||||||
|
eps = append(eps, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
metrics.OnConfigurationUpdate(conf, eps)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resolverNames := map[string]struct{}{}
|
||||||
|
for _, p := range acmeProviders {
|
||||||
|
resolverNames[p.ResolverName] = struct{}{}
|
||||||
|
watcher.AddListener(p.ListenConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
watcher.AddListener(func(config dynamic.Configuration) {
|
||||||
|
for rtName, rt := range config.HTTP.Routers {
|
||||||
|
if rt.TLS == nil || rt.TLS.CertResolver == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := resolverNames[rt.TLS.CertResolver]; !ok {
|
||||||
|
log.WithoutContext().Errorf("the router %s uses a non-existent resolver: %s", rtName, rt.TLS.CertResolver)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, chainBuilder, accessLog), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func switchRouter(routerFactory *server.RouterFactory, acmeProviders []*acme.Provider, serverEntryPointsTCP server.TCPEntryPoints, serverEntryPointsUDP server.UDPEntryPoints, aviator *pilot.Pilot) func(conf dynamic.Configuration) {
|
||||||
|
return func(conf dynamic.Configuration) {
|
||||||
|
rtConf := runtime.NewConfig(conf)
|
||||||
|
|
||||||
|
routers, udpRouters := routerFactory.CreateRouters(rtConf)
|
||||||
|
|
||||||
|
for entryPointName, rt := range routers {
|
||||||
|
for _, p := range acmeProviders {
|
||||||
|
if p != nil && p.HTTPChallenge != nil && p.HTTPChallenge.EntryPoint == entryPointName {
|
||||||
|
rt.HTTPHandler(p.CreateHandler(rt.GetHTTPHandler()))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if aviator != nil {
|
||||||
|
aviator.SetRuntimeConfiguration(rtConf)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverEntryPointsTCP.Switch(routers)
|
||||||
|
serverEntryPointsUDP.Switch(udpRouters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration.
|
||||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager) []*acme.Provider {
|
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager) []*acme.Provider {
|
||||||
challengeStore := acme.NewLocalChallengeStore()
|
challengeStore := acme.NewLocalChallengeStore()
|
||||||
localStores := map[string]*acme.LocalStore{}
|
localStores := map[string]*acme.LocalStore{}
|
||||||
@@ -208,20 +337,78 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := providerAggregator.AddProvider(p); err != nil {
|
if err := providerAggregator.AddProvider(p); err != nil {
|
||||||
log.WithoutContext().Errorf("Unable to add ACME provider to the providers list: %v", err)
|
log.WithoutContext().Errorf("The ACME resolver %q is skipped from the resolvers list because: %v", name, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
p.SetTLSManager(tlsManager)
|
p.SetTLSManager(tlsManager)
|
||||||
|
|
||||||
if p.TLSChallenge != nil {
|
if p.TLSChallenge != nil {
|
||||||
tlsManager.TLSAlpnGetter = p.GetTLSALPNCertificate
|
tlsManager.TLSAlpnGetter = p.GetTLSALPNCertificate
|
||||||
}
|
}
|
||||||
|
|
||||||
p.SetConfigListenerChan(make(chan dynamic.Configuration))
|
p.SetConfigListenerChan(make(chan dynamic.Configuration))
|
||||||
|
|
||||||
resolvers = append(resolvers, p)
|
resolvers = append(resolvers, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resolvers
|
return resolvers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerMetricClients(metricsConfig *types.Metrics) []metrics.Registry {
|
||||||
|
if metricsConfig == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var registries []metrics.Registry
|
||||||
|
|
||||||
|
if metricsConfig.Prometheus != nil {
|
||||||
|
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "prometheus"))
|
||||||
|
prometheusRegister := metrics.RegisterPrometheus(ctx, metricsConfig.Prometheus)
|
||||||
|
if prometheusRegister != nil {
|
||||||
|
registries = append(registries, prometheusRegister)
|
||||||
|
log.FromContext(ctx).Debug("Configured Prometheus metrics")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if metricsConfig.Datadog != nil {
|
||||||
|
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "datadog"))
|
||||||
|
registries = append(registries, metrics.RegisterDatadog(ctx, metricsConfig.Datadog))
|
||||||
|
log.FromContext(ctx).Debugf("Configured Datadog metrics: pushing to %s once every %s",
|
||||||
|
metricsConfig.Datadog.Address, metricsConfig.Datadog.PushInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
if metricsConfig.StatsD != nil {
|
||||||
|
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "statsd"))
|
||||||
|
registries = append(registries, metrics.RegisterStatsd(ctx, metricsConfig.StatsD))
|
||||||
|
log.FromContext(ctx).Debugf("Configured StatsD metrics: pushing to %s once every %s",
|
||||||
|
metricsConfig.StatsD.Address, metricsConfig.StatsD.PushInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
if metricsConfig.InfluxDB != nil {
|
||||||
|
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "influxdb"))
|
||||||
|
registries = append(registries, metrics.RegisterInfluxDB(ctx, metricsConfig.InfluxDB))
|
||||||
|
log.FromContext(ctx).Debugf("Configured InfluxDB metrics: pushing to %s once every %s",
|
||||||
|
metricsConfig.InfluxDB.Address, metricsConfig.InfluxDB.PushInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
return registries
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupAccessLog(conf *types.AccessLog) *accesslog.Handler {
|
||||||
|
if conf == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
accessLoggerMiddleware, err := accesslog.NewHandler(conf)
|
||||||
|
if err != nil {
|
||||||
|
log.WithoutContext().Warnf("Unable to create access logger : %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessLoggerMiddleware
|
||||||
|
}
|
||||||
|
|
||||||
func configureLogging(staticConfiguration *static.Configuration) {
|
func configureLogging(staticConfiguration *static.Configuration) {
|
||||||
// configure default log flags
|
// configure default log flags
|
||||||
stdlog.SetFlags(stdlog.Lshortfile | stdlog.LstdFlags)
|
stdlog.SetFlags(stdlog.Lshortfile | stdlog.LstdFlags)
|
||||||
@@ -259,7 +446,7 @@ func configureLogging(staticConfiguration *static.Configuration) {
|
|||||||
if len(logFile) > 0 {
|
if len(logFile) > 0 {
|
||||||
dir := filepath.Dir(logFile)
|
dir := filepath.Dir(logFile)
|
||||||
|
|
||||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||||
log.WithoutContext().Errorf("Failed to create log path %s: %s", dir, err)
|
log.WithoutContext().Errorf("Failed to create log path %s: %s", dir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,13 +478,13 @@ func stats(staticConfiguration *static.Configuration) {
|
|||||||
logger.Info(`Stats collection is enabled.`)
|
logger.Info(`Stats collection is enabled.`)
|
||||||
logger.Info(`Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.`)
|
logger.Info(`Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.`)
|
||||||
logger.Info(`Help us improve Traefik by leaving this feature on :)`)
|
logger.Info(`Help us improve Traefik by leaving this feature on :)`)
|
||||||
logger.Info(`More details on: https://docs.traefik.io/v2.0/contributing/data-collection/`)
|
logger.Info(`More details on: https://doc.traefik.io/traefik/contributing/data-collection/`)
|
||||||
collect(staticConfiguration)
|
collect(staticConfiguration)
|
||||||
} else {
|
} else {
|
||||||
logger.Info(`
|
logger.Info(`
|
||||||
Stats collection is disabled.
|
Stats collection is disabled.
|
||||||
Help us improve Traefik by turning this feature on :)
|
Help us improve Traefik by turning this feature on :)
|
||||||
More details on: https://docs.traefik.io/v2.0/contributing/data-collection/
|
More details on: https://doc.traefik.io/traefik/contributing/data-collection/
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,8 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/containous/traefik/v2/pkg/cli"
|
"github.com/traefik/paerser/cli"
|
||||||
"github.com/containous/traefik/v2/pkg/version"
|
"github.com/traefik/traefik/v2/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
var versionTemplate = `Version: {{.Version}}
|
var versionTemplate = `Version: {{.Version}}
|
||||||
@@ -17,7 +17,7 @@ Go version: {{.GoVersion}}
|
|||||||
Built: {{.BuildTime}}
|
Built: {{.BuildTime}}
|
||||||
OS/Arch: {{.Os}}/{{.Arch}}`
|
OS/Arch: {{.Os}}/{{.Arch}}`
|
||||||
|
|
||||||
// NewCmd builds a new Version command
|
// NewCmd builds a new Version command.
|
||||||
func NewCmd() *cli.Command {
|
func NewCmd() *cli.Command {
|
||||||
return &cli.Command{
|
return &cli.Command{
|
||||||
Name: "version",
|
Name: "version",
|
||||||
@@ -33,7 +33,7 @@ func NewCmd() *cli.Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrint write Printable version
|
// GetPrint write Printable version.
|
||||||
func GetPrint(wr io.Writer) error {
|
func GetPrint(wr io.Writer) error {
|
||||||
tmpl, err := template.New("").Parse(versionTemplate)
|
tmpl, err := template.New("").Parse(versionTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Traefik
|
Description=Traefik
|
||||||
Documentation=https://docs.traefik.io
|
Documentation=https://doc.traefik.io/traefik/
|
||||||
#After=network-online.target
|
#After=network-online.target
|
||||||
#AssertFileIsExecutable=/usr/bin/traefik
|
#AssertFileIsExecutable=/usr/bin/traefik
|
||||||
#AssertPathExists=/etc/traefik/traefik.toml
|
#AssertPathExists=/etc/traefik/traefik.toml
|
||||||
|
@@ -7,5 +7,6 @@
|
|||||||
"MD026": false,
|
"MD026": false,
|
||||||
"MD033": false,
|
"MD033": false,
|
||||||
"MD034": false,
|
"MD034": false,
|
||||||
"MD036": false
|
"MD036": false,
|
||||||
|
"MD046": false
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
|
|
||||||
FROM alpine:3.9 as alpine
|
FROM alpine:3.10 as alpine
|
||||||
|
|
||||||
# The "build-dependencies" virtual package provides build tools for html-proofer installation.
|
|
||||||
# It compile ruby-nokogiri, because alpine native version is always out of date
|
|
||||||
# This virtual package is cleaned at the end.
|
|
||||||
RUN apk --no-cache --no-progress add \
|
RUN apk --no-cache --no-progress add \
|
||||||
libcurl \
|
libcurl \
|
||||||
ruby \
|
ruby \
|
||||||
@@ -11,21 +8,21 @@ RUN apk --no-cache --no-progress add \
|
|||||||
ruby-etc \
|
ruby-etc \
|
||||||
ruby-ffi \
|
ruby-ffi \
|
||||||
ruby-json \
|
ruby-json \
|
||||||
&& apk add --no-cache --virtual build-dependencies \
|
ruby-nokogiri
|
||||||
build-base \
|
RUN gem install html-proofer --version 3.13.0 --no-document -- --use-system-libraries
|
||||||
libcurl \
|
|
||||||
libxml2-dev \
|
|
||||||
libxslt-dev \
|
|
||||||
ruby-dev \
|
|
||||||
&& gem install --no-document html-proofer -v 3.10.2 \
|
|
||||||
&& apk del build-dependencies
|
|
||||||
|
|
||||||
# After Ruby, some NodeJS YAY!
|
# After Ruby, some NodeJS YAY!
|
||||||
RUN apk --no-cache --no-progress add \
|
RUN apk --no-cache --no-progress add \
|
||||||
git \
|
git \
|
||||||
nodejs \
|
nodejs \
|
||||||
npm \
|
npm
|
||||||
&& npm install markdownlint@0.12.0 markdownlint-cli@0.13.0 --global
|
|
||||||
|
# To handle 'not get uid/gid'
|
||||||
|
RUN npm config set unsafe-perm true
|
||||||
|
|
||||||
|
RUN npm install --global \
|
||||||
|
markdownlint@0.17.2 \
|
||||||
|
markdownlint-cli@0.19.0
|
||||||
|
|
||||||
# Finally the shell tools we need for later
|
# Finally the shell tools we need for later
|
||||||
# tini helps to terminate properly all the parallelized tasks when sending CTRL-C
|
# tini helps to terminate properly all the parallelized tasks when sending CTRL-C
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
docs.traefik.io
|
|
BIN
docs/content/assets/img/providers/consul.png
Normal file
BIN
docs/content/assets/img/providers/consul.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Before Width: | Height: | Size: 289 KiB After Width: | Height: | Size: 284 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
BIN
docs/content/assets/img/traefikproxy-icon-color.png
Normal file
BIN
docs/content/assets/img/traefikproxy-icon-color.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 20 KiB |
70
docs/content/assets/styles/content.css
Normal file
70
docs/content/assets/styles/content.css
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.md-container {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-content h1 {
|
||||||
|
color: var(--dark) !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-content a {
|
||||||
|
color: var(--blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-content a:hover {
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset p code,
|
||||||
|
.md-typeset .codehilite,
|
||||||
|
.md-typeset .highlight {
|
||||||
|
background-color: var(--light-blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset table:not([class]) th {
|
||||||
|
background: var(--dark) !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Front page image size */
|
||||||
|
img[src$='#small'] {
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
img[src$='#medium'] {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Center table and objects */
|
||||||
|
.center,
|
||||||
|
img,
|
||||||
|
.md-typeset__table {
|
||||||
|
display: block !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset table:not([class]) tr td:first-child {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.md-typeset table:not([class]) th:not([align]),
|
||||||
|
.md-typeset table:not([class]) td:not([align]) {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
article p:not([class]),
|
||||||
|
article ul:not([class]),
|
||||||
|
article ol:not([class]) {
|
||||||
|
padding-left: 0.8em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix for Chrome */
|
||||||
|
.md-typeset__table td code {
|
||||||
|
word-break: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset__table tr :nth-child(1) {
|
||||||
|
word-wrap: break-word;
|
||||||
|
max-width: 30em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
@@ -1,63 +0,0 @@
|
|||||||
@import url('https://fonts.googleapis.com/css?family=Noto+Sans|Noto+Serif');
|
|
||||||
|
|
||||||
.md-logo img {
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix for Chrome */
|
|
||||||
.md-typeset__table td code {
|
|
||||||
word-break: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-typeset__table tr :nth-child(1) {
|
|
||||||
word-wrap: break-word;
|
|
||||||
max-width: 30em;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Noto Sans', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-weight: bold !important;
|
|
||||||
color: rgba(0,0,0,.9) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-weight: bold !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-weight: bold !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-typeset h5 {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
figcaption {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.8em;
|
|
||||||
font-style: italic;
|
|
||||||
color: #8D909F;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.subtitle {
|
|
||||||
color: rgba(0,0,0,.54);
|
|
||||||
padding-top: 0;
|
|
||||||
margin-top: -2em;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-body .task-list-item {
|
|
||||||
list-style-type: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown-body .task-list-item input[type="checkbox"] {
|
|
||||||
margin: 0 4px 0.25em -20px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
10
docs/content/assets/styles/footer.css
Normal file
10
docs/content/assets/styles/footer.css
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
.md-footer-meta {
|
||||||
|
background-color: var(--dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-footer-privacy-policy {
|
||||||
|
margin: 0 .6rem;
|
||||||
|
padding: .4rem 0;
|
||||||
|
color: hsla(0,0%,100%,.3);
|
||||||
|
font-size: .64rem;
|
||||||
|
}
|
484
docs/content/assets/styles/header.css
Normal file
484
docs/content/assets/styles/header.css
Normal file
@@ -0,0 +1,484 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Rubik:300i,400,400i,500,500i,700&display=swap');
|
||||||
|
|
||||||
|
.wrapper-1200 {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 61rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 .6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.wrapper-1200 {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-type-1 {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
background-color: #1e54d5;
|
||||||
|
line-height: 1em;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.28) 1%, #1e54d5 99%);
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--secondary {
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid #1e54d5 !important;
|
||||||
|
background: transparent;
|
||||||
|
line-height: 1em;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 9px 13px;
|
||||||
|
letter-spacing: 0;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
color: #1e54d5;
|
||||||
|
transition: all 0.2s;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.button--secondary:hover {
|
||||||
|
color: white !important;
|
||||||
|
background: #1e54d5;
|
||||||
|
}
|
||||||
|
.button--secondary:focus {
|
||||||
|
color: white !important;
|
||||||
|
background: #1e54d5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header-and-placeholder-wrapper {
|
||||||
|
position: relative;
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
transition: height 0.1s;
|
||||||
|
z-index: 100;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 0 7px 0 #00000021;
|
||||||
|
border-bottom: 1px solid #e2e2e2;
|
||||||
|
height: 64px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 10px;
|
||||||
|
font-family: 'Rubik', -apple-system, 'BlinkMacSystemFont', 'Segoe UI',
|
||||||
|
'Helvetica Neue', sans-serif;
|
||||||
|
color: #06102a;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header.scrolled {
|
||||||
|
box-shadow: 0 0 5px 0 #00000028;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
.site-header.scrolled .site-header__title a {
|
||||||
|
font-size: 2.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-placeholder {
|
||||||
|
background: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 64px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.header-placeholder.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header .wrapper-1200 {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.site-header .wrapper-1200 .left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header__logo {
|
||||||
|
max-width: 145px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header__title a {
|
||||||
|
color: #06102a;
|
||||||
|
font-size: 2.2em;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navigation */
|
||||||
|
.site-header__nav .menu-item-wrapper {
|
||||||
|
display: inline-block;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item {
|
||||||
|
color: #06102a;
|
||||||
|
transition: all 0.05s;
|
||||||
|
font-size: 1.45em;
|
||||||
|
line-height: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item:hover {
|
||||||
|
color: #8a959e;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item--with-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item--with-icon .title {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item--with-icon .icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
transition: all 0.1s;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item--with-icon .icon svg {
|
||||||
|
stroke-width: 2.5 !important;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item-wrapper--dropdown {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.site-header__nav .menu-item-wrapper--dropdown:hover .nav-dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.site-header__nav .nav-dropdown-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 500;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu-wrapper {
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 12px 40px 0 rgba(1, 10, 32, 0.24);
|
||||||
|
background: white;
|
||||||
|
margin: 8px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Products, Solutions dropdown menu */
|
||||||
|
.nav-dropdown-menu--products,
|
||||||
|
.nav-dropdown-menu--solutions {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .nav-dropdown-menu-wrapper,
|
||||||
|
.nav-dropdown-menu--solutions .nav-dropdown-menu-wrapper {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .nav-dropdown-menu-wrapper {
|
||||||
|
height: 430px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu--products .dm-header,
|
||||||
|
.nav-dropdown-menu--solutions .dm-header {
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 3.67px;
|
||||||
|
color: #505769;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item {
|
||||||
|
border: none;
|
||||||
|
margin: 0 0 24px;
|
||||||
|
color: #06102a;
|
||||||
|
transition: all 0.1s;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item:last-child,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item .dmi-image {
|
||||||
|
width: 104px;
|
||||||
|
height: 72px;
|
||||||
|
position: absolute;
|
||||||
|
/*background: #f4f4f4;*/
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-image {
|
||||||
|
width: 65px;
|
||||||
|
padding: 10px;
|
||||||
|
background: white;
|
||||||
|
height: auto;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-image img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item .dmi-details,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-details {
|
||||||
|
padding: 6px 0 0 127px;
|
||||||
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
display: block;
|
||||||
|
color: #06102a;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item .dmi-details:hover,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-details:hover {
|
||||||
|
color: #1e54d5;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item .dmi-title,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-title {
|
||||||
|
font-size: 1.6em;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0 0 2px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item .dmi-description,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-description {
|
||||||
|
font-size: 1.4em;
|
||||||
|
opacity: 0.7;
|
||||||
|
line-height: 1.6em;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--products .dm-item--traefikee .dmi-image img,
|
||||||
|
.nav-dropdown-menu--solutions .dm-item--traefikee .dmi-image img {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu--solutions .dm-item .dmi-details {
|
||||||
|
padding: 5px 0 0 80px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--solutions .dm-item:last-child {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown menu: Learn and Company */
|
||||||
|
.nav-dropdown-menu--learn {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--company {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--company .nav-dropdown-menu-wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 50% 50%;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--learn .dm-left,
|
||||||
|
.nav-dropdown-menu--company .dm-left {
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--learn .dm-header,
|
||||||
|
.nav-dropdown-menu--company .dm-header {
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 3.67px;
|
||||||
|
color: #505769;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--learn .dm-item,
|
||||||
|
.nav-dropdown-menu--company .dm-item {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.6em;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #06102a;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--learn .dm-item:last-child,
|
||||||
|
.nav-dropdown-menu--company .dm-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--learn .dm-item:hover,
|
||||||
|
.nav-dropdown-menu--company .dm-item:hover {
|
||||||
|
color: #1e54d5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview {
|
||||||
|
background: #edeff4;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview__feature-image {
|
||||||
|
overflow: hidden;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview__feature-image img {
|
||||||
|
width: 100%;
|
||||||
|
height: 145px;
|
||||||
|
background: #ffffff no-repeat 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview__content {
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview__tag {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #db7d11;
|
||||||
|
letter-spacing: 2.5px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview__title {
|
||||||
|
font-size: 1.6em;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.6em;
|
||||||
|
margin: 0;
|
||||||
|
color: #06102a;
|
||||||
|
display: block;
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dm-preview .arrow-link {
|
||||||
|
justify-content: flex-start;
|
||||||
|
font-size: 1.4em;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 12px;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown menu: Company */
|
||||||
|
.nav-dropdown-menu--company {
|
||||||
|
width: 450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-dropdown-menu--company .dm-right {
|
||||||
|
background: #06102a;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
color: white;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--company .dm-right p {
|
||||||
|
font-size: 1.6em;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0 0 15px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.nav-dropdown-menu--company .dm-right a {
|
||||||
|
text-transform: uppercase;
|
||||||
|
line-height: 1.5em;
|
||||||
|
padding: 9px 12px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Demo */
|
||||||
|
.site-header__demo-button .button--secondary {
|
||||||
|
font-size: 1.4em;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drawer */
|
||||||
|
.site-header .drawer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1219px) {
|
||||||
|
.site-header__nav .menu-item-wrapper {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 980px) {
|
||||||
|
.site-header__nav {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header .drawer {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header .right .site-header__demo-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html [data-md-color-primary=indigo] .md-nav--primary .md-nav__title--site {
|
||||||
|
background-color: #06102a;
|
||||||
|
}
|
||||||
|
|
||||||
|
html .md-nav--primary .md-nav__title {
|
||||||
|
padding: 64px .8rem .2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-search__inner {
|
||||||
|
top: 64px;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-header .md-search {
|
||||||
|
margin-right: 12.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header__main {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmi-image.proxy {
|
||||||
|
background-color: #24a1c1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmi-image.mesh {
|
||||||
|
background-color: #9d0fb0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmi-image.enterprise {
|
||||||
|
background-color: #0060e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmi-image.pilot {
|
||||||
|
background-color: #db7d11;
|
||||||
|
}
|
101
docs/content/assets/styles/menu.css
Normal file
101
docs/content/assets/styles/menu.css
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
.md-nav__link {
|
||||||
|
margin-left: -0.4rem;
|
||||||
|
padding: 0 0.4rem;
|
||||||
|
line-height: 32px;
|
||||||
|
color: var(--dark) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__link::after {
|
||||||
|
font-size: 16px;
|
||||||
|
vertical-align: -.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__toggle:checked + .md-nav__link,
|
||||||
|
.md-nav__link--active,
|
||||||
|
.md-nav__link:hover {
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: var(--light-blue) !important;
|
||||||
|
color: var(--dark) !important;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__link--active {
|
||||||
|
color: var(--blue) !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--primary {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-nav__title {
|
||||||
|
font-size: 12px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin-bottom: 0.4rem;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-sidebar__scrollwrap {
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: var(--light-blue) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-nav__title {
|
||||||
|
padding: 0.8rem 0.4rem 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-nav__list {
|
||||||
|
padding: 0 0.4rem 0.8rem 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-sidebar__scrollwrap .md-nav__link {
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary
|
||||||
|
.md-sidebar__scrollwrap
|
||||||
|
.md-nav__link[data-md-state='blur'],
|
||||||
|
.md-sidebar--secondary .md-sidebar__scrollwrap .md-nav__link:hover {
|
||||||
|
color: var(--blue) !important;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-nav__item {
|
||||||
|
padding: 0 0 0 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .md-nav__link {
|
||||||
|
margin-top: 0.225em;
|
||||||
|
padding: 0.1rem 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary li {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-sidebar--secondary .repo_url {
|
||||||
|
padding: 10px 0 14px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.md-search__inner {
|
||||||
|
width: inherit;
|
||||||
|
float: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-search__input {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: inherit;
|
||||||
|
border: 1px solid rgba(0,0,0,.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-search__input::placeholder {
|
||||||
|
color: rgba(0,0,0,.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 60em) {
|
||||||
|
[data-md-toggle=search]:checked~.md-header .md-search__inner {
|
||||||
|
margin-top: 100px;
|
||||||
|
}
|
||||||
|
}
|
24
docs/content/assets/styles/product-switcher.css
Normal file
24
docs/content/assets/styles/product-switcher.css
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.product-switcher {
|
||||||
|
font-size: 10px;
|
||||||
|
font-family: 'Rubik', -apple-system, 'BlinkMacSystemFont', 'Segoe UI',
|
||||||
|
'Helvetica Neue', sans-serif;
|
||||||
|
color: #06102a;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-switcher .menu-item-wrapper {
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-switcher img {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-switcher img.gopher {
|
||||||
|
margin: 0 2px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-switcher .nav-dropdown-menu--products .nav-dropdown-menu-wrapper {
|
||||||
|
width: auto;
|
||||||
|
height: 335px;
|
||||||
|
}
|
10
docs/content/assets/styles/root.css
Normal file
10
docs/content/assets/styles/root.css
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
:root {
|
||||||
|
--dark: #06102a;
|
||||||
|
--blue: #04B5D1;
|
||||||
|
--light-blue: #E4F7FA;
|
||||||
|
|
||||||
|
--input-bg-color: white;
|
||||||
|
--input-color: black;
|
||||||
|
--input-placeholder-color: #bbb;
|
||||||
|
--input-border-color: #dcdcdc;
|
||||||
|
}
|
@@ -5,6 +5,6 @@ Spread the Love & Tell Us about It
|
|||||||
|
|
||||||
There are many ways to contribute to the project, and there is one that always spark joy: when we see/read about users talking about how Traefik helps them solve their problems.
|
There are many ways to contribute to the project, and there is one that always spark joy: when we see/read about users talking about how Traefik helps them solve their problems.
|
||||||
|
|
||||||
If you're talking about Traefik, [let us know](https://blog.containo.us/spread-the-love-ba5a40aa72e7) and we'll promote your enthusiasm!
|
If you're talking about Traefik, [let us know](https://blog.traefik.io/spread-the-love-ba5a40aa72e7) and we'll promote your enthusiasm!
|
||||||
|
|
||||||
Also, if you've written about Traefik or shared useful information you'd like to promote, feel free to add links in the [dedicated wiki page on Github](https://github.com/containous/traefik/wiki/Awesome-Traefik).
|
Also, if you've written about Traefik or shared useful information you'd like to promote, feel free to add links in the [dedicated wiki page on Github](https://github.com/traefik/traefik/wiki/Awesome-Traefik).
|
||||||
|
@@ -16,6 +16,8 @@ For changes to its dependencies, the `dep` dependency management tool is require
|
|||||||
Run make with the `binary` target.
|
Run make with the `binary` target.
|
||||||
This will create binaries for the Linux platform in the `dist` folder.
|
This will create binaries for the Linux platform in the `dist` folder.
|
||||||
|
|
||||||
|
In case when you run build on CI, you may probably want to run docker in non-interactive mode. To achieve that define `DOCKER_NON_INTERACTIVE=true` environment variable.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ make binary
|
$ make binary
|
||||||
docker build -t traefik-webui -f webui/Dockerfile webui
|
docker build -t traefik-webui -f webui/Dockerfile webui
|
||||||
@@ -28,12 +30,12 @@ Successfully tagged traefik-webui:latest
|
|||||||
[...]
|
[...]
|
||||||
docker build -t "traefik-dev:4475--feature-documentation" -f build.Dockerfile .
|
docker build -t "traefik-dev:4475--feature-documentation" -f build.Dockerfile .
|
||||||
Sending build context to Docker daemon 279MB
|
Sending build context to Docker daemon 279MB
|
||||||
Step 1/10 : FROM golang:1.13-alpine
|
Step 1/10 : FROM golang:1.14-alpine
|
||||||
---> f4bfb3d22bda
|
---> f4bfb3d22bda
|
||||||
[...]
|
[...]
|
||||||
Successfully built 5c3c1a911277
|
Successfully built 5c3c1a911277
|
||||||
Successfully tagged traefik-dev:4475--feature-documentation
|
Successfully tagged traefik-dev:4475--feature-documentation
|
||||||
docker run -e "TEST_CONTAINER=1" -v "/var/run/docker.sock:/var/run/docker.sock" -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -e VERBOSE -e VERSION -e CODENAME -e TESTDIRS -e CI -e CONTAINER=DOCKER -v "/home/ldez/sources/go/src/github.com/containous/traefik/"dist":/go/src/github.com/containous/traefik/"dist"" "traefik-dev:4475--feature-documentation" ./script/make.sh generate binary
|
docker run -e "TEST_CONTAINER=1" -v "/var/run/docker.sock:/var/run/docker.sock" -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -e VERBOSE -e VERSION -e CODENAME -e TESTDIRS -e CI -e CONTAINER=DOCKER -v "/home/ldez/sources/go/src/github.com/traefik/traefik/"dist":/go/src/github.com/traefik/traefik/"dist"" "traefik-dev:4475--feature-documentation" ./script/make.sh generate binary
|
||||||
---> Making bundle: generate (in .)
|
---> Making bundle: generate (in .)
|
||||||
removed 'autogen/genstatic/gen.go'
|
removed 'autogen/genstatic/gen.go'
|
||||||
|
|
||||||
@@ -60,12 +62,13 @@ PRE_TARGET= make test-unit
|
|||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|
||||||
- `go` v1.13+
|
- `go` v1.14+
|
||||||
- environment variable `GO111MODULE=on`
|
- environment variable `GO111MODULE=on`
|
||||||
|
- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
||||||
|
|
||||||
!!! tip "Source Directory"
|
!!! tip "Source Directory"
|
||||||
|
|
||||||
It is recommended that you clone Traefik into the `~/go/src/github.com/containous/traefik` directory.
|
It is recommended that you clone Traefik into the `~/go/src/github.com/traefik/traefik` directory.
|
||||||
This is the official golang workspace hierarchy that will allow dependencies to be properly resolved.
|
This is the official golang workspace hierarchy that will allow dependencies to be properly resolved.
|
||||||
|
|
||||||
!!! note "Environment"
|
!!! note "Environment"
|
||||||
@@ -97,29 +100,31 @@ Requirements:
|
|||||||
#### Build Traefik
|
#### Build Traefik
|
||||||
|
|
||||||
Once you've set up your go environment and cloned the source repository, you can build Traefik.
|
Once you've set up your go environment and cloned the source repository, you can build Traefik.
|
||||||
Beforehand, you need to get `go-bindata` (the first time) in order to be able to use the `go generate` command (which is part of the build process).
|
|
||||||
|
Beforehand, you need to get [go-bindata](https://github.com/containous/go-bindata) (the first time) in order to be able to use the `go generate` command (which is part of the build process).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/go/src/github.com/containous/traefik
|
cd ~/go/src/github.com/traefik/traefik
|
||||||
|
|
||||||
# Get go-bindata. (Important: the ellipses are required.)
|
# Get go-bindata. (Important: the ellipses are required.)
|
||||||
GO111MODULE=off go get github.com/containous/go-bindata/...
|
GO111MODULE=off go get github.com/containous/go-bindata/...
|
||||||
|
```
|
||||||
|
|
||||||
# Let's build
|
```bash
|
||||||
|
# Generate UI static files
|
||||||
|
rm -rf static/ autogen/; make generate-webui
|
||||||
|
|
||||||
# generate
|
# required to merge non-code components into the final binary,
|
||||||
# (required to merge non-code components into the final binary, such as the web dashboard and the provider's templates)
|
# such as the web dashboard/UI
|
||||||
go generate
|
go generate
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
# Standard go build
|
# Standard go build
|
||||||
go build ./cmd/traefik
|
go build ./cmd/traefik
|
||||||
```
|
```
|
||||||
|
|
||||||
You will find the Traefik executable (`traefik`) in the `~/go/src/github.com/containous/traefik` directory.
|
You will find the Traefik executable (`traefik`) in the `~/go/src/github.com/traefik/traefik` directory.
|
||||||
|
|
||||||
### Updating the templates
|
|
||||||
|
|
||||||
If you happen to update the provider's templates (located in `/templates`), you must run `go generate` to update the `autogen` package.
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
@@ -133,13 +138,13 @@ Run all tests (unit and integration) using the `test` target.
|
|||||||
$ make test-unit
|
$ make test-unit
|
||||||
docker build -t "traefik-dev:your-feature-branch" -f build.Dockerfile .
|
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 .)
|
---> Making bundle: generate (in .)
|
||||||
removed 'gen.go'
|
removed 'gen.go'
|
||||||
|
|
||||||
---> Making bundle: test-unit (in .)
|
---> Making bundle: test-unit (in .)
|
||||||
+ go test -cover -coverprofile=cover.out .
|
+ 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
|
Test success
|
||||||
```
|
```
|
||||||
@@ -167,7 +172,7 @@ More: https://labix.org/gocheck
|
|||||||
Unit tests can be run from the cloned directory using `$ go test ./...` which should return `ok`, similar to:
|
Unit tests can be run from the cloned directory using `$ go test ./...` which should return `ok`, similar to:
|
||||||
|
|
||||||
```test
|
```test
|
||||||
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: `$ cd integration && go test -integration ./...`.
|
Integration tests must be run from the `integration/` directory and require the `-integration` switch: `$ cd integration && go test -integration ./...`.
|
||||||
|
@@ -29,7 +29,7 @@ For this very reason, the sendAnonymousUsage option is mandatory: we want you to
|
|||||||
|
|
||||||
## Collected Data
|
## Collected Data
|
||||||
|
|
||||||
This feature comes from the public proposal [here](https://github.com/containous/traefik/issues/2369).
|
This feature comes from the public proposal [here](https://github.com/traefik/traefik/issues/2369).
|
||||||
|
|
||||||
In order to help us learn more about how Traefik is being used and improve it, we collect anonymous usage statistics from running instances.
|
In order to help us learn more about how Traefik is being used and improve it, we collect anonymous usage statistics from running instances.
|
||||||
Those data help us prioritize our developments and focus on what's important for our users (for example, which provider is popular, and which is not).
|
Those data help us prioritize our developments and focus on what's important for our users (for example, which provider is popular, and which is not).
|
||||||
@@ -85,11 +85,11 @@ Once a day (the first call begins 10 minutes after the start of Traefik), we col
|
|||||||
ca = "xxxx"
|
ca = "xxxx"
|
||||||
cert = "xxxx"
|
cert = "xxxx"
|
||||||
key = "xxxx"
|
key = "xxxx"
|
||||||
insecureSkipVerify = false
|
insecureSkipVerify = true
|
||||||
```
|
```
|
||||||
|
|
||||||
## The Code for Data Collection
|
## The Code for Data Collection
|
||||||
|
|
||||||
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/pkg/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/master/pkg/collector/collector.go)
|
||||||
|
|
||||||
By default we anonymize all configuration fields, except fields tagged with `export=true`.
|
By default we anonymize all configuration fields, except fields tagged with `export=true`.
|
||||||
|
@@ -10,7 +10,7 @@ Let's see how.
|
|||||||
|
|
||||||
### General
|
### General
|
||||||
|
|
||||||
This [documentation](https://docs.traefik.io/) is built with [mkdocs](https://mkdocs.org/).
|
This [documentation](https://doc.traefik.io/traefik/) is built with [mkdocs](https://mkdocs.org/).
|
||||||
|
|
||||||
### Method 1: `Docker` and `make`
|
### Method 1: `Docker` and `make`
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ You can build the documentation and test it locally (with live reloading), using
|
|||||||
$ make docs
|
$ make docs
|
||||||
docker build -t traefik-docs -f docs.Dockerfile .
|
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 server:283] Serving on http://0.0.0.0:8000
|
||||||
[I 170828 20:47:48 handlers:60] Start watching changes
|
[I 170828 20:47:48 handlers:60] Start watching changes
|
||||||
@@ -75,7 +75,7 @@ To check that the documentation meets standard expectations (no dead links, html
|
|||||||
$ make docs-verify
|
$ make docs-verify
|
||||||
docker build -t traefik-docs-verify ./script/docs-verify-docker-image ## Build Validator image
|
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...
|
=== Checking HTML content...
|
||||||
Running ["HtmlCheck", "ImageCheck", "ScriptCheck", "LinkCheck"] on /app/site/basics/index.html on *.html...
|
Running ["HtmlCheck", "ImageCheck", "ScriptCheck", "LinkCheck"] on /app/site/basics/index.html on *.html...
|
||||||
```
|
```
|
||||||
|
@@ -15,12 +15,12 @@
|
|||||||
* Michaël Matur [@mmatur](https://github.com/mmatur)
|
* Michaël Matur [@mmatur](https://github.com/mmatur)
|
||||||
* Gérald Croës [@geraldcroes](https://github.com/geraldcroes)
|
* Gérald Croës [@geraldcroes](https://github.com/geraldcroes)
|
||||||
* Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou)
|
* Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou)
|
||||||
* Damien Duportal [@dduportal](https://github.com/dduportal)
|
|
||||||
* Mathieu Lonjaret [@mpl](https://github.com/mpl)
|
* Mathieu Lonjaret [@mpl](https://github.com/mpl)
|
||||||
|
* Romain Tribotté [@rtribotte](https://github.com/rtribotte)
|
||||||
|
|
||||||
## Contributions Daily Meeting
|
## Contributions Daily Meeting
|
||||||
|
|
||||||
* 3 Maintainers should attend to a Contributions Daily Meeting where we sort and label new issues ([is:issue label:status/0-needs-triage](https://github.com/containous/traefik/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Astatus%2F0-needs-triage+)), and review every Pull Requests
|
* 3 Maintainers should attend to a Contributions Daily Meeting where we sort and label new issues ([is:issue label:status/0-needs-triage](https://github.com/traefik/traefik/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Astatus%2F0-needs-triage+)), and review every Pull Requests
|
||||||
* Every pull request should be checked during the Contributions Daily Meeting
|
* Every pull request should be checked during the Contributions Daily Meeting
|
||||||
* Even if it’s already assigned
|
* Even if it’s already assigned
|
||||||
* Even PR labelled with `contributor/waiting-for-corrections` or `contributor/waiting-for-feedback`
|
* Even PR labelled with `contributor/waiting-for-corrections` or `contributor/waiting-for-feedback`
|
||||||
@@ -43,7 +43,7 @@ We use [PRM](https://github.com/ldez/prm) to manage locally pull requests.
|
|||||||
|
|
||||||
## Bots
|
## Bots
|
||||||
|
|
||||||
### [Myrmica Lobicornis](https://github.com/containous/lobicornis/)
|
### [Myrmica Lobicornis](https://github.com/traefik/lobicornis/)
|
||||||
|
|
||||||
Update and Merge Pull Request.
|
Update and Merge Pull Request.
|
||||||
|
|
||||||
@@ -67,12 +67,12 @@ This label is used when:
|
|||||||
* Merging branches into the master
|
* Merging branches into the master
|
||||||
* Preparing the release
|
* Preparing the release
|
||||||
|
|
||||||
### [Myrmica Bibikoffi](https://github.com/containous/bibikoffi/)
|
### [Myrmica Bibikoffi](https://github.com/traefik/bibikoffi/)
|
||||||
|
|
||||||
* closes stale issues [cron]
|
* closes stale issues [cron]
|
||||||
* use some criterion as number of days between creation, last update, labels, ...
|
* 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.
|
Manage GitHub labels.
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
Help Us Help You!
|
Help Us Help You!
|
||||||
{: .subtitle }
|
{: .subtitle }
|
||||||
|
|
||||||
We use the [GitHub issue tracker](https://github.com/containous/traefik/issues) to keep track of issues in Traefik.
|
We use the [GitHub issue tracker](https://github.com/traefik/traefik/issues) to keep track of issues in Traefik.
|
||||||
|
|
||||||
The process of sorting and checking the issues is a daunting task, and requires a lot of work (more than an hour a day ... just for sorting).
|
The process of sorting and checking the issues is a daunting task, and requires a lot of work (more than an hour a day ... just for sorting).
|
||||||
To save us some time and get quicker feedback, be sure to follow the guide lines below.
|
To save us some time and get quicker feedback, be sure to follow the guide lines below.
|
||||||
@@ -14,7 +14,7 @@ To save us some time and get quicker feedback, be sure to follow the guide lines
|
|||||||
|
|
||||||
For end-user related support questions, try using first:
|
For end-user related support questions, try using first:
|
||||||
|
|
||||||
- the Traefik community forum: [](https://community.containo.us/)
|
- the Traefik community forum: [](https://community.traefik.io/)
|
||||||
|
|
||||||
## Issue Title
|
## Issue Title
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ The title must be short and descriptive. (~60 characters)
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Follow the [issue template](https://github.com/containous/traefik/blob/master/.github/ISSUE_TEMPLATE.md) as much as possible.
|
Follow the [issue template](https://github.com/traefik/traefik/blob/master/.github/ISSUE_TEMPLATE.md) as much as possible.
|
||||||
|
|
||||||
Explain us in which conditions you encountered the issue, what is your context.
|
Explain us in which conditions you encountered the issue, what is your context.
|
||||||
|
|
||||||
|
@@ -3,11 +3,11 @@
|
|||||||
A Quick Guide for Efficient Contributions
|
A Quick Guide for Efficient Contributions
|
||||||
{: .subtitle }
|
{: .subtitle }
|
||||||
|
|
||||||
So you've decide to improve Traefik?
|
So you've decided to improve Traefik?
|
||||||
Thank You!
|
Thank You!
|
||||||
Now the last step is to submit your Pull Request in a way that makes sure it gets the attention it deserves.
|
Now the last step is to submit your Pull Request in a way that makes sure it gets the attention it deserves.
|
||||||
|
|
||||||
Let's go though the classic pitfalls to make sure everything is right.
|
Let's go through the classic pitfalls to make sure everything is right.
|
||||||
|
|
||||||
## Title
|
## Title
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ The title must be short and descriptive. (~60 characters)
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Follow the [pull request template](https://github.com/containous/traefik/blob/master/.github/PULL_REQUEST_TEMPLATE.md) as much as possible.
|
Follow the [pull request template](https://github.com/traefik/traefik/blob/master/.github/PULL_REQUEST_TEMPLATE.md) as much as possible.
|
||||||
|
|
||||||
Explain the conditions which led you to write this PR: give us context.
|
Explain the conditions which led you to write this PR: give us context.
|
||||||
The context should lead to something, an idea or a problem that you’re facing.
|
The context should lead to something, an idea or a problem that you’re facing.
|
||||||
@@ -36,7 +36,7 @@ Help the readers focus on what matters, and help them understand the structure o
|
|||||||
- Add tests.
|
- Add tests.
|
||||||
- Address review comments in terms of additional commits (and don't amend/squash existing ones unless the PR is trivial).
|
- Address review comments in terms of additional commits (and don't amend/squash existing ones unless the PR is trivial).
|
||||||
|
|
||||||
!!! note "third-party dependencies"
|
!!! note "Third-Party Dependencies"
|
||||||
|
|
||||||
If a PR involves changes to third-party dependencies, the commits pertaining to the vendor folder and the manifest/lock file(s) should be committed separated.
|
If a PR involves changes to third-party dependencies, the commits pertaining to the vendor folder and the manifest/lock file(s) should be committed separated.
|
||||||
|
|
||||||
|
16
docs/content/contributing/submitting-security-issues.md
Normal file
16
docs/content/contributing/submitting-security-issues.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Security
|
||||||
|
|
||||||
|
## Security Advisories
|
||||||
|
|
||||||
|
We strongly advise you to join our mailing list to be aware of the latest announcements from our security team.
|
||||||
|
You can subscribe sending a mail to security+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/security).
|
||||||
|
|
||||||
|
## CVE
|
||||||
|
|
||||||
|
Reported vulnerabilities can be found on
|
||||||
|
[cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik).
|
||||||
|
|
||||||
|
## Report a Vulnerability
|
||||||
|
|
||||||
|
We want to keep Traefik safe for everyone.
|
||||||
|
If you've discovered a security vulnerability in Traefik, we appreciate your help in disclosing it to us in a responsible manner, using [this form](https://security.traefik.io).
|
@@ -3,8 +3,8 @@
|
|||||||
_You_ Made It
|
_You_ Made It
|
||||||
{: .subtitle}
|
{: .subtitle}
|
||||||
|
|
||||||
Traefik truly is an [open-source project](https://github.com/containous/traefik/),
|
Traefik truly is an [open-source project](https://github.com/traefik/traefik/),
|
||||||
and wouldn't have become what it is today without the help of our [many contributors](https://github.com/containous/traefik/graphs/contributors) (at the time of writing this),
|
and wouldn't have become what it is today without the help of our [many contributors](https://github.com/traefik/traefik/graphs/contributors) (at the time of writing this),
|
||||||
not accounting for people having helped with issues, tests, comments, articles, ... or just enjoying it and letting others know.
|
not accounting for people having helped with issues, tests, comments, articles, ... or just enjoying it and letting others know.
|
||||||
|
|
||||||
So once again, thank you for your invaluable help on making Traefik such a good product.
|
So once again, thank you for your invaluable help on making Traefik such a good product.
|
||||||
|
@@ -74,7 +74,7 @@ traefik --help
|
|||||||
# or
|
# or
|
||||||
|
|
||||||
docker run traefik[:version] --help
|
docker run traefik[:version] --help
|
||||||
# ex: docker run traefik:2.0 --help
|
# ex: docker run traefik:2.1 --help
|
||||||
```
|
```
|
||||||
|
|
||||||
All available arguments can also be found [here](../reference/static-configuration/cli.md).
|
All available arguments can also be found [here](../reference/static-configuration/cli.md).
|
||||||
|
@@ -3,16 +3,20 @@
|
|||||||
You can install Traefik with the following flavors:
|
You can install Traefik with the following flavors:
|
||||||
|
|
||||||
* [Use the official Docker image](./#use-the-official-docker-image)
|
* [Use the official Docker image](./#use-the-official-docker-image)
|
||||||
|
* [Use the Helm Chart](./#use-the-helm-chart)
|
||||||
* [Use the binary distribution](./#use-the-binary-distribution)
|
* [Use the binary distribution](./#use-the-binary-distribution)
|
||||||
* [Compile your binary from the sources](./#compile-your-binary-from-the-sources)
|
* [Compile your binary from the sources](./#compile-your-binary-from-the-sources)
|
||||||
|
|
||||||
## Use the Official Docker Image
|
## Use the Official Docker Image
|
||||||
|
|
||||||
Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with the [sample configuration file](https://raw.githubusercontent.com/containous/traefik/v2.0/traefik.sample.toml):
|
Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with one sample configuration file:
|
||||||
|
|
||||||
|
* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.toml)
|
||||||
|
* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.yml)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d -p 8080:8080 -p 80:80 \
|
docker run -d -p 8080:8080 -p 80:80 \
|
||||||
-v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik:v2.0
|
-v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik:v2.3
|
||||||
```
|
```
|
||||||
|
|
||||||
For more details, go to the [Docker provider documentation](../providers/docker.md)
|
For more details, go to the [Docker provider documentation](../providers/docker.md)
|
||||||
@@ -20,13 +24,114 @@ For more details, go to the [Docker provider documentation](../providers/docker.
|
|||||||
!!! tip
|
!!! tip
|
||||||
|
|
||||||
* Prefer a fixed version than the latest that could be an unexpected version.
|
* Prefer a fixed version than the latest that could be an unexpected version.
|
||||||
ex: `traefik:v2.0.0`
|
ex: `traefik:v2.1.4`
|
||||||
* Docker images are based from the [Alpine Linux Official image](https://hub.docker.com/_/alpine).
|
* Docker images are based from the [Alpine Linux Official image](https://hub.docker.com/_/alpine).
|
||||||
* All the orchestrator using docker images could fetch the official Traefik docker image.
|
* Any orchestrator using docker images can fetch the official Traefik docker image.
|
||||||
|
|
||||||
|
## Use the Helm Chart
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
|
||||||
|
The Traefik Chart from
|
||||||
|
[Helm's default charts repository](https://github.com/helm/charts/tree/master/stable/traefik) is still using [Traefik v1.7](https://doc.traefik.io/traefik/v1.7).
|
||||||
|
|
||||||
|
Traefik can be installed in Kubernetes using the Helm chart from <https://github.com/traefik/traefik-helm-chart>.
|
||||||
|
|
||||||
|
Ensure that the following requirements are met:
|
||||||
|
|
||||||
|
* Kubernetes 1.14+
|
||||||
|
* Helm version 3.x is [installed](https://helm.sh/docs/intro/install/)
|
||||||
|
|
||||||
|
Add Traefik's chart repository to Helm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm repo add traefik https://helm.traefik.io/traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
You can update the chart repository by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm repo update
|
||||||
|
```
|
||||||
|
|
||||||
|
And install it with the `helm` command line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm install traefik traefik/traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tip "Helm Features"
|
||||||
|
|
||||||
|
All [Helm features](https://helm.sh/docs/intro/using_helm/) are supported.
|
||||||
|
For instance, installing the chart in a dedicated namespace:
|
||||||
|
|
||||||
|
```bash tab="Install in a Dedicated Namespace"
|
||||||
|
kubectl create ns traefik-v2
|
||||||
|
# Install in the namespace "traefik-v2"
|
||||||
|
helm install --namespace=traefik-v2 \
|
||||||
|
traefik traefik/traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
??? example "Installing with Custom Values"
|
||||||
|
|
||||||
|
You can customize the installation by specifying custom values,
|
||||||
|
as with [any helm chart](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing).
|
||||||
|
{: #helm-custom-values }
|
||||||
|
|
||||||
|
The values are not (yet) documented, but are self-explanatory:
|
||||||
|
you can look at the [default `values.yaml`](https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml) file to explore possibilities.
|
||||||
|
|
||||||
|
You can also set Traefik command line flags using `additionalArguments`.
|
||||||
|
Example of installation with logging set to `DEBUG`:
|
||||||
|
|
||||||
|
```bash tab="Using Helm CLI"
|
||||||
|
helm install --namespace=traefik-v2 \
|
||||||
|
--set="additionalArguments={--log.level=DEBUG}" \
|
||||||
|
traefik traefik/traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
```yml tab="With a custom values file"
|
||||||
|
# File custom-values.yml
|
||||||
|
## Install with "helm install --values=./custom-values.yml traefik traefik/traefik
|
||||||
|
additionalArguments:
|
||||||
|
- "--log.level=DEBUG"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exposing the Traefik dashboard
|
||||||
|
|
||||||
|
This HelmChart does not expose the Traefik dashboard by default, for security concerns.
|
||||||
|
Thus, there are multiple ways to expose the dashboard.
|
||||||
|
For instance, the dashboard access could be achieved through a port-forward :
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000
|
||||||
|
```
|
||||||
|
|
||||||
|
Accessible with the url: http://127.0.0.1:9000/dashboard/
|
||||||
|
|
||||||
|
Another way would be to apply your own configuration, for instance,
|
||||||
|
by defining and applying an IngressRoute CRD (`kubectl apply -f dashboard.yaml`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# dashboard.yaml
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: dashboard
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- web
|
||||||
|
routes:
|
||||||
|
- match: Host(`traefik.localhost`) && (PathPrefix(`/dashboard`) || PathPrefix(`/api`))
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: api@internal
|
||||||
|
kind: TraefikService
|
||||||
|
```
|
||||||
|
|
||||||
## Use the Binary Distribution
|
## Use the Binary Distribution
|
||||||
|
|
||||||
Grab the latest binary from the [releases](https://github.com/containous/traefik/releases) page.
|
Grab the latest binary from the [releases](https://github.com/traefik/traefik/releases) page.
|
||||||
|
|
||||||
??? info "Check the integrity of the downloaded file"
|
??? info "Check the integrity of the downloaded file"
|
||||||
|
|
||||||
|
@@ -14,8 +14,8 @@ version: '3'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
reverse-proxy:
|
reverse-proxy:
|
||||||
# The official v2.0 Traefik docker image
|
# The official v2 Traefik docker image
|
||||||
image: traefik:v2.0
|
image: traefik:v2.3
|
||||||
# Enables the web UI and tells Traefik to listen to docker
|
# Enables the web UI and tells Traefik to listen to docker
|
||||||
command: --api.insecure=true --providers.docker
|
command: --api.insecure=true --providers.docker
|
||||||
ports:
|
ports:
|
||||||
@@ -48,7 +48,7 @@ Edit your `docker-compose.yml` file and add the following at the end of your fil
|
|||||||
# ...
|
# ...
|
||||||
whoami:
|
whoami:
|
||||||
# A container that exposes an API to show its IP address
|
# A container that exposes an API to show its IP address
|
||||||
image: containous/whoami
|
image: traefik/whoami
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
|
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
|
||||||
```
|
```
|
||||||
|
@@ -12,7 +12,7 @@ Where Every Technical Word finds its Definition`
|
|||||||
- [ ] [Static configuration](getting-started/configuration-overview.md#the-static-configuration)
|
- [ ] [Static configuration](getting-started/configuration-overview.md#the-static-configuration)
|
||||||
- [ ] [Dynamic configuration](getting-started/configuration-overview.md#the-dynamic-configuration)
|
- [ ] [Dynamic configuration](getting-started/configuration-overview.md#the-dynamic-configuration)
|
||||||
- [ ] ACME
|
- [ ] ACME
|
||||||
- [ ] TraefikEE
|
- [ ] Traefik Enterprise
|
||||||
- [ ] Tracing
|
- [ ] Tracing
|
||||||
- [ ] Metrics
|
- [ ] Metrics
|
||||||
- [ ] Orchestrator
|
- [ ] Orchestrator
|
||||||
|
4
docs/content/https/.markdownlint.json
Normal file
4
docs/content/https/.markdownlint.json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../.markdownlint.json",
|
||||||
|
"MD041": false
|
||||||
|
}
|
@@ -8,53 +8,20 @@ You can configure Traefik to use an ACME provider (like Let's Encrypt) for autom
|
|||||||
!!! warning "Let's Encrypt and Rate Limiting"
|
!!! warning "Let's Encrypt and Rate Limiting"
|
||||||
Note that Let's Encrypt API has [rate limiting](https://letsencrypt.org/docs/rate-limits).
|
Note that Let's Encrypt API has [rate limiting](https://letsencrypt.org/docs/rate-limits).
|
||||||
|
|
||||||
## Configuration Examples
|
Use Let's Encrypt staging server with the [`caServer`](#caserver) configuration option
|
||||||
|
when experimenting to avoid hitting this limit too fast.
|
||||||
|
|
||||||
|
## Certificate Resolvers
|
||||||
|
|
||||||
??? example "Enabling ACME"
|
Traefik requires you to define "Certificate Resolvers" in the [static configuration](../getting-started/configuration-overview.md#the-static-configuration),
|
||||||
|
which are responsible for retrieving certificates from an ACME server.
|
||||||
```toml tab="File (TOML)"
|
|
||||||
[entryPoints]
|
Then, each ["router"](../routing/routers/index.md) is configured to enable TLS,
|
||||||
[entryPoints.web]
|
and is associated to a certificate resolver through the [`tls.certresolver` configuration option](../routing/routers/index.md#certresolver).
|
||||||
address = ":80"
|
|
||||||
|
Certificates are requested for domain names retrieved from the router's [dynamic configuration](../getting-started/configuration-overview.md#the-dynamic-configuration).
|
||||||
[entryPoints.web-secure]
|
|
||||||
address = ":443"
|
You can read more about this retrieval mechanism in the following section: [ACME Domain Definition](#domain-definition).
|
||||||
|
|
||||||
[certificatesResolvers.sample.acme]
|
|
||||||
email = "your-email@your-domain.org"
|
|
||||||
storage = "acme.json"
|
|
||||||
[certificatesResolvers.sample.acme.httpChallenge]
|
|
||||||
# used during the challenge
|
|
||||||
entryPoint = "web"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
|
||||||
entryPoints:
|
|
||||||
web:
|
|
||||||
address: ":80"
|
|
||||||
|
|
||||||
web-secure:
|
|
||||||
address: ":443"
|
|
||||||
|
|
||||||
certificatesResolvers:
|
|
||||||
sample:
|
|
||||||
acme:
|
|
||||||
email: your-email@your-domain.org
|
|
||||||
storage: acme.json
|
|
||||||
httpChallenge:
|
|
||||||
# used during the challenge
|
|
||||||
entryPoint: web
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash tab="CLI"
|
|
||||||
--entryPoints.web.address=":80"
|
|
||||||
--entryPoints.websecure.address=":443"
|
|
||||||
# ...
|
|
||||||
--certificatesResolvers.sample.acme.email="your-email@your-domain.org"
|
|
||||||
--certificatesResolvers.sample.acme.storage="acme.json"
|
|
||||||
# used during the challenge
|
|
||||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint=web
|
|
||||||
```
|
|
||||||
|
|
||||||
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
|
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
|
||||||
|
|
||||||
@@ -75,6 +42,100 @@ You can configure Traefik to use an ACME provider (like Let's Encrypt) for autom
|
|||||||
--8<-- "content/https/ref-acme.txt"
|
--8<-- "content/https/ref-acme.txt"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Domain Definition
|
||||||
|
|
||||||
|
Certificate resolvers request certificates for a set of the domain names
|
||||||
|
inferred from routers, with the following logic:
|
||||||
|
|
||||||
|
- If the router has a [`tls.domains`](../routing/routers/index.md#domains) option set,
|
||||||
|
then the certificate resolver uses the `main` (and optionally `sans`) option of `tls.domains` to know the domain names for this router.
|
||||||
|
|
||||||
|
- If no [`tls.domains`](../routing/routers/index.md#domains) option is set,
|
||||||
|
then the certificate resolver uses the [router's rule](../routing/routers/index.md#rule),
|
||||||
|
by checking the `Host()` matchers.
|
||||||
|
Please note that [multiple `Host()` matchers can be used](../routing/routers/index.md#certresolver)) for specifying multiple domain names for this router.
|
||||||
|
|
||||||
|
Please note that:
|
||||||
|
|
||||||
|
- When multiple domain names are inferred from a given router,
|
||||||
|
only **one** certificate is requested with the first domain name as the main domain,
|
||||||
|
and the other domains as ["SANs" (Subject Alternative Name)](https://en.wikipedia.org/wiki/Subject_Alternative_Name).
|
||||||
|
|
||||||
|
- As [ACME V2 supports "wildcard domains"](#wildcard-domains),
|
||||||
|
any router can provide a [wildcard domain](https://en.wikipedia.org/wiki/Wildcard_certificate) name, as "main" domain or as "SAN" domain.
|
||||||
|
|
||||||
|
Please check the [configuration examples below](#configuration-examples) for more details.
|
||||||
|
|
||||||
|
## Configuration Examples
|
||||||
|
|
||||||
|
??? example "Enabling ACME"
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.websecure]
|
||||||
|
address = ":443"
|
||||||
|
|
||||||
|
[certificatesResolvers.myresolver.acme]
|
||||||
|
email = "your-email@example.com"
|
||||||
|
storage = "acme.json"
|
||||||
|
[certificatesResolvers.myresolver.acme.httpChallenge]
|
||||||
|
# used during the challenge
|
||||||
|
entryPoint = "web"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
|
|
||||||
|
certificatesResolvers:
|
||||||
|
myresolver:
|
||||||
|
acme:
|
||||||
|
email: your-email@example.com
|
||||||
|
storage: acme.json
|
||||||
|
httpChallenge:
|
||||||
|
# used during the challenge
|
||||||
|
entryPoint: web
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--entrypoints.web.address=:80
|
||||||
|
--entrypoints.websecure.address=:443
|
||||||
|
# ...
|
||||||
|
--certificatesresolvers.myresolver.acme.email=your-email@example.com
|
||||||
|
--certificatesresolvers.myresolver.acme.storage=acme.json
|
||||||
|
# used during the challenge
|
||||||
|
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
|
||||||
|
|
||||||
|
??? example "Single Domain from Router's Rule Example"
|
||||||
|
|
||||||
|
* A certificate for the domain `example.com` is requested:
|
||||||
|
|
||||||
|
--8<-- "content/https/include-acme-single-domain-example.md"
|
||||||
|
|
||||||
|
??? example "Multiple Domains from Router's Rule Example"
|
||||||
|
|
||||||
|
* A certificate for the domains `example.com` (main) and `blog.example.org`
|
||||||
|
is requested:
|
||||||
|
|
||||||
|
--8<-- "content/https/include-acme-multiple-domains-from-rule-example.md"
|
||||||
|
|
||||||
|
??? example "Multiple Domains from Router's `tls.domain` Example"
|
||||||
|
|
||||||
|
* A certificate for the domains `example.com` (main) and `*.example.org` (SAN)
|
||||||
|
is requested:
|
||||||
|
|
||||||
|
--8<-- "content/https/include-acme-multiple-domains-example.md"
|
||||||
|
|
||||||
## Automatic Renewals
|
## Automatic Renewals
|
||||||
|
|
||||||
Traefik automatically tracks the expiry date of ACME certificates it generates.
|
Traefik automatically tracks the expiry date of ACME certificates it generates.
|
||||||
@@ -84,6 +145,13 @@ If there are less than 30 days remaining before the certificate expires, Traefik
|
|||||||
!!! info ""
|
!!! info ""
|
||||||
Certificates that are no longer used may still be renewed, as Traefik does not currently check if the certificate is being used before renewing.
|
Certificates that are no longer used may still be renewed, as Traefik does not currently check if the certificate is being used before renewing.
|
||||||
|
|
||||||
|
## Using LetsEncrypt with Kubernetes
|
||||||
|
|
||||||
|
When using LetsEncrypt with kubernetes, there are some known caveats with both the [ingress](../providers/kubernetes-ingress.md) and [crd](../providers/kubernetes-crd.md) providers.
|
||||||
|
|
||||||
|
!!! info ""
|
||||||
|
If you intend to run multiple instances of Traefik with LetsEncrypt, please ensure you read the sections on those provider pages.
|
||||||
|
|
||||||
## The Different ACME Challenges
|
## The Different ACME Challenges
|
||||||
|
|
||||||
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
|
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
|
||||||
@@ -98,14 +166,14 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
|
|||||||
??? example "Configuring the `tlsChallenge`"
|
??? example "Configuring the `tlsChallenge`"
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
# ...
|
# ...
|
||||||
[certificatesResolvers.sample.acme.tlsChallenge]
|
[certificatesResolvers.myresolver.acme.tlsChallenge]
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
# ...
|
# ...
|
||||||
tlsChallenge: {}
|
tlsChallenge: {}
|
||||||
@@ -113,7 +181,7 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# ...
|
# ...
|
||||||
--certificatesResolvers.sample.acme.tlsChallenge=true
|
--certificatesresolvers.myresolver.acme.tlschallenge=true
|
||||||
```
|
```
|
||||||
|
|
||||||
### `httpChallenge`
|
### `httpChallenge`
|
||||||
@@ -121,21 +189,21 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
|
|||||||
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning an HTTP resource under a well-known URI.
|
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning an HTTP resource under a well-known URI.
|
||||||
|
|
||||||
As described on the Let's Encrypt [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72),
|
As described on the Let's Encrypt [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72),
|
||||||
when using the `HTTP-01` challenge, `certificatesResolvers.sample.acme.httpChallenge.entryPoint` must be reachable by Let's Encrypt through port 80.
|
when using the `HTTP-01` challenge, `certificatesresolvers.myresolver.acme.httpchallenge.entrypoint` must be reachable by Let's Encrypt through port 80.
|
||||||
|
|
||||||
??? example "Using an EntryPoint Called http for the `httpChallenge`"
|
??? example "Using an EntryPoint Called web for the `httpChallenge`"
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[entryPoints]
|
[entryPoints]
|
||||||
[entryPoints.web]
|
[entryPoints.web]
|
||||||
address = ":80"
|
address = ":80"
|
||||||
|
|
||||||
[entryPoints.web-secure]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
|
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
# ...
|
# ...
|
||||||
[certificatesResolvers.sample.acme.httpChallenge]
|
[certificatesResolvers.myresolver.acme.httpChallenge]
|
||||||
entryPoint = "web"
|
entryPoint = "web"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -144,11 +212,11 @@ when using the `HTTP-01` challenge, `certificatesResolvers.sample.acme.httpChall
|
|||||||
web:
|
web:
|
||||||
address: ":80"
|
address: ":80"
|
||||||
|
|
||||||
web-secure:
|
websecure:
|
||||||
address: ":443"
|
address: ":443"
|
||||||
|
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
# ...
|
# ...
|
||||||
httpChallenge:
|
httpChallenge:
|
||||||
@@ -156,10 +224,10 @@ when using the `HTTP-01` challenge, `certificatesResolvers.sample.acme.httpChall
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--entryPoints.web.address=":80"
|
--entrypoints.web.address=:80
|
||||||
--entryPoints.websecure.address=":443"
|
--entrypoints.websecure.address=:443
|
||||||
# ...
|
# ...
|
||||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint=web
|
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info ""
|
!!! info ""
|
||||||
@@ -172,9 +240,9 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
|
|||||||
??? example "Configuring a `dnsChallenge` with the DigitalOcean Provider"
|
??? example "Configuring a `dnsChallenge` with the DigitalOcean Provider"
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
# ...
|
# ...
|
||||||
[certificatesResolvers.sample.acme.dnsChallenge]
|
[certificatesResolvers.myresolver.acme.dnsChallenge]
|
||||||
provider = "digitalocean"
|
provider = "digitalocean"
|
||||||
delayBeforeCheck = 0
|
delayBeforeCheck = 0
|
||||||
# ...
|
# ...
|
||||||
@@ -182,7 +250,7 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
|
|||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
# ...
|
# ...
|
||||||
dnsChallenge:
|
dnsChallenge:
|
||||||
@@ -193,8 +261,8 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# ...
|
# ...
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.provider=digitalocean
|
--certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.delayBeforeCheck=0
|
--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -207,21 +275,29 @@ Here is a list of supported `providers`, that can automate the DNS verification,
|
|||||||
along with the required environment variables and their [wildcard & root domain support](#wildcard-domains).
|
along with the required environment variables and their [wildcard & root domain support](#wildcard-domains).
|
||||||
Do not hesitate to complete it.
|
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.
|
Many lego environment variables 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`.
|
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`.
|
||||||
|
|
||||||
|
For complete details, refer to your provider's _Additional configuration_ link.
|
||||||
|
|
||||||
| Provider Name | Provider Code | Environment Variables | |
|
| Provider Name | Provider Code | Environment Variables | |
|
||||||
|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
|
|-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
|
||||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) |
|
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) |
|
||||||
| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) |
|
| [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) |
|
||||||
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) |
|
| [ArvanCloud](https://www.arvancloud.com/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) |
|
||||||
|
| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) |
|
||||||
|
| [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) |
|
||||||
| [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]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) |
|
| [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]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) |
|
||||||
| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) |
|
| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) |
|
||||||
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) |
|
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) |
|
||||||
|
| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) |
|
||||||
|
| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) |
|
||||||
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) |
|
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) |
|
||||||
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` [^5] | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) |
|
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) |
|
||||||
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
|
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
|
||||||
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) |
|
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) |
|
||||||
|
| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) |
|
||||||
|
| [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) |
|
||||||
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) |
|
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) |
|
||||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) |
|
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) |
|
||||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) |
|
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) |
|
||||||
@@ -230,52 +306,64 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
|
|||||||
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) |
|
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) |
|
||||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) |
|
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) |
|
||||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) |
|
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) |
|
||||||
|
| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) |
|
||||||
| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) |
|
| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) |
|
||||||
|
| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) |
|
||||||
| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) |
|
| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) |
|
||||||
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) |
|
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) |
|
||||||
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/fastdns) |
|
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) |
|
||||||
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) |
|
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandi) |
|
||||||
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) |
|
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/gandiv5) |
|
||||||
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) |
|
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) |
|
||||||
| [GoDaddy](https://godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) |
|
| [GoDaddy](https://godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) |
|
||||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) |
|
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) |
|
||||||
|
| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) |
|
||||||
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) |
|
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) |
|
||||||
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
|
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
|
||||||
|
| [HyperOne](https://www.hyperone.com) | `hyperone` | `HYPERONE_PASSPORT_LOCATION`, `HYPERONE_LOCATION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/hyperone) |
|
||||||
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) |
|
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) |
|
||||||
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) |
|
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) |
|
||||||
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) |
|
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) |
|
||||||
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) |
|
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) |
|
||||||
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) |
|
| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) |
|
||||||
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linodev4) |
|
|
||||||
| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) |
|
| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) |
|
||||||
| manual | - | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press <kbd>Enter</kbd>. | |
|
| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) |
|
||||||
|
| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press <kbd>Enter</kbd>. | |
|
||||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) |
|
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) |
|
||||||
|
| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) |
|
||||||
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) |
|
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) |
|
||||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) |
|
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) |
|
||||||
| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) |
|
| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) |
|
||||||
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) |
|
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) |
|
||||||
|
| [Netlify](https://www.netlify.com) | `netlify` | `NETLIFY_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/netlify) |
|
||||||
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) |
|
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) |
|
||||||
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) |
|
| [NS1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) |
|
||||||
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) |
|
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) |
|
||||||
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) |
|
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ovh) |
|
||||||
| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) |
|
| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/designate) |
|
||||||
| [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` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) |
|
| [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` | [Additional configuration](https://go-acme.github.io/lego/dns/oraclecloud) |
|
||||||
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) |
|
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) |
|
||||||
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) |
|
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) |
|
||||||
|
| [reg.ru](https://www.reg.ru) | `regru` | `REGRU_USERNAME`, `REGRU_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/regru) |
|
||||||
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) |
|
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) |
|
||||||
| [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. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) |
|
| [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. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) |
|
||||||
|
| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) |
|
||||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) |
|
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) |
|
||||||
|
| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCALEWAY_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) |
|
||||||
| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) |
|
| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/selectel) |
|
||||||
|
| [Servercow](https://servercow.de) | `servercow` | `SERVERCOW_USERNAME`, `SERVERCOW_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/servercow) |
|
||||||
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) |
|
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) |
|
||||||
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) |
|
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) |
|
||||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) |
|
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) |
|
||||||
| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) |
|
| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) |
|
||||||
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) |
|
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) |
|
||||||
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) |
|
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) |
|
||||||
|
| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) |
|
||||||
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) |
|
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) |
|
||||||
|
| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) |
|
||||||
|
|
||||||
[^1]: more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/)
|
[^1]: more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/)
|
||||||
[^2]: [providing_credentials_to_your_application](https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application)
|
[^2]: [providing_credentials_to_your_application](https://cloud.google.com/docs/authentication/production)
|
||||||
[^3]: [google/default.go](https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76)
|
[^3]: [google/default.go](https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76)
|
||||||
[^4]: `docker stack` remark: there is no way to support terminal attached to container when deploying with `docker stack`, so you might need to run container with `docker run -it` to generate certificates using `manual` provider.
|
[^4]: `docker stack` remark: there is no way to support terminal attached to container when deploying with `docker stack`, so you might need to run container with `docker run -it` to generate certificates using `manual` provider.
|
||||||
[^5]: The `Global API Key` needs to be used, not the `Origin CA Key`.
|
[^5]: The `Global API Key` needs to be used, not the `Origin CA Key`.
|
||||||
@@ -290,16 +378,16 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
|
|||||||
Use custom DNS servers to resolve the FQDN authority.
|
Use custom DNS servers to resolve the FQDN authority.
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
# ...
|
# ...
|
||||||
[certificatesResolvers.sample.acme.dnsChallenge]
|
[certificatesResolvers.myresolver.acme.dnsChallenge]
|
||||||
# ...
|
# ...
|
||||||
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
|
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
# ...
|
# ...
|
||||||
dnsChallenge:
|
dnsChallenge:
|
||||||
@@ -311,7 +399,7 @@ certificatesResolvers:
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# ...
|
# ...
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.resolvers:="1.1.1.1:53,8.8.8.8:53"
|
--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Wildcard Domains
|
#### Wildcard Domains
|
||||||
@@ -319,12 +407,21 @@ certificatesResolvers:
|
|||||||
[ACME V2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates.
|
[ACME V2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates.
|
||||||
As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605) wildcard certificates can only be generated through a [`DNS-01` challenge](#dnschallenge).
|
As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605) wildcard certificates can only be generated through a [`DNS-01` challenge](#dnschallenge).
|
||||||
|
|
||||||
## `caServer`
|
## More Configuration
|
||||||
|
|
||||||
|
### `caServer`
|
||||||
|
|
||||||
|
_Required, Default="https://acme-v02.api.letsencrypt.org/directory"_
|
||||||
|
|
||||||
|
The CA server to use:
|
||||||
|
|
||||||
|
- Let's Encrypt production server: https://acme-v02.api.letsencrypt.org/directory
|
||||||
|
- Let's Encrypt staging server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
|
||||||
??? example "Using the Let's Encrypt staging server"
|
??? example "Using the Let's Encrypt staging server"
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
# ...
|
# ...
|
||||||
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
# ...
|
# ...
|
||||||
@@ -332,7 +429,7 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
|
|||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
# ...
|
# ...
|
||||||
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
|
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
@@ -341,16 +438,18 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# ...
|
# ...
|
||||||
--certificatesResolvers.sample.acme.caServer="https://acme-staging-v02.api.letsencrypt.org/directory"
|
--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
## `storage`
|
### `storage`
|
||||||
|
|
||||||
|
_Required, Default="acme.json"_
|
||||||
|
|
||||||
The `storage` option sets the location where your ACME certificates are saved to.
|
The `storage` option sets the location where your ACME certificates are saved to.
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
# ...
|
# ...
|
||||||
storage = "acme.json"
|
storage = "acme.json"
|
||||||
# ...
|
# ...
|
||||||
@@ -358,7 +457,7 @@ The `storage` option sets the location where your ACME certificates are saved to
|
|||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
# ...
|
# ...
|
||||||
storage: acme.json
|
storage: acme.json
|
||||||
@@ -367,17 +466,11 @@ certificatesResolvers:
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# ...
|
# ...
|
||||||
--certificatesResolvers.sample.acme.storage=acme.json
|
--certificatesresolvers.myresolver.acme.storage=acme.json
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
The value can refer to some kinds of storage:
|
ACME certificates are stored in a JSON file that needs to have a `600` file mode.
|
||||||
|
|
||||||
- a JSON file
|
|
||||||
|
|
||||||
### In a File
|
|
||||||
|
|
||||||
ACME certificates can be stored in a JSON file that needs to have a `600` file mode .
|
|
||||||
|
|
||||||
In Docker you can mount either the JSON file, or the folder containing it:
|
In Docker you can mount either the JSON file, or the folder containing it:
|
||||||
|
|
||||||
@@ -390,7 +483,66 @@ docker run -v "/my/host/acme:/etc/traefik/acme" traefik
|
|||||||
```
|
```
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
For concurrency reason, this file cannot be shared across multiple instances of Traefik. Use a key value store entry instead.
|
For concurrency reasons, this file cannot be shared across multiple instances of Traefik.
|
||||||
|
|
||||||
|
### `preferredChain`
|
||||||
|
|
||||||
|
_Optional, Default=""_
|
||||||
|
|
||||||
|
Preferred chain to use.
|
||||||
|
|
||||||
|
If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
|
||||||
|
If no match, the default offered chain will be used.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[certificatesResolvers.myresolver.acme]
|
||||||
|
# ...
|
||||||
|
preferredChain = "ISRG Root X1"
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
certificatesResolvers:
|
||||||
|
myresolver:
|
||||||
|
acme:
|
||||||
|
# ...
|
||||||
|
preferredChain: 'ISRG Root X1'
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
# ...
|
||||||
|
--certificatesresolvers.myresolver.acme.preferredChain="ISRG Root X1"
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### `keyType`
|
||||||
|
|
||||||
|
_Optional, Default="RSA4096"_
|
||||||
|
|
||||||
|
KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[certificatesResolvers.myresolver.acme]
|
||||||
|
# ...
|
||||||
|
keyType = "RSA4096"
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
certificatesResolvers:
|
||||||
|
myresolver:
|
||||||
|
acme:
|
||||||
|
# ...
|
||||||
|
keyType: 'RSA4096'
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
# ...
|
||||||
|
--certificatesresolvers.myresolver.acme.keyType="RSA4096"
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
## Fallback
|
## Fallback
|
||||||
|
|
||||||
|
91
docs/content/https/include-acme-multiple-domains-example.md
Normal file
91
docs/content/https/include-acme-multiple-domains-example.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
## Dynamic configuration
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
- traefik.http.routers.blog.tls.domains[0].main=example.org
|
||||||
|
- traefik.http.routers.blog.tls.domains[0].sans=*.example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Docker (Swarm)"
|
||||||
|
## Dynamic configuration
|
||||||
|
deploy:
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
|
||||||
|
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
- traefik.http.routers.blog.tls.domains[0].main=example.org
|
||||||
|
- traefik.http.routers.blog.tls.domains[0].sans=*.example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: blogtls
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`example.com`) && Path(`/blog`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: blog
|
||||||
|
port: 8080
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
domains:
|
||||||
|
- main: example.org
|
||||||
|
sans:
|
||||||
|
- '*.example.org'
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
labels: {
|
||||||
|
"traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)",
|
||||||
|
"traefik.http.routers.blog.tls": "true",
|
||||||
|
"traefik.http.routers.blog.tls.certresolver": "myresolver",
|
||||||
|
"traefik.http.routers.blog.tls.domains[0].main": "example.com",
|
||||||
|
"traefik.http.routers.blog.tls.domains[0].sans": "*.example.com",
|
||||||
|
"traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
## Dynamic configuration
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
- traefik.http.routers.blog.tls.domains[0].main=example.org
|
||||||
|
- traefik.http.routers.blog.tls.domains[0].sans=*.example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.routers]
|
||||||
|
[http.routers.blog]
|
||||||
|
rule = "Host(`example.com`) && Path(`/blog`)"
|
||||||
|
[http.routers.blog.tls]
|
||||||
|
certResolver = "myresolver" # From static configuration
|
||||||
|
[[http.routers.blog.tls.domains]]
|
||||||
|
main = "example.org"
|
||||||
|
sans = ["*.example.org"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
blog:
|
||||||
|
rule: "Host(`example.com`) && Path(`/blog`)"
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
domains:
|
||||||
|
- main: "example.org"
|
||||||
|
sans:
|
||||||
|
- "*.example.org"
|
||||||
|
```
|
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
## Dynamic configuration
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Docker (Swarm)"
|
||||||
|
## Dynamic configuration
|
||||||
|
deploy:
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: blogtls
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: (Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: blog
|
||||||
|
port: 8080
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
labels: {
|
||||||
|
"traefik.http.routers.blog.rule": "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)",
|
||||||
|
"traefik.http.routers.blog.tls": "true",
|
||||||
|
"traefik.http.routers.blog.tls.certresolver": "myresolver",
|
||||||
|
"traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
## Dynamic configuration
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.routers]
|
||||||
|
[http.routers.blog]
|
||||||
|
rule = "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)"
|
||||||
|
[http.routers.blog.tls]
|
||||||
|
certResolver = "myresolver"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
blog:
|
||||||
|
rule: "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)"
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
```
|
72
docs/content/https/include-acme-single-domain-example.md
Normal file
72
docs/content/https/include-acme-single-domain-example.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
## Dynamic configuration
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Docker (Swarm)"
|
||||||
|
## Dynamic configuration
|
||||||
|
deploy:
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: blogtls
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`example.com`) && Path(`/blog`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: blog
|
||||||
|
port: 8080
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
labels: {
|
||||||
|
"traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)",
|
||||||
|
"traefik.http.routers.blog.tls": "true",
|
||||||
|
"traefik.http.routers.blog.tls.certresolver": "myresolver",
|
||||||
|
"traefik.http.services.blog-svc.loadbalancer.server.port": "8080"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
## Dynamic configuration
|
||||||
|
labels:
|
||||||
|
- traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`)
|
||||||
|
- traefik.http.routers.blog.tls=true
|
||||||
|
- traefik.http.routers.blog.tls.certresolver=myresolver
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
[http.routers]
|
||||||
|
[http.routers.blog]
|
||||||
|
rule = "Host(`example.com`) && Path(`/blog`)"
|
||||||
|
[http.routers.blog.tls]
|
||||||
|
certResolver = "myresolver"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
## Dynamic configuration
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
blog:
|
||||||
|
rule: "Host(`example.com`) && Path(`/blog`)"
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
```
|
@@ -1,11 +1,11 @@
|
|||||||
# Enable ACME (Let's Encrypt): automatic SSL.
|
# Enable ACME (Let's Encrypt): automatic SSL.
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
|
|
||||||
# Email address used for registration.
|
# Email address used for registration.
|
||||||
#
|
#
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
email = "test@traefik.io"
|
email = "test@example.com"
|
||||||
|
|
||||||
# File or key used for certificates storage.
|
# File or key used for certificates storage.
|
||||||
#
|
#
|
||||||
@@ -22,6 +22,16 @@
|
|||||||
#
|
#
|
||||||
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
|
|
||||||
|
# Preferred chain to use.
|
||||||
|
#
|
||||||
|
# If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
|
||||||
|
# If no match, the default offered chain will be used.
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
# Default: ""
|
||||||
|
#
|
||||||
|
# preferredChain = "ISRG Root X1"
|
||||||
|
|
||||||
# KeyType to use.
|
# KeyType to use.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
@@ -35,13 +45,13 @@
|
|||||||
#
|
#
|
||||||
# Optional (but recommended)
|
# Optional (but recommended)
|
||||||
#
|
#
|
||||||
[certificatesResolvers.sample.acme.tlsChallenge]
|
[certificatesResolvers.myresolver.acme.tlsChallenge]
|
||||||
|
|
||||||
# Use a HTTP-01 ACME challenge.
|
# Use a HTTP-01 ACME challenge.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
# [certificatesResolvers.sample.acme.httpChallenge]
|
# [certificatesResolvers.myresolver.acme.httpChallenge]
|
||||||
|
|
||||||
# EntryPoint to use for the HTTP-01 challenges.
|
# EntryPoint to use for the HTTP-01 challenges.
|
||||||
#
|
#
|
||||||
@@ -54,7 +64,7 @@
|
|||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
# [certificatesResolvers.sample.acme.dnsChallenge]
|
# [certificatesResolvers.myresolver.acme.dnsChallenge]
|
||||||
|
|
||||||
# DNS provider used.
|
# DNS provider used.
|
||||||
#
|
#
|
||||||
|
@@ -4,13 +4,13 @@
|
|||||||
#
|
#
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.email="test@traefik.io"
|
--certificatesresolvers.myresolver.acme.email=test@example.com
|
||||||
|
|
||||||
# File or key used for certificates storage.
|
# File or key used for certificates storage.
|
||||||
#
|
#
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.storage="acme.json"
|
--certificatesresolvers.myresolver.acme.storage=acme.json
|
||||||
|
|
||||||
# CA server to use.
|
# CA server to use.
|
||||||
# Uncomment the line to use Let's Encrypt's staging server,
|
# Uncomment the line to use Let's Encrypt's staging server,
|
||||||
@@ -19,7 +19,17 @@
|
|||||||
# Optional
|
# Optional
|
||||||
# Default: "https://acme-v02.api.letsencrypt.org/directory"
|
# Default: "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.caServer="https://acme-staging-v02.api.letsencrypt.org/directory"
|
--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
|
||||||
|
# Preferred chain to use.
|
||||||
|
#
|
||||||
|
# If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
|
||||||
|
# If no match, the default offered chain will be used.
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
# Default: ""
|
||||||
|
#
|
||||||
|
--certificatesresolvers.myresolver.acme.preferredchain="ISRG Root X1"
|
||||||
|
|
||||||
# KeyType to use.
|
# KeyType to use.
|
||||||
#
|
#
|
||||||
@@ -28,38 +38,38 @@
|
|||||||
#
|
#
|
||||||
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
|
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.keyType=RSA4096
|
--certificatesresolvers.myresolver.acme.keytype=RSA4096
|
||||||
|
|
||||||
# Use a TLS-ALPN-01 ACME challenge.
|
# Use a TLS-ALPN-01 ACME challenge.
|
||||||
#
|
#
|
||||||
# Optional (but recommended)
|
# Optional (but recommended)
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.tlsChallenge=true
|
--certificatesresolvers.myresolver.acme.tlschallenge=true
|
||||||
|
|
||||||
# Use a HTTP-01 ACME challenge.
|
# Use a HTTP-01 ACME challenge.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.httpChallenge=true
|
--certificatesresolvers.myresolver.acme.httpchallenge=true
|
||||||
|
|
||||||
# EntryPoint to use for the HTTP-01 challenges.
|
# EntryPoint to use for the HTTP-01 challenges.
|
||||||
#
|
#
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint=web
|
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
|
||||||
|
|
||||||
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
|
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
|
||||||
# Note: mandatory for wildcard certificate generation.
|
# Note: mandatory for wildcard certificate generation.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge=true
|
--certificatesresolvers.myresolver.acme.dnschallenge=true
|
||||||
|
|
||||||
# DNS provider used.
|
# DNS provider used.
|
||||||
#
|
#
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.provider=digitalocean
|
--certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
|
||||||
|
|
||||||
# By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
|
# By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
|
||||||
# If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
|
# If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
|
||||||
@@ -68,14 +78,14 @@
|
|||||||
# Optional
|
# Optional
|
||||||
# Default: 0
|
# Default: 0
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.delayBeforeCheck=0
|
--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
|
||||||
|
|
||||||
# Use following DNS servers to resolve the FQDN authority.
|
# Use following DNS servers to resolve the FQDN authority.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
# Default: empty
|
# Default: empty
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.resolvers="1.1.1.1:53,8.8.8.8:53"
|
--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
|
||||||
|
|
||||||
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
|
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
|
||||||
#
|
#
|
||||||
@@ -85,4 +95,4 @@
|
|||||||
# Optional
|
# Optional
|
||||||
# Default: false
|
# Default: false
|
||||||
#
|
#
|
||||||
--certificatesResolvers.sample.acme.dnsChallenge.disablePropagationCheck=true
|
--certificatesresolvers.myresolver.acme.dnschallenge.disablepropagationcheck=true
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
# Enable ACME (Let's Encrypt): automatic SSL.
|
# Enable ACME (Let's Encrypt): automatic SSL.
|
||||||
acme:
|
acme:
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ certificatesResolvers:
|
|||||||
#
|
#
|
||||||
# Required
|
# Required
|
||||||
#
|
#
|
||||||
email: "test@traefik.io"
|
email: "test@example.com"
|
||||||
|
|
||||||
# File or key used for certificates storage.
|
# File or key used for certificates storage.
|
||||||
#
|
#
|
||||||
@@ -24,6 +24,16 @@ certificatesResolvers:
|
|||||||
#
|
#
|
||||||
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
|
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
|
|
||||||
|
# Preferred chain to use.
|
||||||
|
#
|
||||||
|
# If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
|
||||||
|
# If no match, the default offered chain will be used.
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
# Default: ""
|
||||||
|
#
|
||||||
|
# preferredChain: 'ISRG Root X1'
|
||||||
|
|
||||||
# KeyType to use.
|
# KeyType to use.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
|
@@ -40,7 +40,7 @@ tls:
|
|||||||
|
|
||||||
In the above example, we've used the [file provider](../providers/file.md) to handle these definitions.
|
In the above example, we've used the [file provider](../providers/file.md) to handle these definitions.
|
||||||
It is the only available method to configure the certificates (as well as the options and the stores).
|
It is the only available method to configure the certificates (as well as the options and the stores).
|
||||||
However, in [Kubernetes](../providers/kubernetes-crd.md), the certificates can and must be provided by [secrets](../routing/providers/kubernetes-crd.md#tls).
|
However, in [Kubernetes](../providers/kubernetes-crd.md), the certificates can and must be provided by [secrets](https://kubernetes.io/docs/concepts/configuration/secret/).
|
||||||
|
|
||||||
## Certificates Stores
|
## Certificates Stores
|
||||||
|
|
||||||
@@ -134,6 +134,25 @@ If no default certificate is provided, Traefik generates and uses a self-signed
|
|||||||
|
|
||||||
The TLS options allow one to configure some parameters of the TLS connection.
|
The TLS options allow one to configure some parameters of the TLS connection.
|
||||||
|
|
||||||
|
!!! important "'default' TLS Option"
|
||||||
|
|
||||||
|
The `default` option is special.
|
||||||
|
When no tls options are specified in a tls router, the `default` option is used.
|
||||||
|
When specifying the `default` option explicitly, make sure not to specify provider namespace as the `default` option does not have one.
|
||||||
|
Conversely, for cross-provider references, for example, when referencing the file provider from a docker label,
|
||||||
|
you must specify the provider namespace, for example:
|
||||||
|
`traefik.http.routers.myrouter.tls.options=myoptions@file`
|
||||||
|
|
||||||
|
!!! important "TLSOptions in Kubernetes"
|
||||||
|
|
||||||
|
When using the TLSOptions-CRD in Kubernetes, one might setup a default set of options that,
|
||||||
|
if not explicitly overwritten, should apply to all ingresses.
|
||||||
|
To achieve that, you'll have to create a TLSOptions CR with the name `default`.
|
||||||
|
There may exist only one TLSOption with the name `default` (across all namespaces) - otherwise they will be dropped.
|
||||||
|
To explicitly use a different TLSOption (and using the Kubernetes Ingress resources)
|
||||||
|
you'll have to add an annotation to the Ingress in the following form:
|
||||||
|
`traefik.ingress.kubernetes.io/router.tls.options: <resource-namespace>-<resource-name>@kubernetescrd`
|
||||||
|
|
||||||
### Minimum TLS Version
|
### Minimum TLS Version
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
@@ -181,6 +200,57 @@ spec:
|
|||||||
minVersion: VersionTLS13
|
minVersion: VersionTLS13
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Maximum TLS Version
|
||||||
|
|
||||||
|
We discourage the use of this setting to disable TLS1.3.
|
||||||
|
|
||||||
|
The recommended approach is to update the clients to support TLS1.3.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
[tls.options]
|
||||||
|
|
||||||
|
[tls.options.default]
|
||||||
|
maxVersion = "VersionTLS13"
|
||||||
|
|
||||||
|
[tls.options.maxtls12]
|
||||||
|
maxVersion = "VersionTLS12"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
tls:
|
||||||
|
options:
|
||||||
|
default:
|
||||||
|
maxVersion: VersionTLS13
|
||||||
|
|
||||||
|
maxtls12:
|
||||||
|
maxVersion: VersionTLS12
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: TLSOption
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
maxVersion: VersionTLS13
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: TLSOption
|
||||||
|
metadata:
|
||||||
|
name: maxtls12
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
maxVersion: VersionTLS12
|
||||||
|
```
|
||||||
|
|
||||||
### Cipher Suites
|
### Cipher Suites
|
||||||
|
|
||||||
See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information.
|
See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information.
|
||||||
@@ -223,10 +293,50 @@ spec:
|
|||||||
With TLS 1.3, the cipher suites are not configurable (all supported cipher suites are safe in this case).
|
With TLS 1.3, the cipher suites are not configurable (all supported cipher suites are safe in this case).
|
||||||
<https://golang.org/doc/go1.12#tls_1_3>
|
<https://golang.org/doc/go1.12#tls_1_3>
|
||||||
|
|
||||||
|
### Curve Preferences
|
||||||
|
|
||||||
|
This option allows to set the preferred elliptic curves in a specific order.
|
||||||
|
|
||||||
|
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||||
|
|
||||||
|
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
[tls.options]
|
||||||
|
[tls.options.default]
|
||||||
|
curvePreferences = ["CurveP521", "CurveP384"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
tls:
|
||||||
|
options:
|
||||||
|
default:
|
||||||
|
curvePreferences:
|
||||||
|
- CurveP521
|
||||||
|
- CurveP384
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: TLSOption
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
curvePreferences:
|
||||||
|
- CurveP521
|
||||||
|
- CurveP384
|
||||||
|
```
|
||||||
|
|
||||||
### Strict SNI Checking
|
### Strict SNI Checking
|
||||||
|
|
||||||
With strict SNI checking, Traefik won't allow connections from clients connections
|
With strict SNI checking enabled, Traefik won't allow connections from clients
|
||||||
that do not specify a server_name extension.
|
that do not specify a server_name extension or don't match any certificate configured on the tlsOption.
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Dynamic configuration
|
# Dynamic configuration
|
||||||
@@ -256,6 +366,39 @@ spec:
|
|||||||
sniStrict: true
|
sniStrict: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Prefer Server Cipher Suites
|
||||||
|
|
||||||
|
This option allows the server to choose its most preferred cipher suite instead of the client's.
|
||||||
|
Please note that this is enabled automatically when `minVersion` or `maxVersion` are set.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
[tls.options]
|
||||||
|
[tls.options.default]
|
||||||
|
preferServerCipherSuites = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
tls:
|
||||||
|
options:
|
||||||
|
default:
|
||||||
|
preferServerCipherSuites: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: TLSOption
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
preferServerCipherSuites: true
|
||||||
|
```
|
||||||
|
|
||||||
### Client Authentication (mTLS)
|
### Client Authentication (mTLS)
|
||||||
|
|
||||||
Traefik supports mutual authentication, through the `clientAuth` section.
|
Traefik supports mutual authentication, through the `clientAuth` section.
|
||||||
@@ -304,6 +447,7 @@ metadata:
|
|||||||
|
|
||||||
spec:
|
spec:
|
||||||
clientAuth:
|
clientAuth:
|
||||||
|
# the CA certificate is extracted from key `tls.ca` of the given secrets.
|
||||||
secretNames:
|
secretNames:
|
||||||
- secretCA
|
- secretCA
|
||||||
clientAuthType: RequireAndVerifyClientCert
|
clientAuthType: RequireAndVerifyClientCert
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Traefik is an [open-source](https://github.com/containous/traefik) *Edge Router* that makes publishing your services a fun and easy experience.
|
Traefik is an [open-source](https://github.com/traefik/traefik) *Edge Router* that makes publishing your services a fun and easy experience.
|
||||||
It receives requests on behalf of your system and finds out which components are responsible for handling them.
|
It receives requests on behalf of your system and finds out which components are responsible for handling them.
|
||||||
|
|
||||||
What sets Traefik apart, besides its many features, is that it automatically discovers the right configuration for your services.
|
What sets Traefik apart, besides its many features, is that it automatically discovers the right configuration for your services.
|
||||||
@@ -20,4 +20,9 @@ Developing Traefik, our main goal is to make it simple to use, and we're sure yo
|
|||||||
|
|
||||||
!!! info
|
!!! info
|
||||||
|
|
||||||
If you're a business running critical services behind Traefik, know that [Containous](https://containo.us), the company that sponsors Traefik's development, can provide [commercial support](https://containo.us/services/#commercial-support) and develops an [Enterprise Edition](https://containo.us/traefikee/) of Traefik.
|
Join our user friendly and active [Community Forum](https://community.traefik.io) to discuss, learn, and connect with the traefik community.
|
||||||
|
|
||||||
|
If you're a business running critical services behind Traefik,
|
||||||
|
know that [Traefik Labs](https://traefik.io), the company that sponsors Traefik's development,
|
||||||
|
can provide [commercial support](https://info.traefik.io/commercial-services)
|
||||||
|
and develops an [Enterprise Edition](https://traefik.io/traefik-enterprise/) of Traefik.
|
||||||
|
@@ -26,6 +26,11 @@ spec:
|
|||||||
prefix: /foo
|
prefix: /foo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Prefixing with /foo
|
||||||
|
- "traefik.http.middlewares.add-foo.addprefix.prefix=/foo"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.add-foo.addprefix.prefix": "/foo"
|
"traefik.http.middlewares.add-foo.addprefix.prefix": "/foo"
|
||||||
@@ -58,4 +63,5 @@ http:
|
|||||||
|
|
||||||
### `prefix`
|
### `prefix`
|
||||||
|
|
||||||
`prefix` is the string to add before the current path in the requested URL. It should include the leading slash (`/`).
|
`prefix` is the string to add before the current path in the requested URL.
|
||||||
|
It should include the leading slash (`/`).
|
||||||
|
@@ -12,9 +12,11 @@ The BasicAuth middleware is a quick way to restrict access to your services to k
|
|||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
# Declaring the user list
|
# Declaring the user list
|
||||||
#
|
#
|
||||||
# Note: all dollar signs in the hash need to be doubled for escaping.
|
# Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping.
|
||||||
# To create user:password pair, it's possible to use this command:
|
# To create user:password pair, it's possible to use this command:
|
||||||
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
|
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
|
||||||
|
#
|
||||||
|
# Also note that dollar signs should NOT be doubled when they not evaluated (e.g. Ansible docker_container module).
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||||
```
|
```
|
||||||
@@ -30,6 +32,10 @@ spec:
|
|||||||
secret: secretName
|
secret: secretName
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
"traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||||
@@ -67,7 +73,7 @@ http:
|
|||||||
|
|
||||||
### General
|
### General
|
||||||
|
|
||||||
Passwords must be encoded using MD5, SHA1, or BCrypt.
|
Passwords must be hashed using MD5, SHA1, or BCrypt.
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
|
|
||||||
@@ -75,7 +81,7 @@ Passwords must be encoded using MD5, SHA1, or BCrypt.
|
|||||||
|
|
||||||
### `users`
|
### `users`
|
||||||
|
|
||||||
The `users` option is an array of authorized users. Each user will be declared using the `name:encoded-password` format.
|
The `users` option is an array of authorized users. Each user will be declared using the `name:hashed-password` format.
|
||||||
|
|
||||||
!!! note ""
|
!!! note ""
|
||||||
|
|
||||||
@@ -86,7 +92,7 @@ The `users` option is an array of authorized users. Each user will be declared u
|
|||||||
# Declaring the user list
|
# Declaring the user list
|
||||||
#
|
#
|
||||||
# Note: all dollar signs in the hash need to be doubled for escaping.
|
# Note: all dollar signs in the hash need to be doubled for escaping.
|
||||||
# To create user:password pair, it's possible to use this command:
|
# To create a user:password pair, the following command can be used:
|
||||||
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
|
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||||
@@ -103,6 +109,10 @@ spec:
|
|||||||
secret: authsecret
|
secret: authsecret
|
||||||
|
|
||||||
---
|
---
|
||||||
|
# Note: in a kubernetes secret the string (e.g. generated by htpasswd) must be base64-encoded first.
|
||||||
|
# To create an encoded user:password pair, the following command can be used:
|
||||||
|
# htpasswd -nb user password | openssl base64
|
||||||
|
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
@@ -115,6 +125,11 @@ data:
|
|||||||
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Declaring the user list
|
||||||
|
- "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
"traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||||
@@ -152,7 +167,7 @@ http:
|
|||||||
|
|
||||||
The `usersFile` option is the path to an external file that contains the authorized users for the middleware.
|
The `usersFile` option is the path to an external file that contains the authorized users for the middleware.
|
||||||
|
|
||||||
The file content is a list of `name:encoded-password`.
|
The file content is a list of `name:hashed-password`.
|
||||||
|
|
||||||
!!! note ""
|
!!! note ""
|
||||||
|
|
||||||
@@ -186,6 +201,10 @@ data:
|
|||||||
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.basicauth.usersfile": "/path/to/my/usersfile"
|
"traefik.http.middlewares.test-auth.basicauth.usersfile": "/path/to/my/usersfile"
|
||||||
@@ -237,6 +256,10 @@ spec:
|
|||||||
realm: MyRealm
|
realm: MyRealm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```json tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.basicauth.realm": "MyRealm"
|
"traefik.http.middlewares.test-auth.basicauth.realm": "MyRealm"
|
||||||
@@ -282,6 +305,10 @@ spec:
|
|||||||
headerField: X-WebAuth-User
|
headerField: X-WebAuth-User
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```json tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.my-auth.basicauth.headerField=X-WebAuth-User"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.my-auth.basicauth.headerField": "X-WebAuth-User"
|
"traefik.http.middlewares.my-auth.basicauth.headerField": "X-WebAuth-User"
|
||||||
@@ -322,6 +349,10 @@ spec:
|
|||||||
removeHeader: true
|
removeHeader: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```json tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.basicauth.removeheader=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.basicauth.removeheader": "true"
|
"traefik.http.middlewares.test-auth.basicauth.removeheader": "true"
|
||||||
|
@@ -30,6 +30,11 @@ spec:
|
|||||||
maxRequestBodyBytes: 2000000
|
maxRequestBodyBytes: 2000000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Sets the maximum request body to 2Mb
|
||||||
|
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000"
|
"traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000"
|
||||||
@@ -81,6 +86,10 @@ spec:
|
|||||||
maxRequestBodyBytes: 2000000
|
maxRequestBodyBytes: 2000000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000"
|
"traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000"
|
||||||
@@ -125,6 +134,10 @@ spec:
|
|||||||
memRequestBodyBytes: 2000000
|
memRequestBodyBytes: 2000000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.limit.buffering.memRequestBodyBytes": "2000000"
|
"traefik.http.middlewares.limit.buffering.memRequestBodyBytes": "2000000"
|
||||||
@@ -152,7 +165,7 @@ http:
|
|||||||
|
|
||||||
### `maxResponseBodyBytes`
|
### `maxResponseBodyBytes`
|
||||||
|
|
||||||
With the `maxReesponseBodyBytes` option, you can configure the maximum allowed response size from the service (in Bytes).
|
With the `maxResponseBodyBytes` option, you can configure the maximum allowed response size from the service (in Bytes).
|
||||||
|
|
||||||
If the response exceeds the allowed size, it is not forwarded to the client. The client gets a `413 (Request Entity Too Large) response` instead.
|
If the response exceeds the allowed size, it is not forwarded to the client. The client gets a `413 (Request Entity Too Large) response` instead.
|
||||||
|
|
||||||
@@ -171,6 +184,10 @@ spec:
|
|||||||
maxResponseBodyBytes: 2000000
|
maxResponseBodyBytes: 2000000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.limit.buffering.maxResponseBodyBytes": "2000000"
|
"traefik.http.middlewares.limit.buffering.maxResponseBodyBytes": "2000000"
|
||||||
@@ -215,6 +232,10 @@ spec:
|
|||||||
memResponseBodyBytes: 2000000
|
memResponseBodyBytes: 2000000
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.limit.buffering.memResponseBodyBytes": "2000000"
|
"traefik.http.middlewares.limit.buffering.memResponseBodyBytes": "2000000"
|
||||||
@@ -261,6 +282,10 @@ You can have the Buffering middleware replay the request with the help of the `r
|
|||||||
retryExpression: "IsNetworkError() && Attempts() < 2"
|
retryExpression: "IsNetworkError() && Attempts() < 2"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.limit.buffering.retryExpression": "IsNetworkError() && Attempts() < 2"
|
"traefik.http.middlewares.limit.buffering.retryExpression": "IsNetworkError() && Attempts() < 2"
|
||||||
|
@@ -83,6 +83,17 @@ spec:
|
|||||||
- 127.0.0.1/32
|
- 127.0.0.1/32
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.routers.router1.service=service1"
|
||||||
|
- "traefik.http.routers.router1.middlewares=secured"
|
||||||
|
- "traefik.http.routers.router1.rule=Host(`mydomain`)"
|
||||||
|
- "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users"
|
||||||
|
- "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
|
||||||
|
- "traefik.http.middlewares.https-only.redirectscheme.scheme=https"
|
||||||
|
- "traefik.http.middlewares.known-ips.ipwhitelist.sourceRange=192.168.1.7,127.0.0.1/32"
|
||||||
|
- "http.services.service1.loadbalancer.server.port=80"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.routers.router1.service": "service1",
|
"traefik.http.routers.router1.service": "service1",
|
||||||
|
@@ -7,7 +7,7 @@ Don't Waste Time Calling Unhealthy Services
|
|||||||
|
|
||||||
The circuit breaker protects your system from stacking requests to unhealthy services (resulting in cascading failures).
|
The circuit breaker protects your system from stacking requests to unhealthy services (resulting in cascading failures).
|
||||||
|
|
||||||
When your system is healthy, the circuit is close (normal operations).
|
When your system is healthy, the circuit is closed (normal operations).
|
||||||
When your system becomes unhealthy, the circuit becomes open and the requests are no longer forwarded (but handled by a fallback mechanism).
|
When your system becomes unhealthy, the circuit becomes open and the requests are no longer forwarded (but handled by a fallback mechanism).
|
||||||
|
|
||||||
To assess if your system is healthy, the circuit breaker constantly monitors the services.
|
To assess if your system is healthy, the circuit breaker constantly monitors the services.
|
||||||
@@ -45,6 +45,11 @@ spec:
|
|||||||
expression: LatencyAtQuantileMS(50.0) > 100
|
expression: LatencyAtQuantileMS(50.0) > 100
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Latency Check
|
||||||
|
- "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.latency-check.circuitbreaker.expression": "LatencyAtQuantileMS(50.0) > 100"
|
"traefik.http.middlewares.latency-check.circuitbreaker.expression": "LatencyAtQuantileMS(50.0) > 100"
|
||||||
@@ -77,13 +82,13 @@ http:
|
|||||||
|
|
||||||
There are three possible states for your circuit breaker:
|
There are three possible states for your circuit breaker:
|
||||||
|
|
||||||
- Close (your service operates normally)
|
- Closed (your service operates normally)
|
||||||
- Open (the fallback mechanism takes over your service)
|
- Open (the fallback mechanism takes over your service)
|
||||||
- Recovering (the circuit breaker tries to resume normal operations by progressively sending requests to your service)
|
- Recovering (the circuit breaker tries to resume normal operations by progressively sending requests to your service)
|
||||||
|
|
||||||
### Close
|
### Closed
|
||||||
|
|
||||||
While close, the circuit breaker only collects metrics to analyze the behavior of the requests.
|
While the circuit is closed, the circuit breaker only collects metrics to analyze the behavior of the requests.
|
||||||
|
|
||||||
At specified intervals (`checkPeriod`), it will evaluate `expression` to decide if its state must change.
|
At specified intervals (`checkPeriod`), it will evaluate `expression` to decide if its state must change.
|
||||||
|
|
||||||
|
@@ -25,6 +25,11 @@ spec:
|
|||||||
compress: {}
|
compress: {}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Enable gzip compression
|
||||||
|
- "traefik.http.middlewares.test-compress.compress=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-compress.compress": "true"
|
"traefik.http.middlewares.test-compress.compress": "true"
|
||||||
@@ -58,3 +63,62 @@ http:
|
|||||||
* The response body is larger than `1400` bytes.
|
* The response body is larger than `1400` bytes.
|
||||||
* The `Accept-Encoding` request header contains `gzip`.
|
* The `Accept-Encoding` request header contains `gzip`.
|
||||||
* The response is not already compressed, i.e. the `Content-Encoding` response header is not already set.
|
* The response is not already compressed, i.e. the `Content-Encoding` response header is not already set.
|
||||||
|
|
||||||
|
If Content-Type header is not defined, or empty, the compress middleware will automatically [detect](https://mimesniff.spec.whatwg.org/) a content type.
|
||||||
|
It will also set accordingly the `Content-Type` header with the detected MIME type.
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### `excludedContentTypes`
|
||||||
|
|
||||||
|
`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests to before compressing.
|
||||||
|
|
||||||
|
The requests with content types defined in `excludedContentTypes` are not compressed.
|
||||||
|
|
||||||
|
Content types are compared in a case-insensitive, whitespace-ignored manner.
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-compress
|
||||||
|
spec:
|
||||||
|
compress:
|
||||||
|
excludedContentTypes:
|
||||||
|
- text/event-stream
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
"traefik.http.middlewares.test-compress.compress.excludedcontenttypes": "text/event-stream"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-compress.compress]
|
||||||
|
excludedContentTypes = ["text/event-stream"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-compress:
|
||||||
|
compress:
|
||||||
|
excludedContentTypes:
|
||||||
|
- text/event-stream
|
||||||
|
```
|
||||||
|
86
docs/content/middlewares/contenttype.md
Normal file
86
docs/content/middlewares/contenttype.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
# ContentType
|
||||||
|
|
||||||
|
Handling ContentType auto-detection
|
||||||
|
{: .subtitle }
|
||||||
|
|
||||||
|
The Content-Type middleware - or rather its unique `autoDetect` option -
|
||||||
|
specifies whether to let the `Content-Type` header,
|
||||||
|
if it has not been set by the backend,
|
||||||
|
be automatically set to a value derived from the contents of the response.
|
||||||
|
|
||||||
|
As a proxy, the default behavior should be to leave the header alone,
|
||||||
|
regardless of what the backend did with it.
|
||||||
|
However, the historic default was to always auto-detect and set the header if it was nil,
|
||||||
|
and it is going to be kept that way in order to support users currently relying on it.
|
||||||
|
This middleware exists to enable the correct behavior until at least the default one can be changed in a future version.
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
As explained above, for compatibility reasons the default behavior on a router (without this middleware),
|
||||||
|
is still to automatically set the `Content-Type` header.
|
||||||
|
Therefore, given the default value of the `autoDetect` option (false),
|
||||||
|
simply enabling this middleware for a router switches the router's behavior.
|
||||||
|
|
||||||
|
The scope of the Content-Type middleware is the MIME type detection done by the core of Traefik (the server part).
|
||||||
|
Therefore, it has no effect against any other `Content-Type` header modifications (e.g.: in another middleware such as compress).
|
||||||
|
|
||||||
|
## Configuration Examples
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
# Disable auto-detection
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.autodetect.contenttype.autodetect=false"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# Disable auto-detection
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: autodetect
|
||||||
|
spec:
|
||||||
|
contentType:
|
||||||
|
autoDetect: false
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Disable auto-detection
|
||||||
|
- "traefik.http.middlewares.autodetect.contenttype.autodetect=false"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
"traefik.http.middlewares.autodetect.contenttype.autodetect": "false"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Disable auto-detection
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.autodetect.contenttype.autodetect=false"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Disable auto-detection
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.autodetect.contentType]
|
||||||
|
autoDetect=false
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Disable auto-detection
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
autodetect:
|
||||||
|
contentType:
|
||||||
|
autoDetect: false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### `autoDetect`
|
||||||
|
|
||||||
|
`autoDetect` specifies whether to let the `Content-Type` header,
|
||||||
|
if it has not been set by the backend,
|
||||||
|
be automatically set to a value derived from the contents of the response.
|
@@ -26,6 +26,11 @@ spec:
|
|||||||
secret: userssecret
|
secret: userssecret
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Declaring the user list
|
||||||
|
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
"traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||||
@@ -100,6 +105,10 @@ data:
|
|||||||
dGVzdDp0cmFlZmlrOmEyNjg4ZTAzMWVkYjRiZTZhMzc5N2YzODgyNjU1YzA1CnRlc3QyOnRyYWVmaWs6NTE4ODQ1ODAwZjllMmJmYjFmMWY3NDBlYzI0ZjA3NGUKCg==
|
dGVzdDp0cmFlZmlrOmEyNjg4ZTAzMWVkYjRiZTZhMzc5N2YzODgyNjU1YzA1CnRlc3QyOnRyYWVmaWs6NTE4ODQ1ODAwZjllMmJmYjFmMWY3NDBlYzI0ZjA3NGUKCg==
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
"traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||||
@@ -168,6 +177,10 @@ data:
|
|||||||
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.digestauth.usersfile": "/path/to/my/usersfile"
|
"traefik.http.middlewares.test-auth.digestauth.usersfile": "/path/to/my/usersfile"
|
||||||
@@ -219,6 +232,10 @@ spec:
|
|||||||
realm: MyRealm
|
realm: MyRealm
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.digestauth.realm": "MyRealm"
|
"traefik.http.middlewares.test-auth.digestauth.realm": "MyRealm"
|
||||||
@@ -264,9 +281,8 @@ spec:
|
|||||||
headerField: X-WebAuth-User
|
headerField: X-WebAuth-User
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
|
||||||
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -275,6 +291,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares.my-auth.digestAuth]
|
[http.middlewares.my-auth.digestAuth]
|
||||||
# ...
|
# ...
|
||||||
@@ -309,6 +330,10 @@ spec:
|
|||||||
removeHeader: true
|
removeHeader: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.digestauth.removeheader=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.digestauth.removeheader": "true"
|
"traefik.http.middlewares.test-auth.digestauth.removeheader": "true"
|
||||||
|
@@ -35,6 +35,13 @@ spec:
|
|||||||
port: 80
|
port: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Dynamic Custom Error Page for 5XX Status Code
|
||||||
|
- "traefik.http.middlewares.test-errorpage.errors.status=500-599"
|
||||||
|
- "traefik.http.middlewares.test-errorpage.errors.service=serviceError"
|
||||||
|
- "traefik.http.middlewares.test-errorpage.errors.query=/{status}.html"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-errorpage.errors.status": "500-599",
|
"traefik.http.middlewares.test-errorpage.errors.status": "500-599",
|
||||||
|
@@ -12,48 +12,53 @@ Otherwise, the response from the authentication server is returned.
|
|||||||
## Configuration Examples
|
## Configuration Examples
|
||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
# Forward authentication to authserver.com
|
# Forward authentication to example.com
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth"
|
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
```yaml tab="Kubernetes"
|
||||||
# Forward authentication to authserver.com
|
# Forward authentication to example.com
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Forward authentication to example.com
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.address": "https://authserver.com/auth"
|
"traefik.http.middlewares.test-auth.forwardauth.address": "https://example.com/auth"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Rancher"
|
||||||
# Forward authentication to authserver.com
|
# Forward authentication to example.com
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth"
|
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Forward authentication to authserver.com
|
# Forward authentication to example.com
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
# Forward authentication to authserver.com
|
# Forward authentication to example.com
|
||||||
http:
|
http:
|
||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration Options
|
## Configuration Options
|
||||||
@@ -64,7 +69,7 @@ The `address` option defines the authentication server address.
|
|||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth"
|
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
```yaml tab="Kubernetes"
|
||||||
@@ -74,24 +79,28 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.address": "https://authserver.com/auth"
|
"traefik.http.middlewares.test-auth.forwardauth.address": "https://example.com/auth"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Rancher"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth"
|
- "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
@@ -99,7 +108,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
```
|
```
|
||||||
|
|
||||||
### `trustForwardHeader`
|
### `trustForwardHeader`
|
||||||
@@ -118,10 +127,14 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
trustForwardHeader: true
|
trustForwardHeader: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader": "true"
|
"traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader": "true"
|
||||||
@@ -136,7 +149,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
trustForwardHeader = true
|
trustForwardHeader = true
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -145,7 +158,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
trustForwardHeader: true
|
trustForwardHeader: true
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -165,12 +178,16 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
authResponseHeaders:
|
authResponseHeaders:
|
||||||
- X-Auth-User
|
- X-Auth-User
|
||||||
- X-Secret
|
- X-Secret
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders": "X-Auth-User,X-Secret"
|
"traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders": "X-Auth-User,X-Secret"
|
||||||
@@ -185,7 +202,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
authResponseHeaders = ["X-Auth-User", "X-Secret"]
|
authResponseHeaders = ["X-Auth-User", "X-Secret"]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -194,7 +211,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
authResponseHeaders:
|
authResponseHeaders:
|
||||||
- "X-Auth-User"
|
- "X-Auth-User"
|
||||||
- "X-Secret"
|
- "X-Secret"
|
||||||
@@ -220,7 +237,7 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
tls:
|
tls:
|
||||||
caSecret: mycasercret
|
caSecret: mycasercret
|
||||||
|
|
||||||
@@ -235,6 +252,10 @@ data:
|
|||||||
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.tls.ca": "path/to/local.crt"
|
"traefik.http.middlewares.test-auth.forwardauth.tls.ca": "path/to/local.crt"
|
||||||
@@ -249,7 +270,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
[http.middlewares.test-auth.forwardAuth.tls]
|
[http.middlewares.test-auth.forwardAuth.tls]
|
||||||
ca = "path/to/local.crt"
|
ca = "path/to/local.crt"
|
||||||
```
|
```
|
||||||
@@ -259,7 +280,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
tls:
|
tls:
|
||||||
ca: "path/to/local.crt"
|
ca: "path/to/local.crt"
|
||||||
```
|
```
|
||||||
@@ -285,11 +306,15 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
tls:
|
tls:
|
||||||
caOptional: true
|
caOptional: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.caOptional=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.tls.caOptional": "true"
|
"traefik.http.middlewares.test-auth.forwardauth.tls.caOptional": "true"
|
||||||
@@ -304,7 +329,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
[http.middlewares.test-auth.forwardAuth.tls]
|
[http.middlewares.test-auth.forwardAuth.tls]
|
||||||
caOptional = true
|
caOptional = true
|
||||||
```
|
```
|
||||||
@@ -314,7 +339,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
tls:
|
tls:
|
||||||
caOptional: true
|
caOptional: true
|
||||||
```
|
```
|
||||||
@@ -336,7 +361,7 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
tls:
|
tls:
|
||||||
certSecret: mytlscert
|
certSecret: mytlscert
|
||||||
|
|
||||||
@@ -352,6 +377,11 @@ data:
|
|||||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert",
|
"traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert",
|
||||||
@@ -368,7 +398,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
[http.middlewares.test-auth.forwardAuth.tls]
|
[http.middlewares.test-auth.forwardAuth.tls]
|
||||||
cert = "path/to/foo.cert"
|
cert = "path/to/foo.cert"
|
||||||
key = "path/to/foo.key"
|
key = "path/to/foo.key"
|
||||||
@@ -379,7 +409,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
tls:
|
tls:
|
||||||
cert: "path/to/foo.cert"
|
cert: "path/to/foo.cert"
|
||||||
key: "path/to/foo.key"
|
key: "path/to/foo.key"
|
||||||
@@ -405,7 +435,7 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
tls:
|
tls:
|
||||||
certSecret: mytlscert
|
certSecret: mytlscert
|
||||||
|
|
||||||
@@ -421,6 +451,11 @@ data:
|
|||||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert",
|
"traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert",
|
||||||
@@ -437,7 +472,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
[http.middlewares.test-auth.forwardAuth.tls]
|
[http.middlewares.test-auth.forwardAuth.tls]
|
||||||
cert = "path/to/foo.cert"
|
cert = "path/to/foo.cert"
|
||||||
key = "path/to/foo.key"
|
key = "path/to/foo.key"
|
||||||
@@ -448,7 +483,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
tls:
|
tls:
|
||||||
cert: "path/to/foo.cert"
|
cert: "path/to/foo.cert"
|
||||||
key: "path/to/foo.key"
|
key: "path/to/foo.key"
|
||||||
@@ -473,11 +508,15 @@ metadata:
|
|||||||
name: test-auth
|
name: test-auth
|
||||||
spec:
|
spec:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: https://authserver.com/auth
|
address: https://example.com/auth
|
||||||
tls:
|
tls:
|
||||||
insecureSkipVerify: true
|
insecureSkipVerify: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify": "true"
|
"traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify": "true"
|
||||||
@@ -492,7 +531,7 @@ labels:
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-auth.forwardAuth]
|
[http.middlewares.test-auth.forwardAuth]
|
||||||
address = "https://authserver.com/auth"
|
address = "https://example.com/auth"
|
||||||
[http.middlewares.test-auth.forwardAuth.tls]
|
[http.middlewares.test-auth.forwardAuth.tls]
|
||||||
insecureSkipVerify: true
|
insecureSkipVerify: true
|
||||||
```
|
```
|
||||||
@@ -502,7 +541,7 @@ http:
|
|||||||
middlewares:
|
middlewares:
|
||||||
test-auth:
|
test-auth:
|
||||||
forwardAuth:
|
forwardAuth:
|
||||||
address: "https://authserver.com/auth"
|
address: "https://example.com/auth"
|
||||||
tls:
|
tls:
|
||||||
insecureSkipVerify: true
|
insecureSkipVerify: true
|
||||||
```
|
```
|
||||||
|
@@ -32,6 +32,11 @@ spec:
|
|||||||
X-Custom-Response-Header: "value"
|
X-Custom-Response-Header: "value"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test",
|
"traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test",
|
||||||
@@ -91,6 +96,10 @@ spec:
|
|||||||
X-Custom-Response-Header: "" # Removes
|
X-Custom-Response-Header: "" # Removes
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test",
|
"traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test",
|
||||||
@@ -142,8 +151,13 @@ metadata:
|
|||||||
name: testHeader
|
name: testHeader
|
||||||
spec:
|
spec:
|
||||||
headers:
|
headers:
|
||||||
frameDeny: "true"
|
frameDeny: true
|
||||||
sslRedirect: "true"
|
sslRedirect: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.framedeny=true"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.sslredirect=true"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -183,7 +197,7 @@ This functionality allows for more advanced security features to quickly be set.
|
|||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
|
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
|
||||||
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworigin=origin-list-or-null"
|
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org"
|
||||||
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
|
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
|
||||||
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
||||||
```
|
```
|
||||||
@@ -199,15 +213,24 @@ spec:
|
|||||||
- "GET"
|
- "GET"
|
||||||
- "OPTIONS"
|
- "OPTIONS"
|
||||||
- "PUT"
|
- "PUT"
|
||||||
accessControlAllowOrigin: "origin-list-or-null"
|
accessControlAllowOriginList:
|
||||||
|
- "https://foo.bar.org"
|
||||||
|
- "https://example.org"
|
||||||
accessControlMaxAge: 100
|
accessControlMaxAge: 100
|
||||||
addVaryHeader: "true"
|
addVaryHeader: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
|
||||||
|
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT",
|
"traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT",
|
||||||
"traefik.http.middlewares.testheader.headers.accesscontrolalloworigin": "origin-list-or-null",
|
"traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist": "https://foo.bar.org,https://example.org",
|
||||||
"traefik.http.middlewares.testheader.headers.accesscontrolmaxage": "100",
|
"traefik.http.middlewares.testheader.headers.accesscontrolmaxage": "100",
|
||||||
"traefik.http.middlewares.testheader.headers.addvaryheader": "true"
|
"traefik.http.middlewares.testheader.headers.addvaryheader": "true"
|
||||||
}
|
}
|
||||||
@@ -216,7 +239,7 @@ spec:
|
|||||||
```yaml tab="Rancher"
|
```yaml tab="Rancher"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
|
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
|
||||||
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworigin=origin-list-or-null"
|
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org"
|
||||||
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
|
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
|
||||||
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
||||||
```
|
```
|
||||||
@@ -225,7 +248,7 @@ labels:
|
|||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.testHeader.headers]
|
[http.middlewares.testHeader.headers]
|
||||||
accessControlAllowMethods= ["GET", "OPTIONS", "PUT"]
|
accessControlAllowMethods= ["GET", "OPTIONS", "PUT"]
|
||||||
accessControlAllowOrigin = "origin-list-or-null"
|
accessControlAllowOriginList = ["https://foo.bar.org","https://example.org"]
|
||||||
accessControlMaxAge = 100
|
accessControlMaxAge = 100
|
||||||
addVaryHeader = true
|
addVaryHeader = true
|
||||||
```
|
```
|
||||||
@@ -239,7 +262,9 @@ http:
|
|||||||
- GET
|
- GET
|
||||||
- OPTIONS
|
- OPTIONS
|
||||||
- PUT
|
- PUT
|
||||||
accessControlAllowOrigin: "origin-list-or-null"
|
accessControlAllowOriginList:
|
||||||
|
- https://foo.bar.org
|
||||||
|
- https://example.org
|
||||||
accessControlMaxAge: 100
|
accessControlMaxAge: 100
|
||||||
addVaryHeader: true
|
addVaryHeader: true
|
||||||
```
|
```
|
||||||
@@ -274,14 +299,22 @@ The `accessControlAllowHeaders` indicates which header field names can be used a
|
|||||||
|
|
||||||
The `accessControlAllowMethods` indicates which methods can be used during requests.
|
The `accessControlAllowMethods` indicates which methods can be used during requests.
|
||||||
|
|
||||||
### `accessControlAllowOrigin`
|
### `accessControlAllowOriginList`
|
||||||
|
|
||||||
The `accessControlAllowOrigin` indicates whether a resource can be shared by returning different values.
|
The `accessControlAllowOriginList` indicates whether a resource can be shared by returning different values.
|
||||||
The three options for this value are:
|
|
||||||
|
|
||||||
- `origin-list-or-null`
|
A wildcard origin `*` can also be configured, and will match all requests.
|
||||||
- `*`
|
If this value is set by a backend server, it will be overwritten by Traefik
|
||||||
- `null`
|
|
||||||
|
This value can contains a list of allowed origins.
|
||||||
|
|
||||||
|
More information including how to use the settings can be found on:
|
||||||
|
|
||||||
|
- [Mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin)
|
||||||
|
- [w3](https://fetch.spec.whatwg.org/#http-access-control-allow-origin)
|
||||||
|
- [IETF](https://tools.ietf.org/html/rfc6454#section-7.1)
|
||||||
|
|
||||||
|
Traefik no longer supports the null value, as it is [no longer recommended as a return value](https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null).
|
||||||
|
|
||||||
### `accessControlExposeHeaders`
|
### `accessControlExposeHeaders`
|
||||||
|
|
||||||
@@ -289,11 +322,11 @@ The `accessControlExposeHeaders` indicates which headers are safe to expose to t
|
|||||||
|
|
||||||
### `accessControlMaxAge`
|
### `accessControlMaxAge`
|
||||||
|
|
||||||
The `accessControlMaxAge` indicates how long a preflight request can be cached.
|
The `accessControlMaxAge` indicates how long (in seconds) a preflight request can be cached.
|
||||||
|
|
||||||
### `addVaryHeader`
|
### `addVaryHeader`
|
||||||
|
|
||||||
The `addVaryHeader` is used in conjunction with `accessControlAllowOrigin` to determine whether the vary header should be added or modified to demonstrate that server responses can differ beased on the value of the origin header.
|
The `addVaryHeader` is used in conjunction with `accessControlAllowOriginList` to determine whether the vary header should be added or modified to demonstrate that server responses can differ based on the value of the origin header.
|
||||||
|
|
||||||
### `allowedHosts`
|
### `allowedHosts`
|
||||||
|
|
||||||
|
@@ -24,6 +24,11 @@ spec:
|
|||||||
amount: 10
|
amount: 10
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Limiting to 10 simultaneous connections
|
||||||
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
|
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
|
||||||
@@ -74,6 +79,11 @@ spec:
|
|||||||
amount: 10
|
amount: 10
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Limiting to 10 simultaneous connections
|
||||||
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
|
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
|
||||||
@@ -146,9 +156,8 @@ spec:
|
|||||||
depth: 2
|
depth: 2
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
|
||||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -157,6 +166,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-inflightreq.inflightreq]
|
[http.middlewares.test-inflightreq.inflightreq]
|
||||||
@@ -209,6 +223,10 @@ spec:
|
|||||||
- 192.168.1.7
|
- 192.168.1.7
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7"
|
"traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7"
|
||||||
@@ -259,9 +277,8 @@ spec:
|
|||||||
requestHeaderName: username
|
requestHeaderName: username
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
|
||||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -270,6 +287,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-inflightreq.inflightreq]
|
[http.middlewares.test-inflightreq.inflightreq]
|
||||||
@@ -306,9 +328,8 @@ spec:
|
|||||||
requestHost: true
|
requestHost: true
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Cosul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
|
||||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -317,6 +338,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-inflightreq.inflightreq]
|
[http.middlewares.test-inflightreq.inflightreq]
|
||||||
|
@@ -27,6 +27,11 @@ spec:
|
|||||||
- 192.168.1.7
|
- 192.168.1.7
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Accepts request from defined IP
|
||||||
|
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32,192.168.1.7"
|
"traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32,192.168.1.7"
|
||||||
@@ -61,7 +66,7 @@ http:
|
|||||||
|
|
||||||
### `sourceRange`
|
### `sourceRange`
|
||||||
|
|
||||||
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs).
|
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||||
|
|
||||||
### `ipStrategy`
|
### `ipStrategy`
|
||||||
|
|
||||||
@@ -95,11 +100,10 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
|||||||
depth: 2
|
depth: 2
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
labels:
|
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -109,6 +113,13 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||||
|
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
@@ -168,10 +179,9 @@ spec:
|
|||||||
- 192.168.1.7
|
- 192.168.1.7
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
# Exclude from `X-Forwarded-For`
|
# Exclude from `X-Forwarded-For`
|
||||||
labels:
|
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -180,6 +190,12 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Exclude from `X-Forwarded-For`
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Exclude from `X-Forwarded-For`
|
# Exclude from `X-Forwarded-For`
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
|
@@ -5,19 +5,24 @@ Tweaking the Request
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Attached to the routers, pieces of middleware are a mean of tweaking the requests before they are sent to your [service](../routing/services/index.md) (or before the answer from the services are sent to the clients).
|
Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your [service](../routing/services/index.md) (or before the answer from the services are sent to the clients).
|
||||||
|
|
||||||
There are many different available middlewares in Traefik, some can modify the request, the headers, some are in charge of redirections, some add authentication, and so on.
|
There are several available middleware in Traefik, some can modify the request, the headers, some are in charge of redirections, some add authentication, and so on.
|
||||||
|
|
||||||
Pieces of middleware can be combined in chains to fit every scenario.
|
Pieces of middleware can be combined in chains to fit every scenario.
|
||||||
|
|
||||||
|
!!! warning "Provider Namespace"
|
||||||
|
|
||||||
|
Be aware of the concept of Providers Namespace described in the [Configuration Discovery](../providers/overview.md#provider-namespace) section.
|
||||||
|
It also applies to Middlewares.
|
||||||
|
|
||||||
## Configuration Example
|
## Configuration Example
|
||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
# As a Docker Label
|
# As a Docker Label
|
||||||
whoami:
|
whoami:
|
||||||
# A container that exposes an API to show its IP address
|
# A container that exposes an API to show its IP address
|
||||||
image: containous/whoami
|
image: traefik/whoami
|
||||||
labels:
|
labels:
|
||||||
# Create a middleware named `foo-add-prefix`
|
# Create a middleware named `foo-add-prefix`
|
||||||
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
|
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
|
||||||
@@ -25,7 +30,7 @@ whoami:
|
|||||||
- "traefik.http.routers.router1.middlewares=foo-add-prefix@docker"
|
- "traefik.http.routers.router1.middlewares=foo-add-prefix@docker"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
```yaml tab="Kubernetes IngressRoute"
|
||||||
# As a Kubernetes Traefik IngressRoute
|
# As a Kubernetes Traefik IngressRoute
|
||||||
apiVersion: apiextensions.k8s.io/v1beta1
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
@@ -63,6 +68,13 @@ spec:
|
|||||||
- name: stripprefix
|
- name: stripprefix
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Create a middleware named `foo-add-prefix`
|
||||||
|
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
|
||||||
|
# Apply the middleware named `foo-add-prefix` to the router named `router1`
|
||||||
|
- "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo",
|
"traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo",
|
||||||
@@ -121,78 +133,6 @@ http:
|
|||||||
- url: "http://127.0.0.1:80"
|
- url: "http://127.0.0.1:80"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Provider Namespace
|
|
||||||
|
|
||||||
When you declare a middleware, it lives in its provider namespace.
|
|
||||||
For example, if you declare a middleware using a Docker label, under the hoods, it will reside in the docker provider namespace.
|
|
||||||
|
|
||||||
If you use multiple providers and wish to reference a middleware declared in another provider
|
|
||||||
(aka referencing a cross-provider middleware),
|
|
||||||
then you'll have to append to the middleware name, the `@` separator, followed by the provider name.
|
|
||||||
|
|
||||||
```text
|
|
||||||
<resource-name>@<provider-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
!!! important "Kubernetes Namespace"
|
|
||||||
|
|
||||||
As Kubernetes also has its own notion of namespace, one should not confuse the "provider namespace"
|
|
||||||
with the "kubernetes namespace" of a resource when in the context of a cross-provider usage.
|
|
||||||
In this case, since the definition of the middleware is not in kubernetes,
|
|
||||||
specifying a "kubernetes namespace" when referring to the resource does not make any sense,
|
|
||||||
and therefore this specification would be ignored even if present.
|
|
||||||
|
|
||||||
!!! abstract "Referencing a Middleware from Another Provider"
|
|
||||||
|
|
||||||
Declaring the add-foo-prefix in the file provider.
|
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
|
||||||
[http.middlewares]
|
|
||||||
[http.middlewares.add-foo-prefix.addPrefix]
|
|
||||||
prefix = "/foo"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
|
||||||
http:
|
|
||||||
middlewares:
|
|
||||||
add-foo-prefix:
|
|
||||||
addPrefix:
|
|
||||||
prefix: "/foo"
|
|
||||||
```
|
|
||||||
|
|
||||||
Using the add-foo-prefix middleware from other providers:
|
|
||||||
|
|
||||||
```yaml tab="Docker"
|
|
||||||
your-container: #
|
|
||||||
image: your-docker-image
|
|
||||||
|
|
||||||
labels:
|
|
||||||
# Attach add-foo-prefix@file middleware (declared in file)
|
|
||||||
- "traefik.http.routers.my-container.middlewares=add-foo-prefix@file"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
|
||||||
kind: IngressRoute
|
|
||||||
metadata:
|
|
||||||
name: ingressroutestripprefix
|
|
||||||
|
|
||||||
spec:
|
|
||||||
entryPoints:
|
|
||||||
- web
|
|
||||||
routes:
|
|
||||||
- match: Host(`bar.com`)
|
|
||||||
kind: Rule
|
|
||||||
services:
|
|
||||||
- name: whoami
|
|
||||||
port: 80
|
|
||||||
middlewares:
|
|
||||||
- name: add-foo-prefix@file
|
|
||||||
# namespace: bar
|
|
||||||
# A namespace specification such as above is ignored
|
|
||||||
# when the cross-provider syntax is used.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Available Middlewares
|
## Available Middlewares
|
||||||
|
|
||||||
| Middleware | Purpose | Area |
|
| Middleware | Purpose | Area |
|
||||||
|
@@ -29,6 +29,11 @@ spec:
|
|||||||
pem: true
|
pem: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem": "true"
|
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem": "true"
|
||||||
@@ -65,6 +70,7 @@ http:
|
|||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.serialnumber=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
||||||
@@ -111,26 +117,25 @@ http:
|
|||||||
domainComponent: true
|
domainComponent: true
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||||
labels:
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -154,6 +159,28 @@ http:
|
|||||||
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true"
|
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||||
|
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||||
@@ -238,7 +265,7 @@ In the following example, you can see a complete certificate. We will use each p
|
|||||||
Validity
|
Validity
|
||||||
Not Before: Dec 6 11:10:16 2018 GMT
|
Not Before: Dec 6 11:10:16 2018 GMT
|
||||||
Not After : Dec 5 11:10:16 2020 GMT
|
Not After : Dec 5 11:10:16 2020 GMT
|
||||||
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.cheese.org, CN=*.cheese.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@cheese.org/emailAddress=cert@scheese.com
|
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.example.org, CN=*.example.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@example.org/emailAddress=cert@sexample.com
|
||||||
Subject Public Key Info:
|
Subject Public Key Info:
|
||||||
Public Key Algorithm: rsaEncryption
|
Public Key Algorithm: rsaEncryption
|
||||||
RSA Public-Key: (2048 bit)
|
RSA Public-Key: (2048 bit)
|
||||||
@@ -275,7 +302,7 @@ In the following example, you can see a complete certificate. We will use each p
|
|||||||
keyid:1E:52:A2:E8:54:D5:37:EB:D5:A8:1D:E4:C2:04:1D:37:E2:F7:70:03
|
keyid:1E:52:A2:E8:54:D5:37:EB:D5:A8:1D:E4:C2:04:1D:37:E2:F7:70:03
|
||||||
|
|
||||||
X509v3 Subject Alternative Name:
|
X509v3 Subject Alternative Name:
|
||||||
DNS:*.cheese.org, DNS:*.cheese.net, DNS:*.cheese.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@cheese.org, email:test@cheese.net
|
DNS:*.example.org, DNS:*.example.net, DNS:*.example.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@example.org, email:test@example.net
|
||||||
Signature Algorithm: sha1WithRSAEncryption
|
Signature Algorithm: sha1WithRSAEncryption
|
||||||
76:6b:05:b0:0e:34:11:b1:83:99:91:dc:ae:1b:e2:08:15:8b:
|
76:6b:05:b0:0e:34:11:b1:83:99:91:dc:ae:1b:e2:08:15:8b:
|
||||||
16:b2:9b:27:1c:02:ac:b5:df:1b:d0:d0:75:a4:2b:2c:5c:65:
|
16:b2:9b:27:1c:02:ac:b5:df:1b:d0:d0:75:a4:2b:2c:5c:65:
|
||||||
@@ -380,7 +407,7 @@ In the example, it is the part between `-----BEGIN CERTIFICATE-----` and `-----E
|
|||||||
!!! info "Extracted data"
|
!!! info "Extracted data"
|
||||||
|
|
||||||
The delimiters and `\n` will be removed.
|
The delimiters and `\n` will be removed.
|
||||||
If there are more than one certificate, they are separated by a "`;`".
|
If there are more than one certificate, they are separated by a "`,`".
|
||||||
|
|
||||||
!!! warning "`X-Forwarded-Tls-Client-Cert` value could exceed the web server header size limit"
|
!!! warning "`X-Forwarded-Tls-Client-Cert` value could exceed the web server header size limit"
|
||||||
|
|
||||||
@@ -395,12 +422,12 @@ The value of the header will be an escaped concatenation of all the selected cer
|
|||||||
The following example shows an unescaped result that uses all the available fields:
|
The following example shows an unescaped result that uses all the available fields:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=*.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
|
Subject="DC=org,DC=cheese,C=FR,C=US,ST=Cheese org state,ST=Cheese com state,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=*.example.com";Issuer="DC=org,DC=cheese,C=FR,C=US,ST=Signing State,ST=Signing State 2,L=TOULOUSE,L=LYON,O=Cheese,O=Cheese 2,CN=Simple Signing CA 2";NB="1544094616";NA="1607166616";SAN="*.example.org,*.example.net,*.example.com,test@example.org,test@example.net,10.0.1.0,10.0.1.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "Multiple certificates"
|
!!! info "Multiple certificates"
|
||||||
|
|
||||||
If there are more than one certificate, they are separated by a `;`.
|
If there are more than one certificate, they are separated by a `,`.
|
||||||
|
|
||||||
#### `info.notAfter`
|
#### `info.notAfter`
|
||||||
|
|
||||||
@@ -416,7 +443,7 @@ The data are taken from the following certificate part:
|
|||||||
The escape `notAfter` info part will be like:
|
The escape `notAfter` info part will be like:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
NA=1607166616
|
NA="1607166616"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `info.notBefore`
|
#### `info.notBefore`
|
||||||
@@ -433,7 +460,7 @@ Validity
|
|||||||
The escape `notBefore` info part will be like:
|
The escape `notBefore` info part will be like:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
NB=1544094616
|
NB="1544094616"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `info.sans`
|
#### `info.sans`
|
||||||
@@ -444,19 +471,19 @@ The data are taken from the following certificate part:
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
X509v3 Subject Alternative Name:
|
X509v3 Subject Alternative Name:
|
||||||
DNS:*.cheese.org, DNS:*.cheese.net, DNS:*.cheese.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@cheese.org, email:test@cheese.net
|
DNS:*.example.org, DNS:*.example.net, DNS:*.example.com, IP Address:10.0.1.0, IP Address:10.0.1.2, email:test@example.org, email:test@example.net
|
||||||
```
|
```
|
||||||
|
|
||||||
The escape SANs info part will be like:
|
The escape SANs info part will be like:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
SAN=*.cheese.org,*.cheese.net,*.cheese.com,test@cheese.org,test@cheese.net,10.0.1.0,10.0.1.2
|
SAN="*.example.org,*.example.net,*.example.com,test@example.org,test@example.net,10.0.1.0,10.0.1.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "multiple values"
|
!!! info "multiple values"
|
||||||
|
|
||||||
All the SANs data are separated by a `,`.
|
All the SANs data are separated by a `,`.
|
||||||
|
|
||||||
#### `info.subject`
|
#### `info.subject`
|
||||||
|
|
||||||
The `info.subject` select the specific client certificate subject details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
The `info.subject` select the specific client certificate subject details you want to add to the `X-Forwarded-Tls-Client-Cert-Info` header.
|
||||||
@@ -464,7 +491,7 @@ The `info.subject` select the specific client certificate subject details you wa
|
|||||||
The data are taken from the following certificate part :
|
The data are taken from the following certificate part :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.cheese.org, CN=*.cheese.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@cheese.org/emailAddress=cert@scheese.com
|
Subject: DC=org, DC=cheese, O=Cheese, O=Cheese 2, OU=Simple Signing Section, OU=Simple Signing Section 2, CN=*.example.org, CN=*.example.com, C=FR, C=US, L=TOULOUSE, L=LYON, ST=Cheese org state, ST=Cheese com state/emailAddress=cert@example.org/emailAddress=cert@sexample.com
|
||||||
```
|
```
|
||||||
|
|
||||||
##### `info.subject.country`
|
##### `info.subject.country`
|
||||||
@@ -522,7 +549,7 @@ The data are taken from the subject part with the `CN` key.
|
|||||||
The escape common name info in the subject part will be like :
|
The escape common name info in the subject part will be like :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
CN=*.cheese.com
|
CN=*.example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
##### `info.subject.serialNumber`
|
##### `info.subject.serialNumber`
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
To Control the Number of Requests Going to a Service
|
To Control the Number of Requests Going to a Service
|
||||||
{: .subtitle }
|
{: .subtitle }
|
||||||
|
|
||||||
The RateLimit middleware ensures that services will receive a _fair_ number of requests, and allows you define what is fair.
|
The RateLimit middleware ensures that services will receive a _fair_ number of requests, and allows one to define what fair is.
|
||||||
|
|
||||||
## Configuration Example
|
## Configuration Example
|
||||||
|
|
||||||
@@ -24,8 +24,15 @@ metadata:
|
|||||||
name: test-ratelimit
|
name: test-ratelimit
|
||||||
spec:
|
spec:
|
||||||
rateLimit:
|
rateLimit:
|
||||||
average: 100
|
average: 100
|
||||||
burst: 50
|
burst: 50
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Here, an average of 100 requests per second is allowed.
|
||||||
|
# In addition, a burst of 50 requests is allowed.
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=100"
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=50"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -67,22 +74,33 @@ http:
|
|||||||
|
|
||||||
### `average`
|
### `average`
|
||||||
|
|
||||||
Average is the maximum rate, in requests/s, allowed for the given source.
|
`average` is the maximum rate, by default in requests by second, allowed for the given source.
|
||||||
It defaults to 0, which means no rate limiting.
|
|
||||||
|
It defaults to `0`, which means no rate limiting.
|
||||||
|
|
||||||
|
The rate is actually defined by dividing `average` by `period`.
|
||||||
|
So for a rate below 1 req/s, one needs to define a `period` larger than a second.
|
||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
|
# 100 reqs/s
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=100"
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=100"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
```yaml tab="Kubernetes"
|
||||||
|
# 100 reqs/s
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
name: test-ratelimit
|
name: test-ratelimit
|
||||||
spec:
|
spec:
|
||||||
rateLimit:
|
rateLimit:
|
||||||
average: 100
|
average: 100
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# 100 reqs/s
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=100"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -97,12 +115,14 @@ labels:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
|
# 100 reqs/s
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-ratelimit.rateLimit]
|
[http.middlewares.test-ratelimit.rateLimit]
|
||||||
average = 100
|
average = 100
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
|
# 100 reqs/s
|
||||||
http:
|
http:
|
||||||
middlewares:
|
middlewares:
|
||||||
test-ratelimit:
|
test-ratelimit:
|
||||||
@@ -110,10 +130,78 @@ http:
|
|||||||
average: 100
|
average: 100
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `period`
|
||||||
|
|
||||||
|
`period`, in combination with `average`, defines the actual maximum rate, such as:
|
||||||
|
|
||||||
|
```go
|
||||||
|
r = average / period
|
||||||
|
```
|
||||||
|
|
||||||
|
It defaults to `1` second.
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
# 6 reqs/minute
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=6"
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# 6 reqs/minute
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-ratelimit
|
||||||
|
spec:
|
||||||
|
rateLimit:
|
||||||
|
period: 1m
|
||||||
|
average: 6
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# 6 reqs/minute
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=6"
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
"traefik.http.middlewares.test-ratelimit.ratelimit.average": "6",
|
||||||
|
"traefik.http.middlewares.test-ratelimit.ratelimit.period": "1m",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# 6 reqs/minute
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=6"
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# 6 reqs/minute
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-ratelimit.rateLimit]
|
||||||
|
average = 6
|
||||||
|
period = 1m
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# 6 reqs/minute
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 6
|
||||||
|
period: 1m
|
||||||
|
```
|
||||||
|
|
||||||
### `burst`
|
### `burst`
|
||||||
|
|
||||||
Burst is the maximum number of requests allowed to go through in the same arbitrarily small period of time.
|
`burst` is the maximum number of requests allowed to go through in the same arbitrarily small period of time.
|
||||||
It defaults to 1.
|
|
||||||
|
It defaults to `1`.
|
||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
@@ -127,7 +215,11 @@ metadata:
|
|||||||
name: test-ratelimit
|
name: test-ratelimit
|
||||||
spec:
|
spec:
|
||||||
rateLimit:
|
rateLimit:
|
||||||
burst: 100
|
burst: 100
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -138,8 +230,7 @@ spec:
|
|||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Rancher"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
@@ -204,9 +295,8 @@ spec:
|
|||||||
- 192.168.1.7
|
- 192.168.1.7
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -215,6 +305,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-ratelimit.rateLimit]
|
[http.middlewares.test-ratelimit.rateLimit]
|
||||||
@@ -268,9 +363,8 @@ spec:
|
|||||||
requestHeaderName: username
|
requestHeaderName: username
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username"
|
||||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -279,6 +373,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-ratelimit.rateLimit]
|
[http.middlewares.test-ratelimit.rateLimit]
|
||||||
@@ -315,9 +414,8 @@ spec:
|
|||||||
requestHost: true
|
requestHost: true
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Rancher"
|
```yaml tab="Consul Catalog"
|
||||||
labels:
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true"
|
||||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -326,6 +424,11 @@ labels:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true"
|
||||||
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.test-ratelimit.rateLimit]
|
[http.middlewares.test-ratelimit.rateLimit]
|
||||||
|
@@ -31,6 +31,13 @@ spec:
|
|||||||
replacement: http://mydomain/${1}
|
replacement: http://mydomain/${1}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Redirect with domain replacement
|
||||||
|
# Note: all dollar signs need to be doubled for escaping.
|
||||||
|
- "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^http://localhost/(.*)"
|
||||||
|
- "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-redirectregex.redirectregex.regex": "^http://localhost/(.*)",
|
"traefik.http.middlewares.test-redirectregex.redirectregex.regex": "^http://localhost/(.*)",
|
||||||
|
@@ -15,6 +15,7 @@ RedirectScheme redirect request from a scheme to another.
|
|||||||
# Redirect to https
|
# Redirect to https
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
```yaml tab="Kubernetes"
|
||||||
@@ -26,6 +27,137 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
redirectScheme:
|
redirectScheme:
|
||||||
scheme: https
|
scheme: https
|
||||||
|
permanent: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
"traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme": "https"
|
||||||
|
"traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent": "true"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Redirect to https
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-redirectscheme.redirectScheme]
|
||||||
|
scheme = "https"
|
||||||
|
permanent = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Redirect to https
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-redirectscheme:
|
||||||
|
redirectScheme:
|
||||||
|
scheme: https
|
||||||
|
permanent: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### `permanent`
|
||||||
|
|
||||||
|
Set the `permanent` option to `true` to apply a permanent redirection.
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
# ...
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# Redirect to https
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-redirectscheme
|
||||||
|
spec:
|
||||||
|
redirectScheme:
|
||||||
|
# ...
|
||||||
|
permanent: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
# ...
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
|
||||||
|
"traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent": "true"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
# ...
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Redirect to https
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-redirectscheme.redirectScheme]
|
||||||
|
# ...
|
||||||
|
permanent = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Redirect to https
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-redirectscheme:
|
||||||
|
redirectScheme:
|
||||||
|
# ...
|
||||||
|
permanent: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### `scheme`
|
||||||
|
|
||||||
|
The `scheme` option defines the scheme of the new url.
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# Redirect to https
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-redirectscheme
|
||||||
|
spec:
|
||||||
|
redirectScheme:
|
||||||
|
scheme: https
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
||||||
```
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
@@ -56,16 +188,66 @@ http:
|
|||||||
scheme: https
|
scheme: https
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration Options
|
|
||||||
|
|
||||||
### `permanent`
|
|
||||||
|
|
||||||
Set the `permanent` option to `true` to apply a permanent redirection.
|
|
||||||
|
|
||||||
### `scheme`
|
|
||||||
|
|
||||||
The `scheme` option defines the scheme of the new url.
|
|
||||||
|
|
||||||
### `port`
|
### `port`
|
||||||
|
|
||||||
The `port` option defines the port of the new url.
|
The `port` option defines the port of the new url.
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
# ...
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
# Redirect to https
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: test-redirectscheme
|
||||||
|
spec:
|
||||||
|
redirectScheme:
|
||||||
|
# ...
|
||||||
|
port: "443"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
# ...
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
|
||||||
|
"traefik.http.middlewares.test-redirectscheme.redirectscheme.port": "443"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
# Redirect to https
|
||||||
|
labels:
|
||||||
|
# ...
|
||||||
|
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Redirect to https
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.test-redirectscheme.redirectScheme]
|
||||||
|
# ...
|
||||||
|
port = 443
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Redirect to https
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
test-redirectscheme:
|
||||||
|
redirectScheme:
|
||||||
|
# ...
|
||||||
|
port: "443"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info "Port in this configuration is a string, not a numeric value."
|
||||||
|
@@ -28,6 +28,11 @@ spec:
|
|||||||
path: /foo
|
path: /foo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Replace the path by /foo
|
||||||
|
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-replacepath.replacepath.path": "/foo"
|
"traefik.http.middlewares.test-replacepath.replacepath.path": "/foo"
|
||||||
|
@@ -15,7 +15,7 @@ The ReplaceRegex replace a path from an url to another with regex matching and r
|
|||||||
# Replace path with regex
|
# Replace path with regex
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
|
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
|
||||||
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1"
|
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$$1"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes"
|
```yaml tab="Kubernetes"
|
||||||
@@ -30,6 +30,12 @@ spec:
|
|||||||
replacement: /bar/$1
|
replacement: /bar/$1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Replace path with regex
|
||||||
|
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
|
||||||
|
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-replacepathregex.replacepathregex.regex": "^/foo/(.*)",
|
"traefik.http.middlewares.test-replacepathregex.replacepathregex.regex": "^/foo/(.*)",
|
||||||
|
@@ -29,6 +29,11 @@ spec:
|
|||||||
attempts: 4
|
attempts: 4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Retry to send request 4 times
|
||||||
|
- "traefik.http.middlewares.test-retry.retry.attempts=4"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-retry.retry.attempts": "4"
|
"traefik.http.middlewares.test-retry.retry.attempts": "4"
|
||||||
|
@@ -30,6 +30,11 @@ spec:
|
|||||||
- /fiibar
|
- /fiibar
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
# Strip prefix /foobar and /fiibar
|
||||||
|
- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "/foobar,/fiibar"
|
"traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "/foobar,/fiibar"
|
||||||
@@ -85,3 +90,85 @@ If your backend is serving assets (e.g., images or Javascript files), chances ar
|
|||||||
Continuing on the example, the backend should return `/products/shoes/image.png` (and not `/images.png` which Traefik would likely not be able to associate with the same backend).
|
Continuing on the example, the backend should return `/products/shoes/image.png` (and not `/images.png` which Traefik would likely not be able to associate with the same backend).
|
||||||
|
|
||||||
The `X-Forwarded-Prefix` header can be queried to build such URLs dynamically.
|
The `X-Forwarded-Prefix` header can be queried to build such URLs dynamically.
|
||||||
|
|
||||||
|
### `forceSlash`
|
||||||
|
|
||||||
|
_Optional, Default=true_
|
||||||
|
|
||||||
|
```yaml tab="Docker"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.example.stripprefix.prefixes=/foobar"
|
||||||
|
- "traefik.http.middlewares.example.stripprefix.forceSlash=false"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: example
|
||||||
|
spec:
|
||||||
|
stripPrefix:
|
||||||
|
prefixes:
|
||||||
|
- "/foobar"
|
||||||
|
forceSlash: false
|
||||||
|
```
|
||||||
|
|
||||||
|
```json tab="Marathon"
|
||||||
|
"labels": {
|
||||||
|
"traefik.http.middlewares.example.stripprefix.prefixes": "/foobar",
|
||||||
|
"traefik.http.middlewares.example.stripprefix.forceSlash": "false"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Rancher"
|
||||||
|
labels:
|
||||||
|
- "traefik.http.middlewares.example.stripprefix.prefixes=/foobar"
|
||||||
|
- "traefik.http.middlewares.example.stripprefix.forceSlash=false"
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.example.stripPrefix]
|
||||||
|
prefixes = ["/foobar"]
|
||||||
|
forceSlash = false
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
example:
|
||||||
|
stripPrefix:
|
||||||
|
prefixes:
|
||||||
|
- "/foobar"
|
||||||
|
forceSlash: false
|
||||||
|
```
|
||||||
|
|
||||||
|
The `forceSlash` option makes sure that the resulting stripped path is not the empty string, by replacing it with `/` when necessary.
|
||||||
|
|
||||||
|
This option was added to keep the initial (non-intuitive) behavior of this middleware, in order to avoid introducing a breaking change.
|
||||||
|
|
||||||
|
It's recommended to explicitly set `forceSlash` to `false`.
|
||||||
|
|
||||||
|
??? info "Behavior examples"
|
||||||
|
|
||||||
|
- `forceSlash=true`
|
||||||
|
|
||||||
|
| Path | Prefix to strip | Result |
|
||||||
|
|------------|-----------------|--------|
|
||||||
|
| `/` | `/` | `/` |
|
||||||
|
| `/foo` | `/foo` | `/` |
|
||||||
|
| `/foo/` | `/foo` | `/` |
|
||||||
|
| `/foo/` | `/foo/` | `/` |
|
||||||
|
| `/bar` | `/foo` | `/bar` |
|
||||||
|
| `/foo/bar` | `/foo` | `/bar` |
|
||||||
|
|
||||||
|
- `forceSlash=false`
|
||||||
|
|
||||||
|
| Path | Prefix to strip | Result |
|
||||||
|
|------------|-----------------|--------|
|
||||||
|
| `/` | `/` | empty |
|
||||||
|
| `/foo` | `/foo` | empty |
|
||||||
|
| `/foo/` | `/foo` | `/` |
|
||||||
|
| `/foo/` | `/foo/` | empty |
|
||||||
|
| `/bar` | `/foo` | `/bar` |
|
||||||
|
| `/foo/bar` | `/foo` | `/bar` |
|
||||||
|
@@ -23,6 +23,10 @@ spec:
|
|||||||
- "/foo/[a-z0-9]+/[0-9]+/"
|
- "/foo/[a-z0-9]+/[0-9]+/"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```yaml tab="Consul Catalog"
|
||||||
|
- "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/"
|
||||||
|
```
|
||||||
|
|
||||||
```json tab="Marathon"
|
```json tab="Marathon"
|
||||||
"labels": {
|
"labels": {
|
||||||
"traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex": "/foo/[a-z0-9]+/[0-9]+/"
|
"traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex": "/foo/[a-z0-9]+/[0-9]+/"
|
||||||
|
@@ -10,7 +10,7 @@ feature by feature, of how the configuration looked like in v1, and how it now l
|
|||||||
|
|
||||||
!!! info "Migration Helper"
|
!!! info "Migration Helper"
|
||||||
|
|
||||||
We created a tool to help during the migration: [traefik-migration-tool](https://github.com/containous/traefik-migration-tool)
|
We created a tool to help during the migration: [traefik-migration-tool](https://github.com/traefik/traefik-migration-tool)
|
||||||
|
|
||||||
This tool allows to:
|
This tool allows to:
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Then any router can refer to an instance of the wanted middleware.
|
|||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="K8s Ingress"
|
```yaml tab="K8s Ingress"
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: traefik
|
name: traefik
|
||||||
@@ -50,7 +50,7 @@ Then any router can refer to an instance of the wanted middleware.
|
|||||||
traefik.ingress.kubernetes.io/rule-type: PathPrefix
|
traefik.ingress.kubernetes.io/rule-type: PathPrefix
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
- host: test.locahost
|
- host: test.localhost
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /test
|
- path: /test
|
||||||
@@ -97,14 +97,14 @@ Then any router can refer to an instance of the wanted middleware.
|
|||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.routers.router0.rule=Host(`bar.com`) && PathPrefix(`/test`)"
|
- "traefik.http.routers.router0.rule=Host(`test.localhost`) && PathPrefix(`/test`)"
|
||||||
- "traefik.http.routers.router0.middlewares=auth"
|
- "traefik.http.routers.router0.middlewares=auth"
|
||||||
- "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
- "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="K8s IngressRoute"
|
```yaml tab="K8s IngressRoute"
|
||||||
# The definitions below require the definitions for the Middleware and IngressRoute kinds.
|
# The definitions below require the definitions for the Middleware and IngressRoute kinds.
|
||||||
# https://docs.traefik.io/v2.0/providers/kubernetes-crd/#traefik-ingressroute-definition
|
# https://doc.traefik.io/traefik/v2.3/reference/dynamic-configuration/kubernetes-crd/#definitions
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
@@ -184,39 +184,39 @@ Then any router can refer to an instance of the wanted middleware.
|
|||||||
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||||
```
|
```
|
||||||
|
|
||||||
## TLS Configuration Is Now Dynamic, per Router.
|
## TLS Configuration is Now Dynamic, per Router.
|
||||||
|
|
||||||
TLS parameters used to be specified in the static configuration, as an entryPoint field.
|
TLS parameters used to be specified in the static configuration, as an entryPoint field.
|
||||||
With Traefik v2, a new dynamic TLS section at the root contains all the desired TLS configurations.
|
With Traefik v2, a new dynamic TLS section at the root contains all the desired TLS configurations.
|
||||||
Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one of the [TLS configurations](../https/tls.md) defined at the root, hence defining the [TLS configuration](../https/tls.md) for that router.
|
Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one of the [TLS configurations](../https/tls.md) defined at the root, hence defining the [TLS configuration](../https/tls.md) for that router.
|
||||||
|
|
||||||
!!! example "TLS on web-secure entryPoint becomes TLS option on Router-1"
|
!!! example "TLS on websecure entryPoint becomes TLS option on Router-1"
|
||||||
|
|
||||||
!!! info "v1"
|
!!! info "v1"
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# static configuration
|
# static configuration
|
||||||
[entryPoints]
|
[entryPoints]
|
||||||
[entryPoints.web-secure]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
|
|
||||||
[entryPoints.web-secure.tls]
|
[entryPoints.websecure.tls]
|
||||||
minVersion = "VersionTLS12"
|
minVersion = "VersionTLS12"
|
||||||
cipherSuites = [
|
cipherSuites = [
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
]
|
]
|
||||||
[[entryPoints.web-secure.tls.certificates]]
|
[[entryPoints.websecure.tls.certificates]]
|
||||||
certFile = "path/to/my.cert"
|
certFile = "path/to/my.cert"
|
||||||
keyFile = "path/to/my.key"
|
keyFile = "path/to/my.key"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--entryPoints='Name:web-secure Address::443 TLS:path/to/my.cert,path/to/my.key TLS.MinVersion:VersionTLS12 TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
|
--entryPoints='Name:websecure Address::443 TLS:path/to/my.cert,path/to/my.key TLS.MinVersion:VersionTLS12 TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
@@ -225,7 +225,7 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
|||||||
# dynamic configuration
|
# dynamic configuration
|
||||||
[http.routers]
|
[http.routers]
|
||||||
[http.routers.Router-1]
|
[http.routers.Router-1]
|
||||||
rule = "Host(`bar.com`)"
|
rule = "Host(`example.com`)"
|
||||||
service = "service-id"
|
service = "service-id"
|
||||||
# will terminate the TLS request
|
# will terminate the TLS request
|
||||||
[http.routers.Router-1.tls]
|
[http.routers.Router-1.tls]
|
||||||
@@ -236,26 +236,23 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
|||||||
keyFile = "/path/to/domain.key"
|
keyFile = "/path/to/domain.key"
|
||||||
|
|
||||||
[tls.options]
|
[tls.options]
|
||||||
[tls.options.default]
|
|
||||||
minVersion = "VersionTLS12"
|
|
||||||
|
|
||||||
[tls.options.myTLSOptions]
|
[tls.options.myTLSOptions]
|
||||||
minVersion = "VersionTLS13"
|
minVersion = "VersionTLS12"
|
||||||
cipherSuites = [
|
cipherSuites = [
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
||||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
|
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
|
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
http:
|
http:
|
||||||
routers:
|
routers:
|
||||||
Router-1:
|
Router-1:
|
||||||
rule: "Host(`bar.com`)"
|
rule: "Host(`example.com`)"
|
||||||
service: service-id
|
service: service-id
|
||||||
# will terminate the TLS request
|
# will terminate the TLS request
|
||||||
tls:
|
tls:
|
||||||
@@ -267,18 +264,18 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
|||||||
keyFile: /path/to/domain.key
|
keyFile: /path/to/domain.key
|
||||||
options:
|
options:
|
||||||
myTLSOptions:
|
myTLSOptions:
|
||||||
minVersion: VersionTLS13
|
minVersion: VersionTLS12
|
||||||
cipherSuites:
|
cipherSuites:
|
||||||
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
|
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="K8s IngressRoute"
|
```yaml tab="K8s IngressRoute"
|
||||||
# The definitions below require the definitions for the TLSOption and IngressRoute kinds.
|
# The definitions below require the definitions for the TLSOption and IngressRoute kinds.
|
||||||
# https://docs.traefik.io/v2.0/providers/kubernetes-crd/#traefik-ingressroute-definition
|
# https://doc.traefik.io/traefik/v2.3/reference/dynamic-configuration/kubernetes-crd/#definitions
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: TLSOption
|
kind: TLSOption
|
||||||
metadata:
|
metadata:
|
||||||
@@ -286,11 +283,11 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
|||||||
namespace: default
|
namespace: default
|
||||||
|
|
||||||
spec:
|
spec:
|
||||||
minVersion: VersionTLS13
|
minVersion: VersionTLS12
|
||||||
cipherSuites:
|
cipherSuites:
|
||||||
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
|
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
|
||||||
@@ -304,7 +301,7 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
routes:
|
routes:
|
||||||
- match: Host(`bar.com`)
|
- match: Host(`example.com`)
|
||||||
kind: Rule
|
kind: Rule
|
||||||
services:
|
services:
|
||||||
- name: whoami
|
- name: whoami
|
||||||
@@ -322,50 +319,122 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
|||||||
- "traefik.http.routers.router0.tls.options=myTLSOptions@file"
|
- "traefik.http.routers.router0.tls.options=myTLSOptions@file"
|
||||||
```
|
```
|
||||||
|
|
||||||
## HTTP to HTTPS Redirection Is Now Configured on Routers
|
## HTTP to HTTPS Redirection is Now Configured on Routers
|
||||||
|
|
||||||
Previously on Traefik v1, the redirection was applied on an entry point or on a frontend.
|
Previously on Traefik v1, the redirection was applied on an entry point or on a frontend.
|
||||||
With Traefik v2 it is applied on a [Router](../routing/routers/index.md).
|
With Traefik v2 it is applied on an entry point or a [Router](../routing/routers/index.md).
|
||||||
|
|
||||||
To apply a redirection, one of the redirect middlewares, [RedirectRegex](../middlewares/redirectregex.md) or [RedirectScheme](../middlewares/redirectscheme.md), has to be configured and added to the router middlewares list.
|
To apply a redirection:
|
||||||
|
|
||||||
!!! example "HTTP to HTTPS redirection"
|
- on an entry point, the [HTTP redirection](../routing/entrypoints.md#redirection) has to be configured.
|
||||||
|
- on a router, one of the redirect middlewares, [RedirectRegex](../middlewares/redirectregex.md) or [RedirectScheme](../middlewares/redirectscheme.md), has to be configured and added to the router middlewares list.
|
||||||
|
|
||||||
|
!!! example "Global HTTP to HTTPS redirection"
|
||||||
|
|
||||||
!!! info "v1"
|
!!! info "v1"
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# static configuration
|
# static configuration
|
||||||
defaultEntryPoints = ["http", "https"]
|
defaultEntryPoints = ["web", "websecure"]
|
||||||
|
|
||||||
[entryPoints]
|
[entryPoints]
|
||||||
[entryPoints.http]
|
[entryPoints.web]
|
||||||
address = ":80"
|
address = ":80"
|
||||||
[entryPoints.http.redirect]
|
[entryPoints.web.redirect]
|
||||||
entryPoint = "https"
|
entryPoint = "websecure"
|
||||||
|
|
||||||
[entryPoints.https]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.websecure.tls]
|
||||||
[[entryPoints.https.tls.certificates]]
|
|
||||||
certFile = "examples/traefik.crt"
|
|
||||||
keyFile = "examples/traefik.key"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--entrypoints=Name:web Address::80 Redirect.EntryPoint:web-secure
|
--entrypoints=Name:web Address::80 Redirect.EntryPoint:websecure
|
||||||
--entryPoints='Name:web-secure Address::443 TLS:path/to/my.cert,path/to/my.key'
|
--entryPoints='Name:websecure Address::443 TLS'
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info "v2"
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
## static configuration
|
||||||
|
|
||||||
|
--entrypoints.web.address=:80
|
||||||
|
--entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||||
|
--entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||||
|
--entrypoints.websecure.address=:443
|
||||||
|
--providers.docker=true
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# traefik.toml
|
||||||
|
## static configuration
|
||||||
|
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":80"
|
||||||
|
[entryPoints.web.http.redirections.entryPoint]
|
||||||
|
to = "websecure"
|
||||||
|
scheme = "https"
|
||||||
|
|
||||||
|
[entryPoints.websecure]
|
||||||
|
address = ":443"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# traefik.yaml
|
||||||
|
## static configuration
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: 80
|
||||||
|
http:
|
||||||
|
redirections:
|
||||||
|
entrypoint:
|
||||||
|
to: websecure
|
||||||
|
scheme: https
|
||||||
|
|
||||||
|
websecure:
|
||||||
|
address: 443
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! example "HTTP to HTTPS redirection per domain"
|
||||||
|
|
||||||
|
!!! info "v1"
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.websecure]
|
||||||
|
address = ":443"
|
||||||
|
[entryPoints.websecure.tls]
|
||||||
|
|
||||||
|
[file]
|
||||||
|
|
||||||
|
[frontends]
|
||||||
|
[frontends.frontend1]
|
||||||
|
entryPoints = ["web", "websecure"]
|
||||||
|
[frontends.frontend1.routes]
|
||||||
|
[frontends.frontend1.routes.route0]
|
||||||
|
rule = "Host:example.net"
|
||||||
|
[frontends.frontend1.redirect]
|
||||||
|
entryPoint = "websecure"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
- traefik.http.routers.web.rule=Host(`foo.com`)
|
traefik.http.routers.app.rule: Host(`example.net`)
|
||||||
- traefik.http.routers.web.entrypoints=web
|
traefik.http.routers.app.entrypoints: web
|
||||||
- traefik.http.routers.web.middlewares=redirect@file
|
traefik.http.routers.app.middlewares: https_redirect
|
||||||
- traefik.http.routers.web-secured.rule=Host(`foo.com`)
|
|
||||||
- traefik.http.routers.web-secured.entrypoints=web-secure
|
traefik.http.routers.appsecured.rule: Host(`example.net`)
|
||||||
- traefik.http.routers.web-secured.tls=true
|
traefik.http.routers.appsecured.entrypoints: websecure
|
||||||
|
traefik.http.routers.appsecured.tls: true
|
||||||
|
|
||||||
|
traefik.http.middlewares.https_redirect.redirectscheme.scheme: https
|
||||||
|
traefik.http.middlewares.https_redirect.redirectscheme.permanent: true
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="K8s IngressRoute"
|
```yaml tab="K8s IngressRoute"
|
||||||
@@ -378,13 +447,13 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
routes:
|
routes:
|
||||||
- match: Host(`foo.com`)
|
- match: Host(`example.net`)
|
||||||
kind: Rule
|
kind: Rule
|
||||||
services:
|
services:
|
||||||
- name: whoami
|
- name: whoami
|
||||||
port: 80
|
port: 80
|
||||||
middlewares:
|
middlewares:
|
||||||
- name: redirect
|
- name: https-redirect
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
@@ -394,7 +463,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
|
|||||||
|
|
||||||
spec:
|
spec:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- web-secure
|
- websecure
|
||||||
routes:
|
routes:
|
||||||
- match: Host(`foo`)
|
- match: Host(`foo`)
|
||||||
kind: Rule
|
kind: Rule
|
||||||
@@ -407,119 +476,76 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd
|
|||||||
apiVersion: traefik.containo.us/v1alpha1
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
name: redirect
|
name: https-redirect
|
||||||
spec:
|
spec:
|
||||||
redirectScheme:
|
redirectScheme:
|
||||||
scheme: https
|
scheme: https
|
||||||
|
permanent: true
|
||||||
```
|
```
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
## static configuration
|
|
||||||
# traefik.toml
|
|
||||||
|
|
||||||
[entryPoints.web]
|
|
||||||
address = ":80"
|
|
||||||
|
|
||||||
[entryPoints.web-secure]
|
|
||||||
address = ":443"
|
|
||||||
|
|
||||||
##---------------------##
|
|
||||||
|
|
||||||
## dynamic configuration
|
## dynamic configuration
|
||||||
# dynamic-conf.toml
|
# dynamic-conf.toml
|
||||||
|
|
||||||
[http.routers]
|
[http.routers]
|
||||||
[http.routers.router0]
|
[http.routers.router0]
|
||||||
rule = "Host(`foo.com`)"
|
rule = "Host(`example.net`)"
|
||||||
service = "my-service"
|
service = "my-service"
|
||||||
entrypoints = ["web"]
|
entrypoints = ["web"]
|
||||||
middlewares = ["redirect"]
|
middlewares = ["https_redirect"]
|
||||||
|
|
||||||
[http.routers.router1]
|
[http.routers.router1]
|
||||||
rule = "Host(`foo.com`)"
|
rule = "Host(`example.net`)"
|
||||||
service = "my-service"
|
service = "my-service"
|
||||||
entrypoints = ["web-secure"]
|
entrypoints = ["websecure"]
|
||||||
[http.routers.router1.tls]
|
[http.routers.router1.tls]
|
||||||
|
|
||||||
[http.services]
|
|
||||||
[[http.services.my-service.loadBalancer.servers]]
|
|
||||||
url = "http://10.10.10.1:80"
|
|
||||||
[[http.services.my-service.loadBalancer.servers]]
|
|
||||||
url = "http://10.10.10.2:80"
|
|
||||||
|
|
||||||
[http.middlewares]
|
[http.middlewares]
|
||||||
[http.middlewares.redirect.redirectScheme]
|
[http.middlewares.https_redirect.redirectScheme]
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
|
permanent = true
|
||||||
[[tls.certificates]]
|
|
||||||
certFile = "/path/to/domain.cert"
|
|
||||||
keyFile = "/path/to/domain.key"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
## static configuration
|
|
||||||
# traefik.yml
|
|
||||||
|
|
||||||
entryPoints:
|
|
||||||
web:
|
|
||||||
address: ":80"
|
|
||||||
|
|
||||||
web-secure:
|
|
||||||
address: ":443"
|
|
||||||
|
|
||||||
##---------------------##
|
|
||||||
|
|
||||||
## dynamic configuration
|
## dynamic configuration
|
||||||
# dynamic-conf.yml
|
# dynamic-conf.yml
|
||||||
|
|
||||||
http:
|
http:
|
||||||
routers:
|
routers:
|
||||||
router0:
|
router0:
|
||||||
rule: "Host(`foo.com`)"
|
rule: "Host(`example.net`)"
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
middlewares:
|
middlewares:
|
||||||
- redirect
|
- https_redirect
|
||||||
service: my-service
|
service: my-service
|
||||||
|
|
||||||
router1:
|
router1:
|
||||||
rule: "Host(`foo.com`)"
|
rule: "Host(`example.net`)"
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- web-secure
|
- websecure
|
||||||
service: my-service
|
service: my-service
|
||||||
tls: {}
|
tls: {}
|
||||||
|
|
||||||
services:
|
|
||||||
my-service:
|
|
||||||
loadBalancer:
|
|
||||||
servers:
|
|
||||||
- url: http://10.10.10.1:80
|
|
||||||
- url: http://10.10.10.2:80
|
|
||||||
|
|
||||||
middlewares:
|
middlewares:
|
||||||
redirect:
|
https-redirect:
|
||||||
redirectScheme:
|
redirectScheme:
|
||||||
scheme: https
|
scheme: https
|
||||||
|
permanent: true
|
||||||
tls:
|
|
||||||
certificates:
|
|
||||||
- certFile: /app/certs/server/server.pem
|
|
||||||
keyFile: /app/certs/server/server.pem
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Strip and Rewrite Path Prefixes
|
## Strip and Rewrite Path Prefixes
|
||||||
|
|
||||||
With the new core notions of v2 (introduced earlier in the section
|
With the new core notions of v2 (introduced earlier in the section
|
||||||
["Frontends and Backends Are Dead... Long Live Routers, Middlewares, and Services"](#frontends-and-backends-are-dead-long-live-routers-middlewares-and-services)),
|
["Frontends and Backends Are Dead... Long Live Routers, Middlewares, and Services"](#frontends-and-backends-are-dead-long-live-routers-middlewares-and-services)),
|
||||||
transforming the URL path prefix of incoming requests is configured with [middlewares](../../middlewares/overview/),
|
transforming the URL path prefix of incoming requests is configured with [middlewares](../middlewares/overview.md),
|
||||||
after the routing step with [router rule `PathPrefix`](https://docs.traefik.io/v2.0/routing/routers/#rule).
|
after the routing step with [router rule `PathPrefix`](../routing/routers/index.md#rule).
|
||||||
|
|
||||||
Use Case: Incoming requests to `http://company.org/admin` are forwarded to the webapplication "admin",
|
Use Case: Incoming requests to `http://example.org/admin` are forwarded to the webapplication "admin",
|
||||||
with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, you must:
|
with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, you must:
|
||||||
|
|
||||||
* First, configure a router named `admin` with a rule matching at least the path prefix with the `PathPrefix` keyword,
|
- First, configure a router named `admin` with a rule matching at least the path prefix with the `PathPrefix` keyword,
|
||||||
* Then, define a middlware of type [`stripprefix`](../../middlewares/stripprefix/), which remove the prefix `/admin`, associated to the router `admin`.
|
- Then, define a middleware of type [`stripprefix`](../middlewares/stripprefix.md), which removes the prefix `/admin`, associated to the router `admin`.
|
||||||
|
|
||||||
!!! example "Strip Path Prefix When Forwarding to Backend"
|
!!! example "Strip Path Prefix When Forwarding to Backend"
|
||||||
|
|
||||||
@@ -527,7 +553,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.frontend.rule=Host:company.org;PathPrefixStrip:/admin"
|
- "traefik.frontend.rule=Host:example.org;PathPrefixStrip:/admin"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes Ingress"
|
```yaml tab="Kubernetes Ingress"
|
||||||
@@ -540,7 +566,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
|
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
- host: company.org
|
- host: example.org
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /admin
|
- path: /admin
|
||||||
@@ -552,16 +578,16 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[frontends.admin]
|
[frontends.admin]
|
||||||
[frontends.admin.routes.admin_1]
|
[frontends.admin.routes.admin_1]
|
||||||
rule = "Host:company.org;PathPrefixStrip:/admin"
|
rule = "Host:example.org;PathPrefixStrip:/admin"
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
|
|
||||||
```yaml tab="Docker"
|
```yaml tab="Docker"
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.routers.admin.rule=Host(`company.org`) && PathPrefix(`/admin`)"
|
- "traefik.http.routers.admin.rule=Host(`example.org`) && PathPrefix(`/admin`)"
|
||||||
|
- "traefik.http.routers.admin.middlewares=admin-stripprefix"
|
||||||
- "traefik.http.middlewares.admin-stripprefix.stripprefix.prefixes=/admin"
|
- "traefik.http.middlewares.admin-stripprefix.stripprefix.prefixes=/admin"
|
||||||
- "traefik.http.routers.web.middlewares=admin-stripprefix@docker"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="Kubernetes IngressRoute"
|
```yaml tab="Kubernetes IngressRoute"
|
||||||
@@ -575,7 +601,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
entryPoints:
|
entryPoints:
|
||||||
- web
|
- web
|
||||||
routes:
|
routes:
|
||||||
- match: Host(`company.org`) && PathPrefix(`/admin`)
|
- match: Host(`example.org`) && PathPrefix(`/admin`)
|
||||||
kind: Rule
|
kind: Rule
|
||||||
services:
|
services:
|
||||||
- name: admin-svc
|
- name: admin-svc
|
||||||
@@ -583,6 +609,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
middlewares:
|
middlewares:
|
||||||
- name: admin-stripprefix
|
- name: admin-stripprefix
|
||||||
---
|
---
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
kind: Middleware
|
kind: Middleware
|
||||||
metadata:
|
metadata:
|
||||||
name: admin-stripprefix
|
name: admin-stripprefix
|
||||||
@@ -597,7 +624,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
# dynamic-conf.toml
|
# dynamic-conf.toml
|
||||||
|
|
||||||
[http.routers.router1]
|
[http.routers.router1]
|
||||||
rule = "Host(`company.org`) && PathPrefix(`/admin`)"
|
rule = "Host(`example.org`) && PathPrefix(`/admin`)"
|
||||||
service = "admin-svc"
|
service = "admin-svc"
|
||||||
entrypoints = ["web"]
|
entrypoints = ["web"]
|
||||||
middlewares = ["admin-stripprefix"]
|
middlewares = ["admin-stripprefix"]
|
||||||
@@ -620,7 +647,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
service: admin-svc
|
service: admin-svc
|
||||||
middlewares:
|
middlewares:
|
||||||
- "admin-stripprefix"
|
- "admin-stripprefix"
|
||||||
rule: "Host(`company.org`) && PathPrefix(`/admin`)"
|
rule: "Host(`example.org`) && PathPrefix(`/admin`)"
|
||||||
|
|
||||||
middlewares:
|
middlewares:
|
||||||
admin-stripprefix:
|
admin-stripprefix:
|
||||||
@@ -635,10 +662,10 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
|
|
||||||
Instead of removing the path prefix with the [`stripprefix` middleware](../../middlewares/stripprefix/), you can also:
|
Instead of removing the path prefix with the [`stripprefix` middleware](../../middlewares/stripprefix/), you can also:
|
||||||
|
|
||||||
* Add a path prefix with the [`addprefix` middleware](../../middlewares/addprefix/)
|
- Add a path prefix with the [`addprefix` middleware](../../middlewares/addprefix/)
|
||||||
* Replace the complete path of the request with the [`replacepath` middleware](../../middlewares/replacepath/)
|
- Replace the complete path of the request with the [`replacepath` middleware](../../middlewares/replacepath/)
|
||||||
* ReplaceRewrite path using Regexp with the [`replacepathregex` middleware](../../middlewares/replacepathregex/)
|
- ReplaceRewrite path using Regexp with the [`replacepathregex` middleware](../../middlewares/replacepathregex/)
|
||||||
* And a lot more on the [`middlewares` page](../../middlewares/overview/)
|
- And a lot more on the [`middlewares` page](../../middlewares/overview/)
|
||||||
|
|
||||||
## ACME (LetsEncrypt)
|
## ACME (LetsEncrypt)
|
||||||
|
|
||||||
@@ -650,34 +677,33 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# static configuration
|
# static configuration
|
||||||
defaultEntryPoints = ["web-secure","web"]
|
defaultEntryPoints = ["websecure","web"]
|
||||||
|
|
||||||
[entryPoints.web]
|
[entryPoints.web]
|
||||||
address = ":80"
|
address = ":80"
|
||||||
[entryPoints.web.redirect]
|
[entryPoints.web.redirect]
|
||||||
entryPoint = "webs"
|
entryPoint = "webs"
|
||||||
[entryPoints.web-secure]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
[entryPoints.https.tls]
|
[entryPoints.websecure.tls]
|
||||||
|
|
||||||
[acme]
|
[acme]
|
||||||
email = "your-email-here@my-awesome-app.org"
|
email = "your-email-here@example.com"
|
||||||
storage = "acme.json"
|
storage = "acme.json"
|
||||||
entryPoint = "web-secure"
|
entryPoint = "websecure"
|
||||||
onHostRule = true
|
onHostRule = true
|
||||||
[acme.httpChallenge]
|
[acme.tlsChallenge]
|
||||||
entryPoint = "web"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--defaultentrypoints=web-secure,web
|
--defaultentrypoints=websecure,web
|
||||||
--entryPoints=Name:web Address::80 Redirect.EntryPoint:web-secure
|
--entryPoints=Name:web Address::80 Redirect.EntryPoint:websecure
|
||||||
--entryPoints=Name:web-secure Address::443 TLS
|
--entryPoints=Name:websecure Address::443 TLS
|
||||||
--acme.email=your-email-here@my-awesome-app.org
|
--acme.email=your-email-here@example.com
|
||||||
--acme.storage=acme.json
|
--acme.storage=acme.json
|
||||||
--acme.entryPoint=web-secure
|
--acme.entryPoint=websecure
|
||||||
--acme.onHostRule=true
|
--acme.onHostRule=true
|
||||||
--acme.httpchallenge.entrypoint=http
|
--acme.tlschallenge=true
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
@@ -688,15 +714,15 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
[entryPoints.web]
|
[entryPoints.web]
|
||||||
address = ":80"
|
address = ":80"
|
||||||
|
|
||||||
[entryPoints.web-secure]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
|
[entryPoints.websecure.http.tls]
|
||||||
|
certResolver = "myresolver"
|
||||||
|
|
||||||
[certificatesResolvers.sample.acme]
|
[certificatesResolvers.myresolver.acme]
|
||||||
email = "your-email@your-domain.org"
|
email = "your-email@example.com"
|
||||||
storage = "acme.json"
|
storage = "acme.json"
|
||||||
[certificatesResolvers.sample.acme.httpChallenge]
|
[certificatesResolvers.myresolver.acme.tlsChallenge]
|
||||||
# used during the challenge
|
|
||||||
entryPoint = "web"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
@@ -704,25 +730,26 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo
|
|||||||
web:
|
web:
|
||||||
address: ":80"
|
address: ":80"
|
||||||
|
|
||||||
web-secure:
|
websecure:
|
||||||
address: ":443"
|
address: ":443"
|
||||||
|
http:
|
||||||
|
tls:
|
||||||
|
certResolver: myresolver
|
||||||
|
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
sample:
|
myresolver:
|
||||||
acme:
|
acme:
|
||||||
email: your-email@your-domain.org
|
email: your-email@example.com
|
||||||
storage: acme.json
|
storage: acme.json
|
||||||
httpChallenge:
|
tlsChallenge: {}
|
||||||
# used during the challenge
|
|
||||||
entryPoint: web
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--entryPoints.web.address=":80"
|
--entrypoints.web.address=:80
|
||||||
--entryPoints.websecure.address=":443"
|
--entrypoints.websecure.address=:443
|
||||||
--certificatesResolvers.sample.acme.email: your-email@your-domain.org
|
--certificatesresolvers.myresolver.acme.email=your-email@example.com
|
||||||
--certificatesResolvers.sample.acme.storage: acme.json
|
--certificatesresolvers.myresolver.acme.storage=acme.json
|
||||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint: web
|
--certificatesresolvers.myresolver.acme.tlschallenge=true
|
||||||
```
|
```
|
||||||
|
|
||||||
## Traefik Logs
|
## Traefik Logs
|
||||||
@@ -744,9 +771,9 @@ There is no more log configuration at the root level.
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--logLevel="DEBUG"
|
--logLevel=DEBUG
|
||||||
--traefikLog.filePath="/path/to/traefik.log"
|
--traefikLog.filePath=/path/to/traefik.log
|
||||||
--traefikLog.format="json"
|
--traefikLog.format=json
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
@@ -768,11 +795,18 @@ There is no more log configuration at the root level.
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--log.level="DEBUG"
|
--log.level=DEBUG
|
||||||
--log.filePath="/path/to/traefik.log"
|
--log.filePath=/path/to/traefik.log
|
||||||
--log.format="json"
|
--log.format=json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Access Logs
|
||||||
|
|
||||||
|
Access Logs are configured in the same way as before.
|
||||||
|
|
||||||
|
But all request headers are now filtered out by default in Traefik v2.
|
||||||
|
So during migration, you might want to consider enabling some needed fields (see [access log configuration](../observability/access-logs.md)).
|
||||||
|
|
||||||
## Tracing
|
## Tracing
|
||||||
|
|
||||||
Traefik v2 retains OpenTracing support. The `backend` root option from the v1 is gone, you just have to set your [tracing configuration](../observability/tracing/overview.md).
|
Traefik v2 retains OpenTracing support. The `backend` root option from the v1 is gone, you just have to set your [tracing configuration](../observability/tracing/overview.md).
|
||||||
@@ -794,12 +828,12 @@ Traefik v2 retains OpenTracing support. The `backend` root option from the v1 is
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.backend="jaeger"
|
--tracing.backend=jaeger
|
||||||
--tracing.servicename="tracing"
|
--tracing.servicename=tracing
|
||||||
--tracing.jaeger.localagenthostport="12.0.0.1:6831"
|
--tracing.jaeger.localagenthostport=12.0.0.1:6831
|
||||||
--tracing.jaeger.samplingparam="1.0"
|
--tracing.jaeger.samplingparam=1.0
|
||||||
--tracing.jaeger.samplingserverurl="http://12.0.0.1:5778/sampling"
|
--tracing.jaeger.samplingserverurl=http://12.0.0.1:5778/sampling
|
||||||
--tracing.jaeger.samplingtype="const"
|
--tracing.jaeger.samplingtype=const
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
@@ -827,11 +861,11 @@ Traefik v2 retains OpenTracing support. The `backend` root option from the v1 is
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.servicename="tracing"
|
--tracing.servicename=tracing
|
||||||
--tracing.jaeger.localagenthostport="12.0.0.1:6831"
|
--tracing.jaeger.localagenthostport=12.0.0.1:6831
|
||||||
--tracing.jaeger.samplingparam="1.0"
|
--tracing.jaeger.samplingparam=1.0
|
||||||
--tracing.jaeger.samplingserverurl="http://12.0.0.1:5778/sampling"
|
--tracing.jaeger.samplingserverurl=http://12.0.0.1:5778/sampling
|
||||||
--tracing.jaeger.samplingtype="const"
|
--tracing.jaeger.samplingtype=const
|
||||||
```
|
```
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
@@ -852,7 +886,7 @@ For a basic configuration, the [metrics configuration](../observability/metrics/
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.prometheus.buckets=[0.1,0.3,1.2,5.0]
|
--metrics.prometheus.buckets=[0.1,0.3,1.2,5.0]
|
||||||
--metrics.prometheus.entrypoint="traefik"
|
--metrics.prometheus.entrypoint=traefik
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info "v2"
|
!!! info "v2"
|
||||||
@@ -878,7 +912,7 @@ For a basic configuration, the [metrics configuration](../observability/metrics/
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.prometheus.buckets=[0.1,0.3,1.2,5.0]
|
--metrics.prometheus.buckets=[0.1,0.3,1.2,5.0]
|
||||||
--metrics.prometheus.entrypoint="metrics"
|
--metrics.prometheus.entrypoint=metrics
|
||||||
```
|
```
|
||||||
|
|
||||||
## No More Root Level Key/Values
|
## No More Root Level Key/Values
|
||||||
@@ -901,21 +935,21 @@ Each root item has been moved to a related section or removed.
|
|||||||
providersThrottleDuration = "2s"
|
providersThrottleDuration = "2s"
|
||||||
AllowMinWeightZero = true
|
AllowMinWeightZero = true
|
||||||
debug = true
|
debug = true
|
||||||
defaultEntryPoints = ["web", "web-secure"]
|
defaultEntryPoints = ["web", "websecure"]
|
||||||
keepTrailingSlash = false
|
keepTrailingSlash = false
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--checknewversion=false
|
--checknewversion=false
|
||||||
--sendanonymoususage=true
|
--sendanonymoususage=true
|
||||||
--loglevel="DEBUG"
|
--loglevel=DEBUG
|
||||||
--insecureskipverify=true
|
--insecureskipverify=true
|
||||||
--rootcas="/mycert.cert"
|
--rootcas=/mycert.cert
|
||||||
--maxidleconnsperhost=200
|
--maxidleconnsperhost=200
|
||||||
--providersthrottleduration="2s"
|
--providersthrottleduration=2s
|
||||||
--allowminweightzero=true
|
--allowminweightzero=true
|
||||||
--debug=true
|
--debug=true
|
||||||
--defaultentrypoints="web","web-secure"
|
--defaultentrypoints=web,websecure
|
||||||
--keeptrailingslash=true
|
--keeptrailingslash=true
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -961,9 +995,9 @@ Each root item has been moved to a related section or removed.
|
|||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--global.checknewversion=true
|
--global.checknewversion=true
|
||||||
--global.sendanonymoususage=true
|
--global.sendanonymoususage=true
|
||||||
--log.level="DEBUG"
|
--log.level=DEBUG
|
||||||
--serverstransport.insecureskipverify=true
|
--serverstransport.insecureskipverify=true
|
||||||
--serverstransport.rootcas="/mycert.cert"
|
--serverstransport.rootcas=/mycert.cert
|
||||||
--serverstransport.maxidleconnsperhost=42
|
--serverstransport.maxidleconnsperhost=42
|
||||||
--providers.providersthrottleduration=42
|
--providers.providersthrottleduration=42
|
||||||
```
|
```
|
||||||
@@ -971,14 +1005,11 @@ Each root item has been moved to a related section or removed.
|
|||||||
## Dashboard
|
## Dashboard
|
||||||
|
|
||||||
You need to activate the API to access the [dashboard](../operations/dashboard.md).
|
You need to activate the API to access the [dashboard](../operations/dashboard.md).
|
||||||
As the dashboard access is now secured by default you can either:
|
|
||||||
|
|
||||||
* define a [specific router](../operations/api.md#configuration) with the `api@internal` service and one authentication middleware like the following example
|
To activate the dashboard, you can either:
|
||||||
* or use the [unsecure](../operations/api.md#insecure) option of the API
|
|
||||||
|
|
||||||
!!! info "Dashboard with k8s and dedicated router"
|
- use the [secure mode](../operations/dashboard.md#secure-mode) with the `api@internal` service like in the following examples
|
||||||
|
- or use the [insecure mode](../operations/api.md#insecure)
|
||||||
As `api@internal` is not a Kubernetes service, you have to use the file provider or the `insecure` API option.
|
|
||||||
|
|
||||||
!!! example "Activate and access the dashboard"
|
!!! example "Activate and access the dashboard"
|
||||||
|
|
||||||
@@ -988,21 +1019,21 @@ As the dashboard access is now secured by default you can either:
|
|||||||
## static configuration
|
## static configuration
|
||||||
# traefik.toml
|
# traefik.toml
|
||||||
|
|
||||||
[entryPoints.web-secure]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
[entryPoints.web-secure.tls]
|
[entryPoints.websecure.tls]
|
||||||
[entryPoints.web-secure.auth]
|
[entryPoints.websecure.auth]
|
||||||
[entryPoints.web-secure.auth.basic]
|
[entryPoints.websecure.auth.basic]
|
||||||
users = [
|
users = [
|
||||||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
|
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
|
||||||
]
|
]
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
entryPoint = "web-secure"
|
entryPoint = "websecure"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--entryPoints='Name:web-secure Address::443 TLS Auth.Basic.Users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
|
--entryPoints='Name:websecure Address::443 TLS Auth.Basic.Users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
|
||||||
--api
|
--api
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1012,7 +1043,7 @@ As the dashboard access is now secured by default you can either:
|
|||||||
# dynamic configuration
|
# dynamic configuration
|
||||||
labels:
|
labels:
|
||||||
- "traefik.http.routers.api.rule=Host(`traefik.docker.localhost`)"
|
- "traefik.http.routers.api.rule=Host(`traefik.docker.localhost`)"
|
||||||
- "traefik.http.routers.api.entrypoints=web-secured"
|
- "traefik.http.routers.api.entrypoints=websecure"
|
||||||
- "traefik.http.routers.api.service=api@internal"
|
- "traefik.http.routers.api.service=api@internal"
|
||||||
- "traefik.http.routers.api.middlewares=myAuth"
|
- "traefik.http.routers.api.middlewares=myAuth"
|
||||||
- "traefik.http.routers.api.tls"
|
- "traefik.http.routers.api.tls"
|
||||||
@@ -1023,22 +1054,22 @@ As the dashboard access is now secured by default you can either:
|
|||||||
## static configuration
|
## static configuration
|
||||||
# traefik.toml
|
# traefik.toml
|
||||||
|
|
||||||
[entryPoints.web-secure]
|
[entryPoints.websecure]
|
||||||
address = ":443"
|
address = ":443"
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
|
|
||||||
[providers.file]
|
[providers.file]
|
||||||
filename = "/dynamic-conf.toml"
|
directory = "/path/to/dynamic/config"
|
||||||
|
|
||||||
##---------------------##
|
##---------------------##
|
||||||
|
|
||||||
## dynamic configuration
|
## dynamic configuration
|
||||||
# dynamic-conf.toml
|
# /path/to/dynamic/config/dynamic-conf.toml
|
||||||
|
|
||||||
[http.routers.api]
|
[http.routers.api]
|
||||||
rule = "Host(`traefik.docker.localhost`)"
|
rule = "Host(`traefik.docker.localhost`)"
|
||||||
entrypoints = ["web-secure"]
|
entrypoints = ["websecure"]
|
||||||
service = "api@internal"
|
service = "api@internal"
|
||||||
middlewares = ["myAuth"]
|
middlewares = ["myAuth"]
|
||||||
[http.routers.api.tls]
|
[http.routers.api.tls]
|
||||||
@@ -1054,26 +1085,26 @@ As the dashboard access is now secured by default you can either:
|
|||||||
# traefik.yaml
|
# traefik.yaml
|
||||||
|
|
||||||
entryPoints:
|
entryPoints:
|
||||||
web-secure:
|
websecure:
|
||||||
address: ':443'
|
address: ':443'
|
||||||
|
|
||||||
api: {}
|
api: {}
|
||||||
|
|
||||||
providers:
|
providers:
|
||||||
file:
|
file:
|
||||||
filename: /dynamic-conf.yaml
|
directory: /path/to/dynamic/config
|
||||||
|
|
||||||
##---------------------##
|
##---------------------##
|
||||||
|
|
||||||
## dynamic configuration
|
## dynamic configuration
|
||||||
# dynamic-conf.yaml
|
# /path/to/dynamic/config/dynamic-conf.yaml
|
||||||
|
|
||||||
http:
|
http:
|
||||||
routers:
|
routers:
|
||||||
api:
|
api:
|
||||||
rule: Host(`traefik.docker.localhost`)
|
rule: Host(`traefik.docker.localhost`)
|
||||||
entrypoints:
|
entrypoints:
|
||||||
- web-secure
|
- websecure
|
||||||
service: api@internal
|
service: api@internal
|
||||||
middlewares:
|
middlewares:
|
||||||
- myAuth
|
- myAuth
|
||||||
@@ -1090,28 +1121,28 @@ As the dashboard access is now secured by default you can either:
|
|||||||
|
|
||||||
Supported [providers](../providers/overview.md), for now:
|
Supported [providers](../providers/overview.md), for now:
|
||||||
|
|
||||||
* [ ] Azure Service Fabric
|
- [ ] Azure Service Fabric
|
||||||
* [ ] BoltDB
|
- [x] Consul
|
||||||
* [ ] Consul
|
- [x] Consul Catalog
|
||||||
* [ ] Consul Catalog
|
- [x] Docker
|
||||||
* [x] Docker
|
- [ ] DynamoDB
|
||||||
* [ ] DynamoDB
|
- [ ] ECS
|
||||||
* [ ] ECS
|
- [x] Etcd
|
||||||
* [ ] Etcd
|
- [ ] Eureka
|
||||||
* [ ] Eureka
|
- [x] File
|
||||||
* [x] File
|
- [x] Kubernetes Ingress
|
||||||
* [x] Kubernetes Ingress (without annotations)
|
- [x] Kubernetes IngressRoute
|
||||||
* [x] Kubernetes IngressRoute
|
- [x] Marathon
|
||||||
* [x] Marathon
|
- [ ] Mesos
|
||||||
* [ ] Mesos
|
- [x] Rancher
|
||||||
* [x] Rancher
|
- [x] Redis
|
||||||
* [x] Rest
|
- [x] Rest
|
||||||
* [ ] Zookeeper
|
- [x] Zookeeper
|
||||||
|
|
||||||
## Some Tips You Should Know
|
## Some Tips You Should Know
|
||||||
|
|
||||||
* Different sources of static configuration (file, CLI flags, ...) cannot be [mixed](../getting-started/configuration-overview.md#the-static-configuration).
|
- Different sources of static configuration (file, CLI flags, ...) cannot be [mixed](../getting-started/configuration-overview.md#the-static-configuration).
|
||||||
* Now, configuration elements can be referenced between different providers by using the provider namespace notation: `@<provider>`.
|
- Now, configuration elements can be referenced between different providers by using the provider namespace notation: `@<provider>`.
|
||||||
For instance, a router named `myrouter` in a File Provider can refer to a service named `myservice` defined in Docker Provider with the following notation: `myservice@docker`.
|
For instance, a router named `myrouter` in a File Provider can refer to a service named `myservice` defined in Docker Provider with the following notation: `myservice@docker`.
|
||||||
* Middlewares are applied in the same order as their declaration in router.
|
- Middlewares are applied in the same order as their declaration in router.
|
||||||
* If you have any questions feel free to join our [community forum](https://community.containo.us).
|
- If you have any questions feel free to join our [community forum](https://community.traefik.io).
|
||||||
|
338
docs/content/migration/v2.md
Normal file
338
docs/content/migration/v2.md
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
# Migration: Steps needed between the versions
|
||||||
|
|
||||||
|
## v2.0 to v2.1
|
||||||
|
|
||||||
|
### Kubernetes CRD
|
||||||
|
|
||||||
|
In v2.1, a new Kubernetes CRD called `TraefikService` was added.
|
||||||
|
While updating an installation to v2.1,
|
||||||
|
one should apply that CRD, and update the existing `ClusterRole` definition to allow Traefik to use that CRD.
|
||||||
|
|
||||||
|
To add that CRD and enhance the permissions, following definitions need to be applied to the cluster.
|
||||||
|
|
||||||
|
```yaml tab="TraefikService"
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: traefikservices.traefik.containo.us
|
||||||
|
|
||||||
|
spec:
|
||||||
|
group: traefik.containo.us
|
||||||
|
version: v1alpha1
|
||||||
|
names:
|
||||||
|
kind: TraefikService
|
||||||
|
plural: traefikservices
|
||||||
|
singular: traefikservice
|
||||||
|
scope: Namespaced
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="ClusterRole"
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
name: traefik-ingress-controller
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- services
|
||||||
|
- endpoints
|
||||||
|
- secrets
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- extensions
|
||||||
|
resources:
|
||||||
|
- ingresses
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- extensions
|
||||||
|
resources:
|
||||||
|
- ingresses/status
|
||||||
|
verbs:
|
||||||
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- traefik.containo.us
|
||||||
|
resources:
|
||||||
|
- middlewares
|
||||||
|
- ingressroutes
|
||||||
|
- traefikservices
|
||||||
|
- ingressroutetcps
|
||||||
|
- tlsoptions
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
```
|
||||||
|
|
||||||
|
After having both resources applied, Traefik will work properly.
|
||||||
|
|
||||||
|
## v2.1 to v2.2
|
||||||
|
|
||||||
|
### Headers middleware: accessControlAllowOrigin
|
||||||
|
|
||||||
|
`accessControlAllowOrigin` is deprecated.
|
||||||
|
This field will be removed in future 2.x releases.
|
||||||
|
Please configure your allowed origins in `accessControlAllowOriginList` instead.
|
||||||
|
|
||||||
|
### Kubernetes CRD
|
||||||
|
|
||||||
|
In v2.2, new Kubernetes CRDs called `TLSStore` and `IngressRouteUDP` were added.
|
||||||
|
While updating an installation to v2.2,
|
||||||
|
one should apply that CRDs, and update the existing `ClusterRole` definition to allow Traefik to use that CRDs.
|
||||||
|
|
||||||
|
To add that CRDs and enhance the permissions, following definitions need to be applied to the cluster.
|
||||||
|
|
||||||
|
```yaml tab="TLSStore"
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: tlsstores.traefik.containo.us
|
||||||
|
|
||||||
|
spec:
|
||||||
|
group: traefik.containo.us
|
||||||
|
version: v1alpha1
|
||||||
|
names:
|
||||||
|
kind: TLSStore
|
||||||
|
plural: tlsstores
|
||||||
|
singular: tlsstore
|
||||||
|
scope: Namespaced
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="IngressRouteUDP"
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: ingressrouteudps.traefik.containo.us
|
||||||
|
|
||||||
|
spec:
|
||||||
|
group: traefik.containo.us
|
||||||
|
version: v1alpha1
|
||||||
|
names:
|
||||||
|
kind: IngressRouteUDP
|
||||||
|
plural: ingressrouteudps
|
||||||
|
singular: ingressrouteudp
|
||||||
|
scope: Namespaced
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="ClusterRole"
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
name: traefik-ingress-controller
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- services
|
||||||
|
- endpoints
|
||||||
|
- secrets
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- extensions
|
||||||
|
resources:
|
||||||
|
- ingresses
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- extensions
|
||||||
|
resources:
|
||||||
|
- ingresses/status
|
||||||
|
verbs:
|
||||||
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- traefik.containo.us
|
||||||
|
resources:
|
||||||
|
- middlewares
|
||||||
|
- ingressroutes
|
||||||
|
- traefikservices
|
||||||
|
- ingressroutetcps
|
||||||
|
- ingressrouteudps
|
||||||
|
- tlsoptions
|
||||||
|
- tlsstores
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
After having both resources applied, Traefik will work properly.
|
||||||
|
|
||||||
|
### Kubernetes Ingress
|
||||||
|
|
||||||
|
To enable HTTPS, it is not sufficient anymore to only rely on a TLS section in the Ingress.
|
||||||
|
|
||||||
|
#### Expose an Ingress on 80 and 443
|
||||||
|
|
||||||
|
Define the default TLS configuration on the HTTPS entry point.
|
||||||
|
|
||||||
|
```yaml tab="Ingress"
|
||||||
|
kind: Ingress
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
name: example
|
||||||
|
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- secretName: myTlsSecret
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- host: example.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: "/foo"
|
||||||
|
backend:
|
||||||
|
serviceName: example-com
|
||||||
|
servicePort: 80
|
||||||
|
```
|
||||||
|
|
||||||
|
Entry points definition and enable Ingress provider:
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Static configuration
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: :80
|
||||||
|
websecure:
|
||||||
|
address: :443
|
||||||
|
http:
|
||||||
|
tls: {}
|
||||||
|
|
||||||
|
providers:
|
||||||
|
kubernetesIngress: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Static configuration
|
||||||
|
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.websecure]
|
||||||
|
address = ":443"
|
||||||
|
[entryPoints.websecure.http]
|
||||||
|
[entryPoints.websecure.http.tls]
|
||||||
|
|
||||||
|
[providers.kubernetesIngress]
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
# Static configuration
|
||||||
|
|
||||||
|
--entryPoints.web.address=:80
|
||||||
|
--entryPoints.websecure.address=:443
|
||||||
|
--entryPoints.websecure.http.tls=true
|
||||||
|
--providers.kubernetesIngress=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Use TLS only on one Ingress
|
||||||
|
|
||||||
|
Define the TLS restriction with annotations.
|
||||||
|
|
||||||
|
```yaml tab="Ingress"
|
||||||
|
kind: Ingress
|
||||||
|
apiVersion: networking.k8s.io/v1beta1
|
||||||
|
metadata:
|
||||||
|
name: example-tls
|
||||||
|
annotations:
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||||
|
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- secretName: myTlsSecret
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- host: example.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: ""
|
||||||
|
backend:
|
||||||
|
serviceName: example-com
|
||||||
|
servicePort: 80
|
||||||
|
```
|
||||||
|
|
||||||
|
Entry points definition and enable Ingress provider:
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Static configuration
|
||||||
|
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: :80
|
||||||
|
websecure:
|
||||||
|
address: :443
|
||||||
|
|
||||||
|
providers:
|
||||||
|
kubernetesIngress: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Static configuration
|
||||||
|
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":80"
|
||||||
|
|
||||||
|
[entryPoints.websecure]
|
||||||
|
address = ":443"
|
||||||
|
|
||||||
|
[providers.kubernetesIngress]
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
# Static configuration
|
||||||
|
|
||||||
|
--entryPoints.web.address=:80
|
||||||
|
--entryPoints.websecure.address=:443
|
||||||
|
--providers.kubernetesIngress=true
|
||||||
|
```
|
||||||
|
|
||||||
|
## v2.2.2 to v2.2.5
|
||||||
|
|
||||||
|
### InsecureSNI removal
|
||||||
|
|
||||||
|
In `v2.2.2` we introduced a new flag (`insecureSNI`) which was available as a global option to disable domain fronting.
|
||||||
|
Since `v2.2.5` this global option has been removed, and you should not use it anymore.
|
||||||
|
|
||||||
|
### HostSNI rule matcher removal
|
||||||
|
|
||||||
|
In `v2.2.2` we introduced a new rule matcher (`HostSNI`) for HTTP routers which was allowing to match the Server Name Indication at the router level.
|
||||||
|
Since `v2.2.5` this rule has been removed for HTTP routers, and you should not use it anymore.
|
||||||
|
|
||||||
|
## v2.2 to v2.3
|
||||||
|
|
||||||
|
### X.509 CommonName Deprecation
|
||||||
|
|
||||||
|
The deprecated, legacy behavior of treating the CommonName field on X.509 certificates as a host name when no Subject Alternative Names are present, is now disabled by default.
|
||||||
|
|
||||||
|
It means that if one is using https with your backend servers, and a certificate with only a CommonName,
|
||||||
|
Traefik will not try to match the server name indication with the CommonName anymore.
|
||||||
|
|
||||||
|
It can be temporarily re-enabled by adding the value `x509ignoreCN=0` to the `GODEBUG` environment variable.
|
||||||
|
|
||||||
|
More information: https://golang.org/doc/go1.15#commonname
|
||||||
|
|
||||||
|
### File Provider
|
||||||
|
|
||||||
|
The file parser has been changed, since v2.3 the unknown options/fields in a dynamic configuration file are treated as errors.
|
||||||
|
|
||||||
|
### IngressClass
|
||||||
|
|
||||||
|
In `v2.3`, the support of `IngressClass`, which is available since Kubernetes version `1.18`, has been introduced.
|
||||||
|
In order to be able to use this new resource the [Kubernetes RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) must be updated.
|
@@ -35,7 +35,7 @@ If the given format is unsupported, the default (CLF) is used instead.
|
|||||||
!!! info "Common Log Format"
|
!!! info "Common Log Format"
|
||||||
|
|
||||||
```html
|
```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
|
<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_router_name>" "<Traefik_server_URL>" <request_duration_in_ms>ms
|
||||||
```
|
```
|
||||||
|
|
||||||
### `bufferingSize`
|
### `bufferingSize`
|
||||||
@@ -61,7 +61,7 @@ accessLog:
|
|||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# Configuring a buffer of 100 lines
|
# Configuring a buffer of 100 lines
|
||||||
--accesslog=true
|
--accesslog=true
|
||||||
--accesslog.filepath="/path/to/access.log"
|
--accesslog.filepath=/path/to/access.log
|
||||||
--accesslog.bufferingsize=100
|
--accesslog.bufferingsize=100
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -104,16 +104,16 @@ accessLog:
|
|||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# Configuring Multiple Filters
|
# Configuring Multiple Filters
|
||||||
--accesslog=true
|
--accesslog=true
|
||||||
--accesslog.filepath="/path/to/access.log"
|
--accesslog.filepath=/path/to/access.log
|
||||||
--accesslog.format="json"
|
--accesslog.format=json
|
||||||
--accesslog.filters.statuscodes="200, 300-302"
|
--accesslog.filters.statuscodes=200,300-302
|
||||||
--accesslog.filters.retryattempts
|
--accesslog.filters.retryattempts
|
||||||
--accesslog.filters.minduration="10ms"
|
--accesslog.filters.minduration=10ms
|
||||||
```
|
```
|
||||||
|
|
||||||
### Limiting the Fields
|
### Limiting the Fields/Including Headers
|
||||||
|
|
||||||
You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.header` options
|
You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.headers` options.
|
||||||
|
|
||||||
Each field can be set to:
|
Each field can be set to:
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ Each field can be set to:
|
|||||||
- `drop` to drop the value
|
- `drop` to drop the value
|
||||||
- `redact` to replace the value with "redacted"
|
- `redact` to replace the value with "redacted"
|
||||||
|
|
||||||
The `defaultMode` for `fields.header` is `drop`.
|
The `defaultMode` for `fields.headers` is `drop`.
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
# Limiting the Logs to Specific Fields
|
# Limiting the Logs to Specific Fields
|
||||||
@@ -164,14 +164,14 @@ accessLog:
|
|||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# Limiting the Logs to Specific Fields
|
# Limiting the Logs to Specific Fields
|
||||||
--accesslog=true
|
--accesslog=true
|
||||||
--accesslog.filepath="/path/to/access.log"
|
--accesslog.filepath=/path/to/access.log
|
||||||
--accesslog.format="json"
|
--accesslog.format=json
|
||||||
--accesslog.fields.defaultmode="keep"
|
--accesslog.fields.defaultmode=keep
|
||||||
--accesslog.fields.names.ClientUsername="drop"
|
--accesslog.fields.names.ClientUsername=drop
|
||||||
--accesslog.fields.headers.defaultmode="keep"
|
--accesslog.fields.headers.defaultmode=keep
|
||||||
--accesslog.fields.headers.names.User-Agent="redact"
|
--accesslog.fields.headers.names.User-Agent=redact
|
||||||
--accesslog.fields.headers.names.Authorization="drop"
|
--accesslog.fields.headers.names.Authorization=drop
|
||||||
--accesslog.fields.headers.names.Content-Type="keep"
|
--accesslog.fields.headers.names.Content-Type=keep
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "Available Fields"
|
??? info "Available Fields"
|
||||||
@@ -181,10 +181,10 @@ accessLog:
|
|||||||
| `StartUTC` | The time at which request processing started. |
|
| `StartUTC` | The time at which request processing started. |
|
||||||
| `StartLocal` | The local time at which request processing started. |
|
| `StartLocal` | The local time at which request processing started. |
|
||||||
| `Duration` | The total time taken (in nanoseconds) by processing the response, including the origin server's time but not the log writing time. |
|
| `Duration` | The total time taken (in nanoseconds) by processing the response, including the origin server's time but not the log writing time. |
|
||||||
| `FrontendName` | The name of the Traefik frontend. |
|
| `RouterName` | The name of the Traefik router. |
|
||||||
| `BackendName` | The name of the Traefik backend. |
|
| `ServiceName` | The name of the Traefik backend. |
|
||||||
| `BackendURL` | The URL of the Traefik backend. |
|
| `ServiceURL` | The URL of the Traefik backend. |
|
||||||
| `BackendAddr` | The IP:port of the Traefik backend (extracted from `BackendURL`) |
|
| `ServiceAddr` | The IP:port of the Traefik backend (extracted from `ServiceURL`) |
|
||||||
| `ClientAddr` | The remote address in its original form (usually IP:port). |
|
| `ClientAddr` | The remote address in its original form (usually IP:port). |
|
||||||
| `ClientHost` | The remote IP address from which the client request was received. |
|
| `ClientHost` | The remote IP address from which the client request was received. |
|
||||||
| `ClientPort` | The remote TCP port from which the client request was received. |
|
| `ClientPort` | The remote TCP port from which the client request was received. |
|
||||||
@@ -195,6 +195,7 @@ accessLog:
|
|||||||
| `RequestMethod` | The HTTP method. |
|
| `RequestMethod` | The HTTP method. |
|
||||||
| `RequestPath` | The HTTP request URI, not including the scheme, host or port. |
|
| `RequestPath` | The HTTP request URI, not including the scheme, host or port. |
|
||||||
| `RequestProtocol` | The version of HTTP requested. |
|
| `RequestProtocol` | The version of HTTP requested. |
|
||||||
|
| `RequestScheme` | The HTTP scheme requested `http` or `https`. |
|
||||||
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
|
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
|
||||||
| `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. |
|
| `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. |
|
| `OriginDuration` | The time taken by the origin server ('upstream') to return its response. |
|
||||||
@@ -216,3 +217,32 @@ This allows the logs to be rotated and processed by an external program, such as
|
|||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
This does not work on Windows due to the lack of USR signals.
|
This does not work on Windows due to the lack of USR signals.
|
||||||
|
|
||||||
|
## Time Zones
|
||||||
|
|
||||||
|
Traefik will timestamp each log line in UTC time by default.
|
||||||
|
|
||||||
|
It is possible to configure the Traefik to timestamp in a specific timezone by ensuring the following configuration has been made in your environment:
|
||||||
|
|
||||||
|
1. Provide time zone data to `/etc/localtime` or `/usr/share/zoneinfo` (based on your distribution) or set the environment variable TZ to the desired timezone
|
||||||
|
2. Specify the field `StartLocal` by dropping the field named `StartUTC` (available on the default Common Log Format (CLF) as well as JSON)
|
||||||
|
|
||||||
|
Example utilizing Docker Compose:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:v2.2
|
||||||
|
environment:
|
||||||
|
- TZ=US/Alaska
|
||||||
|
command:
|
||||||
|
- --accesslog
|
||||||
|
- --accesslog.fields.names.StartUTC=drop
|
||||||
|
- --providers.docker
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
```
|
||||||
|
@@ -30,7 +30,7 @@ log:
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# Writing Logs to a File
|
# Writing Logs to a File
|
||||||
--log.filePath="/path/to/traefik.log"
|
--log.filePath=/path/to/traefik.log
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `format`
|
#### `format`
|
||||||
@@ -53,8 +53,8 @@ log:
|
|||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
# Writing Logs to a File, in JSON
|
# Writing Logs to a File, in JSON
|
||||||
--log.filePath="/path/to/traefik.log"
|
--log.filePath=/path/to/traefik.log
|
||||||
--log.format="json"
|
--log.format=json
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `level`
|
#### `level`
|
||||||
@@ -72,7 +72,7 @@ log:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--log.level="DEBUG"
|
--log.level=DEBUG
|
||||||
```
|
```
|
||||||
|
|
||||||
## Log Rotation
|
## Log Rotation
|
||||||
|
@@ -35,7 +35,7 @@ metrics:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.datadog.address="127.0.0.1:8125"
|
--metrics.datadog.address=127.0.0.1:8125
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `addEntryPointsLabels`
|
#### `addEntryPointsLabels`
|
||||||
|
@@ -35,7 +35,7 @@ metrics:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.influxdb.address="localhost:8089"
|
--metrics.influxdb.address=localhost:8089
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `protocol`
|
#### `protocol`
|
||||||
@@ -57,7 +57,7 @@ metrics:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.influxdb.protocol="udp"
|
--metrics.influxdb.protocol=udp
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `database`
|
#### `database`
|
||||||
@@ -69,17 +69,17 @@ InfluxDB database used when protocol is http.
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[metrics]
|
[metrics]
|
||||||
[metrics.influxDB]
|
[metrics.influxDB]
|
||||||
database = ""
|
database = "db"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
metrics:
|
metrics:
|
||||||
influxDB:
|
influxDB:
|
||||||
database: ""
|
database: "db"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.influxdb.database=""
|
--metrics.influxdb.database=db
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `retentionPolicy`
|
#### `retentionPolicy`
|
||||||
@@ -91,17 +91,17 @@ InfluxDB retention policy used when protocol is http.
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[metrics]
|
[metrics]
|
||||||
[metrics.influxDB]
|
[metrics.influxDB]
|
||||||
retentionPolicy = ""
|
retentionPolicy = "two_hours"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
metrics:
|
metrics:
|
||||||
influxDB:
|
influxDB:
|
||||||
retentionPolicy: ""
|
retentionPolicy: "two_hours"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.influxdb.retentionPolicy=""
|
--metrics.influxdb.retentionPolicy=two_hours
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `username`
|
#### `username`
|
||||||
@@ -113,17 +113,17 @@ InfluxDB username (only with http).
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[metrics]
|
[metrics]
|
||||||
[metrics.influxDB]
|
[metrics.influxDB]
|
||||||
username = ""
|
username = "john"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
metrics:
|
metrics:
|
||||||
influxDB:
|
influxDB:
|
||||||
username: ""
|
username: "john"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.influxdb.username=""
|
--metrics.influxdb.username=john
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `password`
|
#### `password`
|
||||||
@@ -135,17 +135,17 @@ InfluxDB password (only with http).
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[metrics]
|
[metrics]
|
||||||
[metrics.influxDB]
|
[metrics.influxDB]
|
||||||
password = ""
|
password = "secret"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
metrics:
|
metrics:
|
||||||
influxDB:
|
influxDB:
|
||||||
password: ""
|
password: "secret"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.influxdb.password=""
|
--metrics.influxdb.password=secret
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `addEntryPointsLabels`
|
#### `addEntryPointsLabels`
|
||||||
|
@@ -113,6 +113,28 @@ metrics:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--entryPoints.metrics.address=":8082"
|
--entryPoints.metrics.address=:8082
|
||||||
--metrics.prometheus.entryPoint="metrics"
|
--metrics.prometheus.entryPoint=metrics
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `manualRouting`
|
||||||
|
|
||||||
|
_Optional, Default=false_
|
||||||
|
|
||||||
|
If `manualRouting` is `true`, it disables the default internal router in order to allow one to create a custom router for the `prometheus@internal` service.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.prometheus]
|
||||||
|
manualRouting = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
prometheus:
|
||||||
|
manualRouting: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.prometheus.manualrouting=true
|
||||||
```
|
```
|
||||||
|
@@ -35,7 +35,7 @@ metrics:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.statsd.address="localhost:8125"
|
--metrics.statsd.address=localhost:8125
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `addEntryPointsLabels`
|
#### `addEntryPointsLabels`
|
||||||
@@ -103,3 +103,25 @@ metrics:
|
|||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--metrics.statsd.pushInterval=10s
|
--metrics.statsd.pushInterval=10s
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `prefix`
|
||||||
|
|
||||||
|
_Optional, Default="traefik"_
|
||||||
|
|
||||||
|
The prefix to use for metrics collection.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.statsD]
|
||||||
|
prefix = "traefik"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
statsD:
|
||||||
|
prefix: traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.statsd.prefix="traefik"
|
||||||
|
```
|
@@ -35,7 +35,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.datadog.localAgentHostPort="127.0.0.1:8126"
|
--tracing.datadog.localAgentHostPort=127.0.0.1:8126
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `debug`
|
#### `debug`
|
||||||
@@ -79,7 +79,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.datadog.globalTag="sample"
|
--tracing.datadog.globalTag=sample
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `prioritySampling`
|
#### `prioritySampling`
|
||||||
|
88
docs/content/observability/tracing/elastic.md
Normal file
88
docs/content/observability/tracing/elastic.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Elastic
|
||||||
|
|
||||||
|
To enable the Elastic:
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.elastic]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
elastic: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.elastic=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `serverURL`
|
||||||
|
|
||||||
|
_Optional, Default="http://localhost:8200"_
|
||||||
|
|
||||||
|
APM ServerURL is the URL of the Elastic APM server.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.elastic]
|
||||||
|
serverURL = "http://apm:8200"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
elastic:
|
||||||
|
serverURL: "http://apm:8200"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.elastic.serverurl="http://apm:8200"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `secretToken`
|
||||||
|
|
||||||
|
_Optional, Default=""_
|
||||||
|
|
||||||
|
APM Secret Token is the token used to connect to Elastic APM Server.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.elastic]
|
||||||
|
secretToken = "mytoken"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
elastic:
|
||||||
|
secretToken: "mytoken"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.elastic.secrettoken="mytoken"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `serviceEnvironment`
|
||||||
|
|
||||||
|
_Optional, Default=""_
|
||||||
|
|
||||||
|
APM Service Environment is the name of the environment Traefik is deployed in, e.g. `production` or `staging`.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.elastic]
|
||||||
|
serviceEnvironment = "production"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
elastic:
|
||||||
|
serviceEnvironment: "production"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.elastic.serviceenvironment="production"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Further
|
||||||
|
|
||||||
|
Additional configuration of Elastic APM Go agent can be done using environment variables.
|
||||||
|
See [APM Go agent reference](https://www.elastic.co/guide/en/apm/agent/go/current/configuration.html).
|
@@ -35,29 +35,29 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.haystack.localAgentHost="127.0.0.1"
|
--tracing.haystack.localAgentHost=127.0.0.1
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `localAgentPort`
|
#### `localAgentPort`
|
||||||
|
|
||||||
_Require, Default=42699_
|
_Require, Default=35000_
|
||||||
|
|
||||||
Local Agent port instructs reporter to send spans to the haystack-agent at this port.
|
Local Agent port instructs reporter to send spans to the haystack-agent at this port.
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[tracing]
|
[tracing]
|
||||||
[tracing.haystack]
|
[tracing.haystack]
|
||||||
localAgentPort = 42699
|
localAgentPort = 35000
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
tracing:
|
tracing:
|
||||||
haystack:
|
haystack:
|
||||||
localAgentPort: 42699
|
localAgentPort: 35000
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.haystack.localAgentPort=42699
|
--tracing.haystack.localAgentPort=35000
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `globalTag`
|
#### `globalTag`
|
||||||
@@ -79,7 +79,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.haystack.globalTag="sample:test"
|
--tracing.haystack.globalTag=sample:test
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `traceIDHeaderName`
|
#### `traceIDHeaderName`
|
||||||
@@ -91,61 +91,61 @@ Specifies the header name that will be used to store the trace ID.
|
|||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[tracing]
|
[tracing]
|
||||||
[tracing.haystack]
|
[tracing.haystack]
|
||||||
traceIDHeaderName = "sample"
|
traceIDHeaderName = "Trace-ID"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
tracing:
|
tracing:
|
||||||
haystack:
|
haystack:
|
||||||
traceIDHeaderName: sample
|
traceIDHeaderName: Trace-ID
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.haystack.traceIDHeaderName="sample"
|
--tracing.haystack.traceIDHeaderName=Trace-ID
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `parentIDHeaderName`
|
#### `parentIDHeaderName`
|
||||||
|
|
||||||
_Optional, Default=empty_
|
_Optional, Default=empty_
|
||||||
|
|
||||||
|
Specifies the header name that will be used to store the parent ID.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.haystack]
|
||||||
|
parentIDHeaderName = "Parent-Message-ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
haystack:
|
||||||
|
parentIDHeaderName: Parent-Message-ID
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.haystack.parentIDHeaderName=Parent-Message-ID
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `spanIDHeaderName`
|
||||||
|
|
||||||
|
_Optional, Default=empty_
|
||||||
|
|
||||||
Specifies the header name that will be used to store the span ID.
|
Specifies the header name that will be used to store the span ID.
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
```toml tab="File (TOML)"
|
||||||
[tracing]
|
[tracing]
|
||||||
[tracing.haystack]
|
[tracing.haystack]
|
||||||
parentIDHeaderName = "sample"
|
spanIDHeaderName = "Message-ID"
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
```yaml tab="File (YAML)"
|
||||||
tracing:
|
tracing:
|
||||||
haystack:
|
haystack:
|
||||||
parentIDHeaderName: "sample"
|
spanIDHeaderName: Message-ID
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.haystack.parentIDHeaderName="sample"
|
--tracing.haystack.spanIDHeaderName=Message-ID
|
||||||
```
|
|
||||||
|
|
||||||
#### `spanIDHeaderName`
|
|
||||||
|
|
||||||
_Optional, Default=empty_
|
|
||||||
|
|
||||||
Apply shared tag in a form of Key:Value to all the traces.
|
|
||||||
|
|
||||||
```toml tab="File (TOML)"
|
|
||||||
[tracing]
|
|
||||||
[tracing.haystack]
|
|
||||||
spanIDHeaderName = "sample:test"
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml tab="File (YAML)"
|
|
||||||
tracing:
|
|
||||||
haystack:
|
|
||||||
spanIDHeaderName: "sample:test"
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash tab="CLI"
|
|
||||||
--tracing.haystack.spanIDHeaderName=sample:test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `baggagePrefixHeaderName`
|
#### `baggagePrefixHeaderName`
|
||||||
@@ -168,5 +168,5 @@ tracing:
|
|||||||
|
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.haystack.baggagePrefixHeaderName="sample"
|
--tracing.haystack.baggagePrefixHeaderName=sample
|
||||||
```
|
```
|
||||||
|
@@ -35,7 +35,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.instana.localAgentHost="127.0.0.1"
|
--tracing.instana.localAgentHost=127.0.0.1
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `localAgentPort`
|
#### `localAgentPort`
|
||||||
@@ -86,5 +86,5 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.instana.logLevel="info"
|
--tracing.instana.logLevel=info
|
||||||
```
|
```
|
||||||
|
@@ -39,7 +39,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.samplingServerURL="http://localhost:5778/sampling"
|
--tracing.jaeger.samplingServerURL=http://localhost:5778/sampling
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `samplingType`
|
#### `samplingType`
|
||||||
@@ -61,7 +61,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.samplingType="const"
|
--tracing.jaeger.samplingType=const
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `samplingParam`
|
#### `samplingParam`
|
||||||
@@ -89,7 +89,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.samplingParam="1.0"
|
--tracing.jaeger.samplingParam=1.0
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `localAgentHostPort`
|
#### `localAgentHostPort`
|
||||||
@@ -111,7 +111,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.localAgentHostPort="127.0.0.1:6831"
|
--tracing.jaeger.localAgentHostPort=127.0.0.1:6831
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `gen128Bit`
|
#### `gen128Bit`
|
||||||
@@ -159,7 +159,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.propagation="jaeger"
|
--tracing.jaeger.propagation=jaeger
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `traceContextHeaderName`
|
#### `traceContextHeaderName`
|
||||||
@@ -182,7 +182,30 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.traceContextHeaderName="uber-trace-id"
|
--tracing.jaeger.traceContextHeaderName=uber-trace-id
|
||||||
|
```
|
||||||
|
|
||||||
|
### disableAttemptReconnecting
|
||||||
|
|
||||||
|
_Optional, Default=true_
|
||||||
|
|
||||||
|
Disable the UDP connection helper that periodically re-resolves the agent's hostname and reconnects if there was a change.
|
||||||
|
Enabling the re-resolving of UDP address make the client more robust in Kubernetes deployments.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[tracing]
|
||||||
|
[tracing.jaeger]
|
||||||
|
disableAttemptReconnecting = false
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
tracing:
|
||||||
|
jaeger:
|
||||||
|
disableAttemptReconnecting: false
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--tracing.jaeger.disableAttemptReconnecting=false
|
||||||
```
|
```
|
||||||
|
|
||||||
### `collector`
|
### `collector`
|
||||||
@@ -206,7 +229,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.collector.endpoint="http://127.0.0.1:14268/api/traces?format=jaeger.thrift"
|
--tracing.jaeger.collector.endpoint=http://127.0.0.1:14268/api/traces?format=jaeger.thrift
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `user`
|
#### `user`
|
||||||
@@ -229,7 +252,7 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.collector.user="my-user"
|
--tracing.jaeger.collector.user=my-user
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `password`
|
#### `password`
|
||||||
@@ -252,5 +275,5 @@ tracing:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--tracing.jaeger.collector.password="my-password"
|
--tracing.jaeger.collector.password=my-password
|
||||||
```
|
```
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user