1
0
mirror of https://github.com/containous/traefik.git synced 2025-09-30 17:44:25 +03:00

Compare commits

..

48 Commits
v3.4.1 ... v3.4

Author SHA1 Message Date
Sheddy
ba0f7364f1 Update Migration Docs 2025-07-24 18:06:04 +02:00
Romain
43162507e3 Add a note for the removal of default MPTCP enablement in the migration guide 2025-07-23 12:04:04 +02:00
Romain
9bf14b6764 Prepare release v3.4.5 2025-07-23 11:16:04 +02:00
kevinpollet
16d43aefd7 Merge branch v2.11 into v3.4 2025-07-23 10:41:06 +02:00
Romain
c6daab54e3 Prepare release v2.11.28 2025-07-23 10:34:04 +02:00
Michael
a59bcb29b5 Improve integration tests 2025-07-23 09:56:04 +02:00
romain
6486cf95d8 Merge branch v2.11 into v3.4 2025-07-22 16:11:58 +02:00
Jesper Noordsij
50931813f2 Remove all mentions of ordering for TLSOption CurvePreferences field 2025-07-22 15:44:05 +02:00
GreyXor
96386b1d78 Bump github.com/quic-go/quic-go to v0.54.0 2025-07-22 14:54:04 +02:00
Zeroday BYTE
5ef853a0c5 Fix client arbitrary file access during archive extraction zipslip 2025-07-22 14:24:05 +02:00
Romain
b2b4b66b08 Disable MPTCP by default
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2025-07-22 11:10:05 +02:00
Harold Ozouf
27326e6569 Redact logged install configuration 2025-07-18 17:16:04 +02:00
Adrien Kunysz
f2b7d7f6e1 Fix typo 2025-07-17 15:28:05 +02:00
Kevin Pollet
95434e870b Prepare release v3.4.4 2025-07-11 10:26:04 +02:00
kevinpollet
aa1c0d8686 Merge branch v2.11 into v3.4 2025-07-11 09:35:25 +02:00
Kevin Pollet
7ca90a4b18 Prepare release v2.11.27 2025-07-11 09:30:05 +02:00
Kevin Pollet
a3685ee9fa Bump github.com/go-viper/mapstructure/v2 to v2.3.0 2025-07-10 16:10:05 +02:00
Kevin Pollet
ba595bfa98 Fix concurrent access to balancer status map in WRR and P2C strategies 2025-07-10 16:08:04 +02:00
Dylan Rodgers
9a46d35169 Update index.md to include full Traefik Platform context 2025-07-09 11:54:04 +02:00
Kevin Pollet
955f484d33 Fix label for overriding swarm network on container 2025-07-08 17:46:05 +02:00
Simon Delicata
cdacf0bca8 Respect service.nativelb=false annotation when nativeLBByDefault is enabled 2025-07-08 11:58:04 +02:00
Sheddy
d674b393a8 Add New Expose Guides to the Documentation 2025-07-04 10:14:04 +02:00
Sheddy
137efedba7 Update Logs and Accesslogs Reference Documentation with OTLP Options 2025-07-01 08:54:04 +02:00
Sheddy
c69a8b5cdb Add New Setup Guides to the Documentation 2025-06-30 09:28:04 +02:00
Romain
b0e246cea9 Prepare release v3.4.3 2025-06-26 15:18:04 +02:00
Joshua
c9c8cd6b50 Bump quic-go to v.0.49.0 2025-06-26 14:46:04 +02:00
Romain
a519180665 Prepare release v3.4.2 2025-06-26 12:30:04 +02:00
romain
e223116225 Merge branch v2.11 into v3.4 2025-06-26 12:05:16 +02:00
Romain
8ae0379171 Prepare release v2.11.26 2025-06-26 11:50:04 +02:00
Sheddy
4daf13b866 Update the EntryPoints Documentation 2025-06-25 14:30:04 +02:00
Adrien Kunysz
c2c488ffc5 Remove conflicting information from the CircuitBreaker documentation. 2025-06-25 11:12:04 +02:00
Sheddy
107efb8a5a Add New Observe Guides to the Documentation 2025-06-23 17:06:04 +02:00
Sheddy
0f862f4792 Update Getting started Section with New Docker and Kubernetes Tutorial 2025-06-20 17:36:04 +02:00
romain
74eafcd044 Merge branch v2.11 into v3.4 2025-06-11 10:03:28 +02:00
Romain
b0d8e08e2b Fix typo in redirect middleware documentation 2025-06-11 09:46:05 +02:00
Etienne Dysli Metref
917771739e Add a note about Ingress Backend Resource support 2025-06-04 16:22:04 +02:00
Kevin Pollet
ae79d4e5f0 Do not log redis sentinel username and password 2025-06-04 12:08:04 +02:00
Alexy Van Den Abele
aac8bc69ad Clarify mirroring service default percent value 2025-06-04 11:18:04 +02:00
Romain
bfcef58a4f Fix KV reference rendering 2025-06-03 16:56:04 +02:00
Jesper Noordsij
f7a6f32784 Update Dockerfiles to Alpine 3.22 2025-06-03 11:24:05 +02:00
Lukáš Stuchlík
fe5c7fdc65 Add a note to certificatesDuration 2025-06-02 16:22:04 +02:00
Jesper Noordsij
92f798dfcd Update supported versions 2025-06-02 16:08:04 +02:00
romain
bd4bfd8919 Merge branch v2.11 into v3.4 2025-06-02 15:50:06 +02:00
Michael
f174014d96 feat: parallelise unit tests 2025-06-02 11:00:05 +02:00
Romain
2fdee25bb3 Attempt to fix TestProxyFromEnvironment test
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2025-06-02 10:46:04 +02:00
Kevin Pollet
cd16321dd9 Bump to go1.24
Co-authored-by: Romain <rtribotte@users.noreply.github.com>
2025-06-02 10:36:05 +02:00
Thomas Mauran
0b4058dde0 Remove obsolete version field in compose files 2025-05-28 17:16:08 +02:00
Corey
6a54f1f66c Add WebSocket guide 2025-05-28 11:46:04 +02:00
246 changed files with 6690 additions and 1339 deletions

View File

@@ -10,7 +10,7 @@ on:
- 'script/gcg/**'
env:
GO_VERSION: '1.23'
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:

View File

@@ -7,7 +7,7 @@ on:
- v*
env:
GO_VERSION: '1.23'
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:

View File

@@ -6,7 +6,7 @@ on:
- 'v*.*.*'
env:
GO_VERSION: '1.23'
GO_VERSION: '1.24'
CGO_ENABLED: 0
VERSION: ${{ github.ref_name }}
TRAEFIKER_EMAIL: "traefiker@traefik.io"

View File

@@ -10,7 +10,7 @@ on:
- 'script/gcg/**'
env:
GO_VERSION: '1.23'
GO_VERSION: '1.24'
CGO_ENABLED: 0
jobs:
@@ -34,7 +34,21 @@ jobs:
run: touch webui/static/index.html
- name: Build binary
run: make binary
run: make binary-linux-amd64
- name: Save go cache build
uses: actions/cache/save@v4
with:
path: |
~/.cache/go-build
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
- name: Artifact traefik binary
uses: actions/upload-artifact@v4
with:
name: traefik
path: ./dist/linux/amd64/traefik
retention-days: 1
test-integration:
runs-on: ubuntu-latest
@@ -61,8 +75,21 @@ jobs:
- name: Avoid generating webui
run: touch webui/static/index.html
- name: Build binary
run: make binary
- name: Download traefik binary
uses: actions/download-artifact@v4
with:
name: traefik
path: ./dist/linux/amd64/
- name: Make binary executable
run: chmod +x ./dist/linux/amd64/traefik
- name: Restore go cache build
uses: actions/cache/restore@v4
with:
path: |
~/.cache/go-build
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
- name: Generate go test Slice
id: test_split

View File

@@ -10,12 +10,40 @@ on:
- 'script/gcg/**'
env:
GO_VERSION: '1.23'
GO_VERSION: '1.24'
jobs:
generate-packages:
name: List Go Packages
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
- name: Generate matrix
id: set-matrix
run: |
matrix_output=$(go run ./internal/testsci/genmatrix.go)
echo "$matrix_output"
echo "$matrix_output" >> $GITHUB_OUTPUT
test-unit:
runs-on: ubuntu-latest
needs: generate-packages
strategy:
matrix:
package: ${{ fromJson(needs.generate-packages.outputs.matrix) }}
steps:
- name: Check out code
@@ -33,7 +61,8 @@ jobs:
run: touch webui/static/index.html
- name: Tests
run: make test-unit
run: |
go test -v -parallel 8 ${{ matrix.package.group }}
test-ui-unit:
runs-on: ubuntu-latest

View File

@@ -6,7 +6,7 @@ on:
- '*'
env:
GO_VERSION: '1.23'
GO_VERSION: '1.24'
GOLANGCI_LINT_VERSION: v2.0.2
MISSPELL_VERSION: v0.6.0

View File

@@ -1,3 +1,86 @@
## [v3.4.5](https://github.com/traefik/traefik/tree/v3.4.5) (2025-07-23)
[All Commits](https://github.com/traefik/traefik/compare/v3.4.4...v3.4.5)
**Bug fixes:**
- **[http3]** Bump github.com/quic-go/quic-go to v0.54.0 ([#11919](https://github.com/traefik/traefik/pull/11919) by [GreyXor](https://github.com/GreyXor))
**Documentation:**
- Fix typo in entrypoints page ([#11914](https://github.com/traefik/traefik/pull/11914) by [adk-swisstopo](https://github.com/adk-swisstopo))
**Misc:**
- Merge branch v2.11 into v3.4 ([#11930](https://github.com/traefik/traefik/pull/11930) by [kevinpollet](https://github.com/kevinpollet))
- Merge branch v2.11 into v3.4 ([#11926](https://github.com/traefik/traefik/pull/11926) by [rtribotte](https://github.com/rtribotte))
## [v2.11.28](https://github.com/traefik/traefik/tree/v2.11.28) (2025-07-23)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.27...v2.11.28)
**Bug fixes:**
- **[logs]** Redact logged install configuration ([#11907](https://github.com/traefik/traefik/pull/11907) by [jspdown](https://github.com/jspdown))
- **[plugins]** Fix client arbitrary file access during archive extraction zipslip ([#11911](https://github.com/traefik/traefik/pull/11911) by [odaysec](https://github.com/odaysec))
- **[server]** Disable MPTCP by default ([#11918](https://github.com/traefik/traefik/pull/11918) by [rtribotte](https://github.com/rtribotte))
**Documentation:**
- **[k8s/crd,k8s]** Remove all mentions of ordering for TLSOption CurvePreferences field ([#11924](https://github.com/traefik/traefik/pull/11924) by [jnoordsij](https://github.com/jnoordsij))
## [v3.4.4](https://github.com/traefik/traefik/tree/v3.4.4) (2025-07-11)
[All Commits](https://github.com/traefik/traefik/compare/v3.4.3...v3.4.4)
**Bug fixes:**
- **[k8s/gatewayapi]** Respect service.nativelb=false annotation when nativeLBByDefault is enabled ([#11847](https://github.com/traefik/traefik/pull/11847) by [sdelicata](https://github.com/sdelicata))
- **[service]** Fix concurrent access to balancer status map in WRR and P2C strategies ([#11887](https://github.com/traefik/traefik/pull/11887) by [kevinpollet](https://github.com/kevinpollet))
**Documentation:**
- **[docker,k8s]** Add New Expose Guides ([#11760](https://github.com/traefik/traefik/pull/11760) by [sheddy-traefik](https://github.com/sheddy-traefik))
- **[docker,k8s]** Add New Setup Guides ([#11741](https://github.com/traefik/traefik/pull/11741) by [sheddy-traefik](https://github.com/sheddy-traefik))
- **[docker/swarm]** Fix label for overriding swarm network on container ([#11881](https://github.com/traefik/traefik/pull/11881) by [kevinpollet](https://github.com/kevinpollet))
- **[logs,accesslogs]** Update Logs and Accesslogs Reference documentation with OTLP Options ([#11845](https://github.com/traefik/traefik/pull/11845) by [sheddy-traefik](https://github.com/sheddy-traefik))
- Update what is Traefik page to include full Traefik Platform context ([#11885](https://github.com/traefik/traefik/pull/11885) by [tomatokoolaid](https://github.com/tomatokoolaid))
**Misc:**
- Merge branch v2.11 into v3.4 ([#11896](https://github.com/traefik/traefik/pull/11896) by [kevinpollet](https://github.com/kevinpollet))
## [v2.11.27](https://github.com/traefik/traefik/tree/v2.11.27) (2025-07-11)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.26...v2.11.27)
**Bug fixes:**
- Bump github.com/go-viper/mapstructure/v2 to v2.3.0 ([#11880](https://github.com/traefik/traefik/pull/11880) by [kevinpollet](https://github.com/kevinpollet))
## [v3.4.3](https://github.com/traefik/traefik/tree/v3.4.3) (2025-06-26)
[All Commits](https://github.com/traefik/traefik/compare/v3.4.2...v3.4.3)
**Bug fixes:**
- **[http3]** Bump quic-go to v.0.49.0 ([#11848](https://github.com/traefik/traefik/pull/11848) by [joshua-siw](https://github.com/joshua-siw))
## [v3.4.2](https://github.com/traefik/traefik/tree/v3.4.2) (2025-06-26)
[All Commits](https://github.com/traefik/traefik/compare/v3.4.1...v3.4.2)
**Documentation:**
- **[acme]** Add a note to certificatesDuration ([#11808](https://github.com/traefik/traefik/pull/11808) by [sMteX](https://github.com/sMteX))
- **[docker,k8s]** Update Getting started Section with New Docker and Kubernetes Tutorial ([#11714](https://github.com/traefik/traefik/pull/11714) by [sheddy-traefik](https://github.com/sheddy-traefik))
- **[docker]** Remove obsolete version field in compose files ([#11798](https://github.com/traefik/traefik/pull/11798) by [thomas-mauran](https://github.com/thomas-mauran))
- **[k8s]** Add a note about Ingress Backend Resource support ([#11785](https://github.com/traefik/traefik/pull/11785) by [edysli](https://github.com/edysli))
- **[logs,metrics,tracing,accesslogs]** Update the EntryPoints Documentation ([#11856](https://github.com/traefik/traefik/pull/11856) by [sheddy-traefik](https://github.com/sheddy-traefik))
- **[logs,metrics,tracing,accesslogs]** Add New Observe Guides to the Documentation ([#11828](https://github.com/traefik/traefik/pull/11828) by [sheddy-traefik](https://github.com/sheddy-traefik))
- **[middleware]** Remove conflicting information from the CircuitBreaker documentation. ([#11835](https://github.com/traefik/traefik/pull/11835) by [adk-swisstopo](https://github.com/adk-swisstopo))
- **[service]** Clarify mirroring service default percent value ([#11804](https://github.com/traefik/traefik/pull/11804) by [Alexy-vda](https://github.com/Alexy-vda))
- **[websocket]** Add WebSocket guide ([#11623](https://github.com/traefik/traefik/pull/11623) by [NX211](https://github.com/NX211))
**Misc:**
- Merge branch v2.11 into v3.4 ([#11859](https://github.com/traefik/traefik/pull/11859) by [rtribotte](https://github.com/rtribotte))
- Merge branch v2.11 into v3.4 ([#11831](https://github.com/traefik/traefik/pull/11831) by [rtribotte](https://github.com/rtribotte))
- Merge branch v2.11 into v3.4 ([#11810](https://github.com/traefik/traefik/pull/11810) by [rtribotte](https://github.com/rtribotte))
## [v2.11.26](https://github.com/traefik/traefik/tree/v2.11.26) (2025-06-26)
[All Commits](https://github.com/traefik/traefik/compare/v2.11.25...v2.11.26)
**Bug fixes:**
- **[middleware]** Do not log redis sentinel username and password ([#11819](https://github.com/traefik/traefik/pull/11819) by [kevinpollet](https://github.com/kevinpollet))
**Documentation:**
- **[kv]** Fix KV reference rendering ([#11815](https://github.com/traefik/traefik/pull/11815) by [rtribotte](https://github.com/rtribotte))
- **[middleware,k8s/crd]** Fix typo in redirect middleware documentation ([#11830](https://github.com/traefik/traefik/pull/11830) by [rtribotte](https://github.com/rtribotte))
- Update supported versions ([#11811](https://github.com/traefik/traefik/pull/11811) by [jnoordsij](https://github.com/jnoordsij))
## [v3.4.1](https://github.com/traefik/traefik/tree/v3.4.1) (2025-05-27)
[All Commits](https://github.com/traefik/traefik/compare/v3.4.0...v3.4.1)

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1.2
FROM alpine:3.21
FROM alpine:3.22
RUN apk add --no-cache --no-progress ca-certificates tzdata

View File

@@ -95,7 +95,7 @@ test-unit:
.PHONY: test-integration
#? test-integration: Run the integration tests
test-integration: binary
test-integration:
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -test.timeout=20m -failfast -v $(TESTFLAGS)
.PHONY: test-gateway-api-conformance

View File

@@ -3,7 +3,6 @@ package main
import (
"context"
"crypto/x509"
"encoding/json"
"fmt"
"io"
stdlog "log"
@@ -40,6 +39,7 @@ import (
"github.com/traefik/traefik/v3/pkg/provider/traefik"
"github.com/traefik/traefik/v3/pkg/proxy"
"github.com/traefik/traefik/v3/pkg/proxy/httputil"
"github.com/traefik/traefik/v3/pkg/redactor"
"github.com/traefik/traefik/v3/pkg/safe"
"github.com/traefik/traefik/v3/pkg/server"
"github.com/traefik/traefik/v3/pkg/server/middleware"
@@ -104,12 +104,11 @@ func runCmd(staticConfiguration *static.Configuration) error {
log.Info().Str("version", version.Version).
Msgf("Traefik version %s built on %s", version.Version, version.BuildDate)
jsonConf, err := json.Marshal(staticConfiguration)
redactedStaticConfiguration, err := redactor.RemoveCredentials(staticConfiguration)
if err != nil {
log.Error().Err(err).Msg("Could not marshal static configuration")
log.Debug().Interface("staticConfiguration", staticConfiguration).Msg("Static configuration loaded [struct]")
log.Error().Err(err).Msg("Could not redact static configuration")
} else {
log.Debug().RawJSON("staticConfiguration", jsonConf).Msg("Static configuration loaded [json]")
log.Debug().RawJSON("staticConfiguration", []byte(redactedStaticConfiguration)).Msg("Static configuration loaded [json]")
}
if staticConfiguration.Global.CheckNewVersion {

View File

@@ -1,4 +1,4 @@
FROM alpine:3.21
FROM alpine:3.22
RUN apk --no-cache --no-progress add \
build-base \
@@ -9,9 +9,7 @@ RUN apk --no-cache --no-progress add \
ruby \
ruby-bigdecimal \
ruby-dev \
ruby-etc \
ruby-ffi \
ruby-json \
zlib-dev
RUN gem install nokogiri --version 1.18.6 --no-document -- --use-system-libraries

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

View File

@@ -6,11 +6,12 @@ Below is a non-exhaustive list of versions and their maintenance status:
| Version | Release Date | Active Support | Security Support |
|---------|--------------|--------------------|-------------------|
| 3.3 | Jan 06, 2025 | Yes | Yes |
| 3.4 | May 05, 2025 | Yes | Yes |
| 3.3 | Jan 06, 2025 | Ended May 05, 2025 | No |
| 3.2 | Oct 28, 2024 | Ended Jan 06, 2025 | No |
| 3.1 | Jul 15, 2024 | Ended Oct 28, 2024 | No |
| 3.0 | Apr 29, 2024 | Ended Jul 15, 2024 | No |
| 2.11 | Feb 12, 2024 | Ends Apr 29, 2025 | Ends Feb 01, 2026 |
| 2.11 | Feb 12, 2024 | Ended Apr 29, 2025 | Ends Feb 01, 2026 |
| 2.10 | Apr 24, 2023 | Ended Feb 12, 2024 | No |
| 2.9 | Oct 03, 2022 | Ended Apr 24, 2023 | No |
| 2.8 | Jun 29, 2022 | Ended Oct 03, 2022 | No |
@@ -32,7 +33,7 @@ Below is a non-exhaustive list of versions and their maintenance status:
This page is maintained and updated periodically to reflect our roadmap and any decisions affecting the end of support for Traefik Proxy.
Please refer to our migration guides for specific instructions on upgrading between versions, an example is the [v2 to v3 migration guide](../migration/v2-to-v3.md).
Please refer to our migration guides for specific instructions on upgrading between versions, an example is the [v2 to v3 migration guide](../migrate/v2-to-v3.md).
!!! important "All target dates for end of support or feature removal announcements may be subject to change."

View File

@@ -0,0 +1,462 @@
# Exposing Services with Traefik on Docker
This guide will help you expose your services securely through Traefik Proxy using Docker. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
## Prerequisites
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the Traefik Docker Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/router/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service in `docker-compose.yml`:
```yaml
labels:
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
- "traefik.http.middlewares.secure-headers.headers.browserXssFilter=true"
- "traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
```
Add the same middleware to your whoami-api service:
```yaml
labels:
- "traefik.http.routers.whoami-api.middlewares=secure-headers,ip-allowlist"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Middlewares
Now let's verify that our middlewares are working correctly:
Test the Secure Headers middleware:
```bash
curl -k -I -H "Host: whoami.docker.localhost" https://localhost/
```
In the response headers, you should see security headers set by the middleware:
- `X-Frame-Options: DENY`
- `X-Content-Type-Options: nosniff`
- `X-XSS-Protection: 1; mode=block`
- `Strict-Transport-Security` with the appropriate settings
Test the IP Allowlist middleware:
If your request comes from an IP that's in the allow list (e.g., 127.0.0.1), it should succeed:
```bash
curl -k -I -H "Host: whoami.docker.localhost" https://localhost/
```
If you try to access from an IP not in the allow list, the request will be rejected with a `403` Forbidden response. To simulate this in a local environment, you can modify the middleware configuration temporarily to exclude your IP address, then test again.
## Generate Certificates with Let's Encrypt
Let's Encrypt provides free, automated TLS certificates. Let's configure Traefik to automatically obtain and renew certificates for our services.
Instead of using self-signed certificates, update your existing `docker-compose.yml` file with the following changes:
Add the Let's Encrypt certificate resolver to the Traefik service command section:
```yaml
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--entryPoints.web.http.redirections.entryPoint.to=websecure"
- "--entryPoints.web.http.redirections.entryPoint.scheme=https"
# Let's Encrypt configuration
- "--certificatesresolvers.le.acme.email=your-email@example.com" # replace with your actual email
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
```
Add a volume for Let's Encrypt certificates:
```yaml
volumes:
# ...Existing volumes...
- "./letsencrypt:/letsencrypt"
```
Update your service labels to use the certificate resolver:
```yaml
labels:
- "traefik.http.routers.whoami.tls.certresolver=le"
```
Do the same for any other services you want to secure:
```yaml
labels:
- "traefik.http.routers.whoami-api.tls.certresolver=le"
```
Create a directory for storing Let's Encrypt certificates:
```bash
mkdir -p letsencrypt
```
Apply the changes:
```bash
docker compose up -d
```
!!! important "Public DNS Required"
Let's Encrypt may require a publicly accessible domain to validate domain ownership. For testing with local domains like `whoami.docker.localhost`, the certificate will remain self-signed. In production, replace it with a real domain that has a publicly accessible DNS record pointing to your Traefik instance.
Once the certificate is issued, you can verify it:
```bash
# Verify the certificate chain
curl -v https://whoami.docker.localhost/ 2>&1 | grep -i "server certificate"
```
You should see that your certificate is issued by Let's Encrypt.
## Configure Sticky Sessions
Sticky sessions ensure that a user's requests always go to the same backend server, which is essential for applications that maintain session state. Let's implement sticky sessions for our whoami service.
### First, Add Sticky Session Labels
Add the following labels to your whoami service in the `docker-compose.yml` file:
```yaml
labels:
- "traefik.http.services.whoami.loadbalancer.sticky.cookie=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=sticky_cookie"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.secure=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.httpOnly=true"
```
Apply the changes:
```bash
docker compose up -d
```
### Then, Scale Up the Service
To demonstrate sticky sessions with Docker, use Docker Compose's scale feature:
```bash
docker compose up -d --scale whoami=3
```
This creates multiple instances of the whoami service.
!!! important "Scaling After Configuration Changes"
If you run `docker compose up -d` after scaling, it will reset the number of whoami instances back to 1. Always scale after applying configuration changes and starting the services.
### Test Sticky Sessions
You can test the sticky sessions by making multiple requests and observing that they all go to the same backend container:
```bash
# First request - save cookies to a file
curl -k -c cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
# Subsequent requests - use the cookies
curl -k -b cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
curl -k -b cookies.txt -H "Host: whoami.docker.localhost" https://localhost/
```
Pay attention to the `Hostname` field in each response - it should remain the same across all requests when using the cookie file, confirming that sticky sessions are working.
For comparison, try making requests without the cookie:
```bash
# Requests without cookies should be load-balanced across different containers
curl -k -H "Host: whoami.docker.localhost" https://localhost/
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
You should see different `Hostname` values in these responses, as each request is load-balanced to a different container.
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
## Conclusion
In this guide, you've learned how to:
- Expose HTTP services through Traefik in Docker
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/router/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
# Exposing Services with Traefik Proxy
This section guides you through exposing services securely with Traefik Proxy. You'll learn how to route HTTP and HTTPS traffic to your services, add security features, and implement advanced load balancing.
## What You'll Accomplish
Following these guides, you'll learn how to:
- Route HTTP traffic to your services with [Gateway API](../reference/routing-configuration/kubernetes/gateway-api.md) and [IngressRoute](../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
- Configure routing rules to direct requests
- Enable HTTPS with TLS
- Add security middlewares
- Generate certificates automatically with Let's Encrypt
- Implement sticky sessions for session persistence
## Platform-Specific Guides
For detailed steps tailored to your environment, follow the guide for your platform:
- [Kubernetes](./kubernetes.md)
- [Docker](./docker.md)
- [Docker Swarm](./swarm.md)

View File

@@ -0,0 +1,401 @@
# Exposing Services with Traefik on Docker Swarm
This guide will help you expose your services securely through Traefik Proxy using Docker Swarm. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
## Prerequisites
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the Traefik Docker Swarm Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/router/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service deployment section in `docker-compose.yml`:
```yaml
deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
- "traefik.http.middlewares.secure-headers.headers.browserXssFilter=true"
- "traefik.http.middlewares.secure-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply the middlewares
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
Add the same middleware to your whoami-api service:
```yaml
deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
- "traefik.http.routers.whoami-api.middlewares=secure-headers,ip-allowlist"
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Middlewares
Now let's verify that our middlewares are working correctly:
Test the Secure Headers middleware:
```bash
curl -k -I -H "Host: whoami.swarm.localhost" https://localhost/
```
In the response headers, you should see security headers set by the middleware:
- `X-Frame-Options: DENY`
- `X-Content-Type-Options: nosniff`
- `X-XSS-Protection: 1; mode=block`
- `Strict-Transport-Security` with the appropriate settings
Test the IP Allowlist middleware:
If your request comes from an IP that's in the allow list (e.g., 127.0.0.1), it should succeed:
```bash
curl -k -I -H "Host: whoami.swarm.localhost" https://localhost/
```
If you try to access from an IP not in the allow list, the request will be rejected with a `403` Forbidden response. To simulate this in a local environment, you can modify the middleware configuration temporarily to exclude your IP address, then test again.
## Generate Certificates with Let's Encrypt
Let's Encrypt provides free, automated TLS certificates. Let's configure Traefik to automatically obtain and renew certificates for our services.
Instead of using self-signed certificates, update your existing `docker-compose.yml` file with the following changes:
Add the Let's Encrypt certificate resolver to the Traefik service command section:
```yaml
command:
# ... existing commands ...
# Let's Encrypt configuration
- "--certificatesresolvers.le.acme.email=your-email@example.com" # replace with your actual email
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
```
Add a volume for Let's Encrypt certificates:
```yaml
volumes:
# ...Existing volumes...
- letsencrypt:/letsencrypt
```
Update your service labels to use the certificate resolver:
```yaml
labels:
# ... existing labels ...
- "traefik.http.routers.whoami.tls.certresolver=le"
```
Do the same for any other services you want to secure:
```yaml
labels:
# ... existing labels ...
- "traefik.http.routers.whoami-api.tls.certresolver=le"
```
Create a named volume for storing Let's Encrypt certificates by adding to the volumes section:
```yaml
volumes:
# ... existing volumes ...
letsencrypt:
driver: local
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
!!! important "Public DNS Required"
Let's Encrypt may require a publicly accessible domain to validate domain ownership. For testing with local domains like `whoami.swarm.localhost`, the certificate will remain self-signed. In production, replace it with a real domain that has a publicly accessible DNS record pointing to your Traefik instance.
Once the certificate is issued, you can verify it:
```bash
# Verify the certificate chain
curl -v https://whoami.swarm.localhost/ 2>&1 | grep -i "server certificate"
```
You should see that your certificate is issued by Let's Encrypt.
## Configure Sticky Sessions
Sticky sessions ensure that a user's requests always go to the same backend server, which is essential for applications that maintain session state. Let's implement sticky sessions for our whoami service.
Docker Swarm already has multiple replicas running; we'll now add sticky session configuration. Update your whoami service in the `docker-compose.yml` file:
### Add Sticky Session Configuration
Add the following labels to your whoami service in the `docker-compose.yml` file:
```yaml
deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Sticky Sessions Configuration
- "traefik.http.services.whoami.loadbalancer.sticky.cookie=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=sticky_cookie"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.secure=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.httpOnly=true"
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test Sticky Sessions
You can test the sticky sessions by making multiple requests and observing that they all go to the same backend container:
```bash
# First request - save cookies to a file
curl -k -c cookies.txt -H "Host: whoami.swarm.localhost" https://localhost/
# Subsequent requests - use the cookies
curl -k -b cookies.txt -H "Host: whoami.swarm.localhost" https://localhost/
curl -k -b cookies.txt -H "Host: whoami.swarm.localhost" https://localhost/
```
Pay attention to the `Hostname` field in each response - it should remain the same across all requests when using the cookie file, confirming that sticky sessions are working.
For comparison, try making requests without the cookie:
```bash
# Requests without cookies should be load-balanced across different containers
curl -k -H "Host: whoami.swarm.localhost" https://localhost/
curl -k -H "Host: whoami.swarm.localhost" https://localhost/
```
You should see different `Hostname` values in these responses, as each request is load-balanced to a different container.
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
## Conclusion
In this guide, you've learned how to:
- Expose HTTP services through Traefik in Docker Swarm
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker Swarm. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/router/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration

View File

@@ -0,0 +1,162 @@
---
title: "Docker and Traefik Quick Start"
description: "Deploy Traefik in Docker and expose your first service"
---
# Getting Started with Docker and Traefik
Docker is a first-class citizen in Traefik, offering native support for Docker containers and services.
Whether you're using Docker Compose or running containers directly, Traefik provides a seamless experience for managing your Docker traffic.
This guide shows you how to:
- Install Traefik using Docker
- Expose the Traefik dashboard
- Deploy a sample application
- Configure basic routing
## Prerequisites
- Docker
- Docker Compose (optional)
## Install Traefik
### Using Docker Compose
Create a Docker Compose file.
This configuration:
- Exposes ports 80 and 8080.
- Enables the Docker provider
- Configures the dashboard with basic settings. Port 8080 serves the dashboard because we enabled `--api.insecure=true` (development use only)
- Mounts the Docker socket for container discovery
```yaml
# docker-compose.yml
services:
traefik:
image: traefik:v3.4
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
Start Traefik:
```bash
docker-compose up -d
```
### Using Docker CLI
Alternatively, you can run Traefik directly with Docker.
This command:
- Exposes ports 80 and 8080 for web traffic and dashboard access
- Mounts the configuration file and Docker socket
- Uses the same configuration as the Docker Compose example
Create a configuration file:
```yaml
# traefik.yml
api:
insecure: true
entryPoints:
web:
address: ":80"
providers:
docker: {}
```
Start Traefik:
```bash
docker run -d \
-p 80:80 \
-p 8080:8080 \
-v $PWD/traefik.yml:/etc/traefik/traefik.yml \
-v /var/run/docker.sock:/var/run/docker.sock \
traefik:v3.4
```
## Expose the Dashboard
Because we explicitly enabled insecure mode, the [dashboard](../reference/install-configuration/api-dashboard.md) is reachable on port 8080 without authentication.
**Do not enable this flag in production**.
You can access the dashboard at:
[http://localhost:8080/dashboard/](http://localhost:8080/dashboard/)
![Traefik Dashboard Screenshot](../assets/img/getting-started/traefik-dashboard.png)
## Deploy a Sample Application
Create a whoami service:
```yaml
# whoami.yml
services:
whoami:
image: traefik/whoami
labels:
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
```
Apply the configuration:
```bash
docker-compose -f whoami.yml up -d
```
## Test Your Setup
You can use the following curl command to verify that the application is correctly exposed:
```bash
curl http://whoami.localhost
Hostname: 068c0a29a8b7
IP: 127.0.0.1
IP: ::1
IP: 192.168.147.3
RemoteAddr: 192.168.147.2:56006
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 192.168.147.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 9232cdd4fd6c
X-Real-Ip: 192.168.147.1
```
You can also open [http://whoami.localhost](http://whoami.localhost) in a browser to test the application:
![whoami application Screenshot](../assets/img/getting-started/whoami-localhost.png)
If you navigate to the **HTTP Routers** section of the Traefik dashboard, you can see that the `whoami.localhost` route is managed by the Traefik Docker provider:
![Traefik Dashboard HTTP Routers Section Screenshot](../assets/img/getting-started/docker-router.png)
That's it! You've successfully deployed Traefik and configured routing in Docker.
## Next Steps
- [Configure TLS](../reference/routing-configuration/http/tls/overview.md)
- [Set up Middlewares](../reference/routing-configuration/http/middlewares/overview.md)
- [Enable Metrics](../reference/install-configuration/observability/metrics.md)
- [Learn more about Docker provider](../reference/install-configuration/providers/docker.md)
{!traefik-for-business-applications.md!}

View File

@@ -0,0 +1,25 @@
---
title: "Getting Started with Traefik"
description: "Quick start guides for deploying Traefik in Kubernetes and Docker environments"
---
# Getting Started with Traefik
Traefik can be deployed in various environments. Choose your preferred deployment method:
- [Kubernetes Quick Start](./kubernetes.md) - Deploy Traefik using Helm
- [Docker Quick Start](./docker.md) - Deploy Traefik using Docker
Each guide will help you:
- Install Traefik
- Expose the dashboard
- Deploy a sample application
- Configure basic routing
## Before You Begin
Make sure you have the necessary prerequisites for your chosen environment:
- **Kubernetes**: A running Kubernetes cluster, Helm 3, and kubectl
- **Docker**: Docker and optionally Docker Compose

View File

@@ -0,0 +1,331 @@
---
title: "Kubernetes and Traefik Quick Start"
description: "Deploy Traefik in Kubernetes using Helm and expose your first service"
slug: quick-start-with-kubernetes
---
# Getting Started with Kubernetes and Traefik
Kubernetes is a first-class citizen in Traefik, offering native support for Kubernetes resources and the latest Kubernetes standards.
Whether you're using Traefik's [IngressRoute CRD](../reference/routing-configuration/kubernetes/crd/http/ingressroute.md), [Ingress](../reference/routing-configuration/kubernetes/ingress.md) or the [Kubernetes Gateway API](../reference/routing-configuration/kubernetes/gateway-api.md),
Traefik provides a seamless experience for managing your Kubernetes traffic.
This guide shows you how to:
- Create a Kubernetes cluster using k3d
- Install Traefik using Helm
- Expose the Traefik dashboard
- Deploy a sample application
- Configure basic routing with IngressRoute and Gateway API
## Prerequisites
- Kubernetes
- Helm 3
- kubectl
- k3d (for local cluster creation)
## Create a Kubernetes Cluster
### Using k3d
Create a cluster with the following command. This command:
- Creates a k3d cluster named "traefik"
- Maps ports 80, 443, and 8000 to the loadbalancer for accessing services
- Disables the built-in Traefik ingress controller to avoid conflicts
```bash
k3d cluster create traefik \
--port 80:80@loadbalancer \
--port 443:443@loadbalancer \
--port 8000:8000@loadbalancer \
--k3s-arg "--disable=traefik@server:0"
```
Configure kubectl:
```bash
kubectl cluster-info --context k3d-traefik
```
## Install Traefik
### Using Helm Values File
Add the Traefik Helm repository:
```bash
helm repo add traefik https://traefik.github.io/charts
helm repo update
```
Create a values file. This configuration:
- Maps ports 80 and 443 to the web and websecure [entrypoints](../reference/install-configuration/entrypoints.md)
- Enables the [dashboard](../reference/install-configuration/api-dashboard.md) with a specific hostname rule
- Enables the [Kubernetes Gateway API provider](../reference/routing-configuration/kubernetes/gateway-api.md)
- Allows the Gateway to expose [HTTPRoutes](https://gateway-api.sigs.k8s.io/api-types/httproute/) from all namespaces
```yaml
# values.yaml
ingressRoute:
dashboard:
enabled: true
matchRule: Host(`dashboard.localhost`)
entryPoints:
- web
providers:
kubernetesGateway:
enabled: true
gateway:
namespacePolicy: All
```
!!! info
The [KubernetesCRD](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) provider is enabled by default when using the Helm chart so we don't need to set it in the values file.
Install Traefik:
```bash
helm install traefik traefik/traefik -f values.yaml --wait
```
### Using Helm CLI Arguments
Alternatively, you can install Traefik using CLI arguments. This command:
- Maps ports `30000` and `30001` to the web and websecure entrypoints
- Enables the dashboard with a specific hostname rule
- Enables the [Kubernetes Gateway API provider](../reference/routing-configuration/kubernetes/gateway-api.md)
- Allows the Gateway to expose HTTPRoutes from all namespaces
```bash
helm install traefik traefik/traefik --wait \
--set ingressRoute.dashboard.enabled=true \
--set ingressRoute.dashboard.matchRule='Host(`dashboard.localhost`)' \
--set ingressRoute.dashboard.entryPoints={web} \
--set providers.kubernetesGateway.enabled=true \
--set gateway.namespacePolicy=All
```
!!! info
The [KubernetesCRD](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) provider is enabled by default when using the Helm chart so we don't need to set it in the CLI arguments.
When Traefik is installed with the Gateway API provider enabled, it automatically creates a default GatewayClass named **traefik**:
```bash
kubectl describe GatewayClass traefik
```
## Expose the Dashboard
The dashboard is exposed with an [IngressRoute](../reference/routing-configuration/kubernetes/crd/http/ingressroute.md) provided by the Chart, as we defined in the helm values during installation.
Access it at:
[http://dashboard.localhost/dashboard/](http://dashboard.localhost/dashboard/)
![Traefik Dashboard Screenshot](../assets/img/getting-started/traefik-dashboard.png)
## Deploy a Sample Application
Create a deployment:
```yaml
# whoami.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
```
Create a service:
```yaml
# whoami-service.yaml
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- port: 80
selector:
app: whoami
```
Apply the manifests:
```bash
kubectl apply -f whoami.yaml
kubectl apply -f whoami-service.yaml
```
## Exposing the Application Using an IngressRoute (CRD)
Create an IngressRoute:
```yaml
# whoami-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Apply the manifest:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test Your Setup
You can use the following curl command to verify that the application is correctly exposed:
```bash
curl http://whoami.localhost
Hostname: whoami-76c9859cfc-6v8hh
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.11
IP: fe80::20ad:eeff:fe44:a63
RemoteAddr: 10.42.0.9:38280
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-598946cd7-zds59
X-Real-Ip: 127.0.0.1
```
You can also visit [http://whoami.localhost](http://whoami.localhost) in a browser to verify that the application is exposed correctly:
![whoami application Screenshot](../assets/img/getting-started/whoami-localhost.png)
## Exposing the Application Using the Gateway API
Traefik supports the Kubernetes Gateway API specification, which provides a more standardized way to configure ingress in Kubernetes.
When we installed Traefik earlier, we enabled the Gateway API provider.
You can verify this in the providers section of the Traefik dashboard.
![Providers Section Screenshot](../assets/img/getting-started/providers.png)
To use the Gateway API:
Install the Gateway API CRDs in your cluster:
```bash
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
```
Create an HTTPRoute. This configuration:
- Creates an HTTPRoute named "whoami"
- Attaches it to the default Gateway that Traefik created during installation
- Configures routing for the hostname "whoami-gatewayapi.localhost"
- Routes all traffic to the whoami service on port 80
```yaml
# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami-gatewayapi.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Apply the manifest:
```bash
kubectl apply -f httproute.yaml
```
### Test Your Setup
You can use the following curl command to verify that the application is correctly exposed:
```bash
curl http://whoami-gatewayapi.localhost
Hostname: whoami-76c9859cfc-6v8hh
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.11
IP: fe80::20ad:eeff:fe44:a63
RemoteAddr: 10.42.0.9:38280
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-598946cd7-zds59
X-Real-Ip: 127.0.0.1
```
You can now visit [http://whoami.localhost](http://whoami.localhost) in your browser to verify that the application is exposed correctly:
![whoami application Screenshot](../assets/img/getting-started/whoami-localhost.png)
If you navigate to the **HTTP Routes** section of the traefik dashboard, you can see that the `whoami.localhost` route is managed by the Traefik Kubernetes Gateway API provider:
![Traefik Dashboard HTTP Routes Section Screenshot](../assets/img/getting-started/kubernetes-gateway.png)
That's it! You've successfully deployed Traefik and configured routing in a Kubernetes cluster.
## Next Steps
- [Configure TLS](../reference/routing-configuration/http/tls/overview.md)
- [Set up Middlewares](../reference/routing-configuration/http/middlewares/overview.md)
- [Enable Metrics](../reference/install-configuration/observability/metrics.md)
- [Learn more about Kubernetes CRD provider](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md)
- [Learn more about Kubernetes Gateway API provider](../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md)
{!traefik-for-business-applications.md!}

View File

@@ -3,342 +3,4 @@ title: "Traefik Getting Started With Kubernetes"
description: "Get started with Traefik Proxy and Kubernetes."
---
# Quick Start
A Use Case of Traefik Proxy and Kubernetes
{: .subtitle }
This guide is an introduction to using Traefik Proxy in a Kubernetes environment.
The objective is to learn how to run an application behind a Traefik reverse proxy in Kubernetes.
It presents and explains the basic blocks required to start with Traefik such as Ingress Controller, Ingresses, Deployments, static, and dynamic configuration.
## Permissions and Accesses
Traefik uses the Kubernetes API to discover running services.
To use the Kubernetes API, Traefik needs some permissions.
This [permission mechanism](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) is based on roles defined by the cluster administrator.
The role is then bound to an account used by an application, in this case, Traefik Proxy.
The first step is to create the role.
The [`ClusterRole`](https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/cluster-role-v1/#ClusterRole) resource enumerates the resources and actions available for the role.
In a file called `00-role.yml`, put the following `ClusterRole`:
```yaml tab="00-role.yml"
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role
rules:
- apiGroups:
- ""
resources:
- services
- secrets
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.io
resources:
- middlewares
- middlewaretcps
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
- serverstransports
- serverstransporttcps
verbs:
- get
- list
- watch
```
!!! info "You can find the reference for this file [there](../../reference/dynamic-configuration/kubernetes-crd/#rbac)."
The next step is to create a dedicated service account for Traefik.
In a file called `00-account.yml`, put the following [`ServiceAccount`](https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/service-account-v1/#ServiceAccount) resource:
```yaml tab="00-account.yml"
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-account
```
And then, bind the role on the account to apply the permissions and rules on the latter. In a file called `01-role-binding.yml`, put the
following [`ClusterRoleBinding`](https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/cluster-role-binding-v1/#ClusterRoleBinding) resource:
```yaml tab="01-role-binding.yml"
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-role
subjects:
- kind: ServiceAccount
name: traefik-account
namespace: default # This tutorial uses the "default" K8s namespace.
```
!!! info "`roleRef` is the Kubernetes reference to the role created in `00-role.yml`."
!!! info "`subjects` is the list of accounts reference."
In this guide, it only contains the account created in `00-account.yml`
## Deployment and Exposition
!!! info "This section can be managed with the help of the [Traefik Helm chart](../install-traefik/#use-the-helm-chart)."
The [ingress controller](https://traefik.io/glossary/kubernetes-ingress-and-ingress-controller-101/#what-is-a-kubernetes-ingress-controller)
is a software that runs in the same way as any other application on a cluster.
To start Traefik on the Kubernetes cluster,
a [`Deployment`](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/) resource must exist to describe how to configure
and scale containers horizontally to support larger workloads.
Start by creating a file called `02-traefik.yml` and paste the following `Deployment` resource:
```yaml tab="02-traefik.yml"
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik-deployment
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-account
containers:
- name: traefik
image: traefik:v3.4
args:
- --api.insecure
- --providers.kubernetesingress
ports:
- name: web
containerPort: 80
- name: dashboard
containerPort: 8080
```
The deployment contains an important attribute for customizing Traefik: `args`.
These arguments are the static configuration for Traefik.
From here, it is possible to enable the dashboard,
configure entry points,
select dynamic configuration providers,
and [more](../reference/static-configuration/cli.md).
In this deployment,
the static configuration enables the Traefik dashboard,
and uses Kubernetes native Ingress resources as router definitions to route incoming requests.
!!! info "When there is no entry point in the static configuration"
Traefik creates a default one called `web` using the port `80` routing HTTP requests.
!!! info "When enabling the [`api.insecure`](../../operations/api/#insecure) mode, Traefik exposes the dashboard on the port `8080`."
A deployment manages scaling and then can create lots of containers, called [Pods](https://kubernetes.io/docs/concepts/workloads/pods/).
Each Pod is configured following the `spec` field in the deployment.
Given that, a Deployment can run multiple Traefik Proxy Pods,
a piece is required to forward the traffic to any of the instance:
namely a [`Service`](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#Service).
Create a file called `02-traefik-services.yml` and insert the two `Service` resources:
```yaml tab="02-traefik-services.yml"
apiVersion: v1
kind: Service
metadata:
name: traefik-dashboard-service
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: dashboard
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-service
spec:
type: LoadBalancer
ports:
- targetPort: web
port: 80
selector:
app: traefik
```
!!! warning "It is possible to expose a service in different ways."
Depending on your working environment and use case, the `spec.type` might change.
It is strongly recommended to understand the available [service types](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) before proceeding to the next step.
It is now time to apply those files on your cluster to start Traefik.
```shell
kubectl apply -f 00-role.yml \
-f 00-account.yml \
-f 01-role-binding.yml \
-f 02-traefik.yml \
-f 02-traefik-services.yml
```
## Proxying applications
The only part still missing is the business application behind the reverse proxy.
For this guide, we use the example application [traefik/whoami](https://github.com/traefik/whoami),
but the principles are applicable to any other application.
The `whoami` application is an HTTP server running on port 80 which answers host-related information to the incoming requests.
As usual, start by creating a file called `03-whoami.yml` and paste the following `Deployment` resource:
```yaml tab="03-whoami.yml"
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
labels:
app: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- name: web
containerPort: 80
```
And continue by creating the following `Service` resource in a file called `03-whoami-services.yml`:
```yaml tab="03-whoami-services.yml"
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- name: web
port: 80
targetPort: web
selector:
app: whoami
```
Thanks to the Kubernetes API,
Traefik is notified when an Ingress resource is created, updated, or deleted.
This makes the process dynamic.
The ingresses are, in a way, the [dynamic configuration](../../providers/kubernetes-ingress/) for Traefik.
!!! tip
Find more information on [ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/),
and [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) in the official Kubernetes documentation.
Create a file called `04-whoami-ingress.yml` and insert the `Ingress` resource:
```yaml tab="04-whoami-ingress.yml"
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: whoami
port:
name: web
```
This `Ingress` configures Traefik to redirect any incoming requests starting with `/` to the `whoami:80` service.
At this point, all the configurations are ready.
It is time to apply those new files:
```shell
kubectl apply -f 03-whoami.yml \
-f 03-whoami-services.yml \
-f 04-whoami-ingress.yml
```
Now you should be able to access the `whoami` application and the Traefik dashboard.
Load the dashboard on a web browser: [`http://localhost:8080`](http://localhost:8080).
And now access the `whoami` application:
```shell
curl -v http://localhost/
```
!!! question "Going further"
- [Filter the ingresses](../providers/kubernetes-ingress.md#ingressclass) to use with [IngressClass](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)
- Use [IngressRoute CRD](../providers/kubernetes-crd.md)
- Protect [ingresses with TLS](../routing/providers/kubernetes-ingress.md#enabling-tls-via-annotations)
{!traefik-for-business-applications.md!}
--8<-- "content/getting-started/kubernetes.md"

View File

@@ -3,122 +3,4 @@ title: "Traefik Getting Started Quickly"
description: "Get started with Traefik Proxy and Docker."
---
# Quick Start
A Use Case Using Docker
{: .subtitle }
![quickstart-diagram](../assets/img/quickstart-diagram.png)
## Launch Traefik With the Docker Provider
Create a `docker-compose.yml` file where you will define a `reverse-proxy` service that uses the official Traefik image:
```yaml
version: '3'
services:
reverse-proxy:
# The official v3 Traefik docker image
image: traefik:v3.4
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
```
**That's it. Now you can launch Traefik!**
Start your `reverse-proxy` with the following command:
```shell
docker compose up -d reverse-proxy
```
You can open a browser and go to `http://localhost:8080/api/rawdata` to see Traefik's API rawdata (you'll go back there once you have launched a service in step 2).
## Traefik Detects New Services and Creates the Route for You
Now that you have a Traefik instance up and running, you will deploy new services.
Edit your `docker-compose.yml` file and add the following at the end of your file.
```yaml
version: '3'
services:
...
whoami:
# A container that exposes an API to show its IP address
image: traefik/whoami
labels:
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
```
The above defines `whoami`: a web service that outputs information about the machine it is deployed on (its IP address, host, and others).
Start the `whoami` service with the following command:
```shell
docker compose up -d whoami
```
Browse `http://localhost:8080/api/rawdata` and see that Traefik has automatically detected the new container and updated its own configuration.
When Traefik detects new services, it creates the corresponding routes, so you can call them ... _let's see!_ (Here, you're using curl)
```shell
curl -H Host:whoami.docker.localhost http://127.0.0.1
```
_Shows the following output:_
```yaml
Hostname: a656c8ddca6c
IP: 172.27.0.3
#...
```
## More Instances? Traefik Load Balances Them
Run more instances of your `whoami` service with the following command:
```shell
docker compose up -d --scale whoami=2
```
Browse to `http://localhost:8080/api/rawdata` and see that Traefik has automatically detected the new instance of the container.
Finally, see that Traefik load-balances between the two instances of your service by running the following command twice:
```shell
curl -H Host:whoami.docker.localhost http://127.0.0.1
```
The output will show alternatively one of the following:
```yaml
Hostname: a656c8ddca6c
IP: 172.27.0.3
#...
```
```yaml
Hostname: s458f154e1f1
IP: 172.27.0.4
# ...
```
!!! question "Where to Go Next?"
Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it is time to dive into [the user guides](../../user-guides/docker-compose/basic-example/ "Link to the user guides") and [the documentation](/ "Link to the docs landing page") and let Traefik work for you!
{!traefik-for-business-applications.md!}
--8<-- "content/getting-started/docker.md"

View File

@@ -767,6 +767,8 @@ docker run -v "/my/host/acme:/etc/traefik/acme" traefik
_Optional, Default=2160_
`certificatesDuration` specifies the duration (in hours) of the certificates issued by the CA server. It is used to determine when to renew the certificate, but it **doesn't** define the duration of the certificates, that is up to the CA server.
`certificatesDuration` is used to calculate two durations:
- `Renew Period`: the period before the end of the certificate duration, during which the certificate should be renewed.

View File

@@ -384,11 +384,11 @@ spec:
### Curve Preferences
This option allows to set the preferred elliptic curves in a specific order.
This option allows to set the enabled elliptic curves for key exchange.
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
See [CurvePreferences](https://godoc.org/crypto/tls#Config.CurvePreferences) and [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
```yaml tab="File (YAML)"
# Dynamic configuration

View File

@@ -7,18 +7,15 @@ description: "Traefik Proxy, an open-source Edge Router, auto-discovers configur
![Architecture](assets/img/traefik-architecture.png)
Traefik is an [open-source](https://github.com/traefik/traefik) *Application Proxy* that makes publishing your services a fun and easy experience.
It receives requests on behalf of your system, identifies which components are responsible for handling them, and routes them securely.
Traefik is an [open-source](https://github.com/traefik/traefik) Application Proxy and the core of the Traefik Hub Runtime Platform.
What sets Traefik apart, besides its many features, is that it automatically discovers the right configuration for your services.
The magic happens when Traefik inspects your infrastructure, where it finds relevant information and discovers which service serves which request.
If you start with Traefik for service discovery and routing, you can seamlessly add [API management](https://traefik.io/solutions/api-management/), [API gateway](https://traefik.io/solutions/api-gateway/), [AI gateway](https://traefik.io/solutions/ai-gateway/), and [API mocking](https://traefik.io/solutions/api-mocking/) capabilities as needed.
Traefik is natively compliant with every major cluster technology, such as Kubernetes, Docker Swarm, AWS, and [the list goes on](./reference/install-configuration/providers/overview.md); and can handle many at the same time. (It even works for legacy software running on bare metal.)
With Traefik, there is no need to maintain and synchronize a separate configuration file: everything happens automatically, in real time (no restarts, no connection interruptions).
With Traefik, you spend time developing and deploying new features to your system, not on configuring and maintaining its working state.
With 3.3 billion downloads and over 55k stars on GitHub, Traefik is used globally across hybrid cloud, multi-cloud, on prem, and bare metal environments running Kuberentes, Docker Swarm, AWS, [the list goes on](https://doc.traefik.io/traefik/reference/install-configuration/providers/overview/).
And if your needs change, you can add API gateway and API management capabilities seamlessly to your existing Traefik deployments. It takes less than a minute, theres no rip-and-replace, and all your configurations are preserved. See this in action in [our API gateway demo video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=docs).
Heres how it works—Traefik receives requests on behalf of your system, identifies which components are responsible for handling them, and routes them securely. It automatically discovers the right configuration for your services by inspecting your infrastructure to identify relevant information and which service serves which request.
Because everything happens automatically, in real time (no restarts, no connection interruptions), you can focus on developing and deploying new features to your system, instead of configuring and maintaining its working state.
!!! quote "From the Traefik Maintainer Team"
When developing Traefik, our main goal is to make it easy to use, and we're sure you'll enjoy it.
@@ -53,6 +50,6 @@ Use the sidebar to navigate to the section that is most appropriate for your nee
Have a question? Join our [Community Forum](https://community.traefik.io "Link to Traefik Community Forum") to discuss, learn, and connect with the Traefik community.
Using Traefik OSS in Production? Consider our enterprise-grade [API Gateway](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc) or our [24/7/365 OSS Support](https://info.traefik.io/request-commercial-support?cta=doc).
Using Traefik OSS in production? Consider upgrading to our API gateway ([watch demo video](https://info.traefik.io/watch-traefik-api-gw-demo)) for better security, control, and 24/7 support.
Explore our API Gateway upgrade via [this short demo video](https://info.traefik.io/watch-traefik-api-gw-demo?cta=doc).
Just need support? Explore our [24/7/365 support for Traefik OSS](https://info.traefik.io/request-commercial-support?cta=doc).

View File

@@ -160,8 +160,8 @@ Here is the list of supported operators:
### Fallback mechanism
The fallback mechanism returns a `HTTP 503 Service Unavailable` to the client instead of calling the target service.
This behavior cannot be configured.
By default the fallback mechanism returns a `HTTP 503 Service Unavailable` to the client instead of calling the target service.
The response code can be configured.
### `CheckPeriod`

View File

@@ -0,0 +1,161 @@
---
title: "Traefik V3 Migration Documentation"
description: "Migrate from Traefik Proxy v2 to v3 and update all the necessary configurations to take advantage of all the improvements. Read the technical documentation."
---
# Migration Guide: From v2 to v3
How to Migrate from Traefik v2 to Traefik v3.
{: .subtitle }
!!! success "Streamlined Migration Process"
Traefik v3 introduces minimal breaking changes and maintains backward compatibility with v2 syntax in dynamic configuration, offering a gradual migration path.
With Traefik v3, we are introducing a streamlined transition process from v2. Minimal breaking changes have been made to specific options in the [static configuration](./v2-to-v3-details.md#static-configuration-changes "Link to static configuration changes"), and we are ensuring backward compatibility with v2 syntax in the [dynamic configuration](./v2-to-v3-details.md#dynamic-configuration-changes "Link to dynamic configuration changes"). This will offer a gradual path for adopting the v3 syntax, allowing users to progressively migrate their Kubernetes ingress resources, Docker labels, etc., to the new format.
## Migration Overview
The migration process consists of three progressive steps designed to minimize risk and ensure a smooth transition:
!!! abstract "Migration Steps"
**Step 1:** [Prepare configurations and test v3](#step-1-prepare-configurations-and-test-v3)
**Step 2:** [Migrate production instances to Traefik v3](#step-2-migrate-production-instances-to-traefik-v3)
**Step 3:** [Progressively migrate dynamic configuration](#step-3-progressively-migrate-dynamic-configuration)
---
## Step 1: Prepare Configurations and Test v3
!!! info "Preparation Phase"
This step focuses on updating static configurations and enabling backward compatibility for a safe testing environment.
### Configuration Updates
**Review and Update Static Configuration**
Check the changes in [static configurations](./v2-to-v3-details.md#static-configuration-changes "Link to static configuration changes") and [operations](./v2-to-v3-details.md#operations-changes "Link to operations changes") brought by Traefik v3. Modify your configurations accordingly.
**Enable v2 Compatibility Mode**
Add the following configuration to maintain v2 syntax compatibility:
```yaml
# static configuration
core:
defaultRuleSyntax: v2
```
!!! note "Backward Compatibility"
This snippet in the static configuration makes the [v2 format](../migrate/v2-to-v3-details.md#configure-the-default-syntax-in-static-configuration "Link to configure default syntax in static config") the default rule matchers syntax.
### Testing Phase
**Start Your Test Environment**
1. Start Traefik v3 with the updated configuration
2. Monitor the startup logs for any errors
3. Test routing to your applications
**Validation Checklist**
- ✅ Traefik starts without error logs
- ✅ All routes are functioning correctly
- ✅ Applications are accessible through Traefik
!!! success "Ready for Next Step"
If you don't get any error logs while testing, you are good to go! Otherwise, follow the remaining migration options highlighted in the logs.
Once your Traefik test instances are starting and routing to your applications, proceed to the next step.
---
## Step 2: Migrate Production Instances to Traefik v3
!!! warning "Production Migration"
This is the critical step where you migrate your production environment. Proper monitoring and rollback preparation are essential.
### Migration Strategy
**Progressive Deployment**
We strongly advise you to follow a progressive migration strategy ([Kubernetes rolling update mechanism](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/ "Link to the Kubernetes rolling update documentation"), for example) to migrate your production instances to v3.
**Required Preparations**
!!! danger "Critical Requirements"
-**Real-time monitoring solution** for ingress traffic ([monitoring guide](https://traefik.io/blog/capture-traefik-metrics-for-apps-on-kubernetes-with-prometheus/ "Link to the blog on capturing Traefik metrics with Prometheus"))
-**Rollback plan** ready for immediate execution
-**Team availability** during migration window
### Migration Execution
**During Migration:**
1. **Monitor continuously:** Watch ingress traffic for any errors or anomalies
2. **Be prepared to rollback:** Have your rollback procedure ready to execute immediately
3. **Use debug logs:** Leverage debug and access logs to understand any issues that arise
**Validation Steps:**
- Monitor response times and error rates
- Verify all critical application paths are working
- Check that SSL/TLS termination is functioning correctly
- Validate middleware behavior
!!! success "Migration Complete"
Once every Traefik instance is updated, you will be on Traefik v3!
---
## Step 3: Progressively Migrate Dynamic Configuration
!!! info "Optional Immediate Step"
This step can be done later in the process, as Traefik v3 is compatible with the v2 format for [dynamic configuration](./v2-to-v3-details.md#dynamic-configuration-changes "Link to dynamic configuration changes"). Enable Traefik logs to get some help if any deprecated option is in use.
### Migration Process
**Review Dynamic Configuration Changes**
Check the changes in [dynamic configuration](./v2-to-v3-details.md#dynamic-configuration-changes "Link to dynamic configuration changes") to understand what updates are needed.
**Progressive Router Migration**
1. **Select a router** to migrate first (start with non-critical services)
2. **[Switch to v3 syntax](./v2-to-v3-details.md#configure-the-syntax-per-router "Link to configuring the syntax per router")** for that specific router
3. **Test thoroughly** to ensure ingress traffic is not impacted
4. **Deploy and validate** the updated resource
5. **Remove the old v2 resource** once validation is complete
6. **Repeat** for each remaining router
### Migration Best Practices
!!! tip "Migration Strategy"
- Start with development or staging environments
- Migrate one service at a time
- Test each migration thoroughly before proceeding
- Keep detailed logs of what was changed
### Final Configuration Cleanup
Once all Ingress resources are migrated to v3 syntax, remove the compatibility configuration:
```yaml
# Remove this from static configuration
core:
defaultRuleSyntax: v2 # ← Delete this entire section
```
!!! success "🎉 Migration Complete!"
You are now fully migrated to Traefik v3 and can take advantage of all the new features and improvements!
### Post-Migration Verification
**Final Checklist:**
- ✅ All routers use v3 syntax
- ✅ v2 compatibility mode disabled
- ✅ No deprecated warnings in logs
- ✅ All applications functioning correctly
- ✅ Performance metrics stable
{!traefik-for-business-applications.md!}

View File

@@ -706,3 +706,14 @@ and Traefik now keeps them encoded to avoid any ambiguity.
| `/foo/../bar` | PathPrefix(`/bar`) | Match | Match |
| `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match |
| `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match |
## v2.11.28
### MultiPath TCP
Since `v2.11.28`, the MultiPath TCP support introduced with `v2.11.26` has been removed.
It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message:
- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported`
However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124).

422
docs/content/migrate/v3.md Normal file
View File

@@ -0,0 +1,422 @@
---
title: "Traefik Migration Documentation"
description: "Learn the steps needed to migrate to new Traefik Proxy v3 versions. Read the technical documentation."
---
# Migration: Steps needed between the versions
This guide provides detailed migration steps for upgrading between different Traefik v3 versions. Each section covers breaking changes, deprecations, and configuration updates required for a smooth transition.
---
## v3.0 to v3.1
### Kubernetes Provider RBACs
Starting with v3.1, Traefik's Kubernetes Providers use the [EndpointSlices API](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) (requires Kubernetes >=v1.21) for service endpoint discovery. This change also introduces NodePort load-balancing capabilities.
The following RBAC updates are required for all Kubernetes providers:
- Remove endpoints permissions and add endpointslices:
```yaml
# Remove this section from your RBAC
# - apiGroups: [""]
# resources: ["endpoints"]
# verbs: ["get", "list", "watch"]
# Add this section instead
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
```
- Add nodes permissions for NodePort support:
```yaml
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
```
!!! note "Affected Providers"
These changes apply to:
- [KubernetesIngress](../routing/providers/kubernetes-ingress.md#configuration-example) provider
- [KubernetesCRD](../reference/dynamic-configuration/kubernetes-crd.md#rbac) provider
- [KubernetesGateway](../reference/dynamic-configuration/kubernetes-gateway-rbac.yml) provider
#### Gateway API: KubernetesGateway Provider
The KubernetesGateway Provider is no longer experimental in v3.1 and can be enabled without the `experimental.kubernetesgateway` option.
**Deprecated Configuration:**
??? example "Experimental kubernetesgateway option (deprecated)"
```yaml tab="File (YAML)"
experimental:
kubernetesgateway: true
```
```toml tab="File (TOML)"
[experimental]
kubernetesgateway=true
```
```bash tab="CLI"
--experimental.kubernetesgateway=true
```
**Migration Steps:**
1. Remove the `kubernetesgateway` option from the experimental section
2. Configure the provider using the [KubernetesGateway Provider documentation](../providers/kubernetes-gateway.md)
---
## v3.1.0 to v3.1.1
### IngressClass Lookup
The `disableIngressClassLookup` option has been deprecated and will be removed in the next major version.
**Migration Required:**
- **Old:** `disableIngressClassLookup`
- **New:** `disableClusterScopeResources`
The new option provides broader control over cluster scope resources discovery, including both IngressClass and Nodes resources.
---
## v3.1 to v3.2
### Kubernetes CRD Provider
New optional fields have been added to several CRDs. These updates are backward compatible and only add new functionality.
**Apply the latest CRDs:**
```shell
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.3/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
```
**Updated Resources:**
- [TraefikService](../../routing/services#mirroring-service) ([PR #11032](https://github.com/traefik/traefik/pull/11032))
- [RateLimit](../../middlewares/http/ratelimit) & [InFlightReq](../../middlewares/http/inflightreq) middlewares ([PR #9747](https://github.com/traefik/traefik/pull/9747))
- [Compress](../../middlewares/http/compress) middleware ([PR #10943](https://github.com/traefik/traefik/pull/10943))
### Kubernetes Gateway Provider Standard Channel
Starting with v3.2, the Kubernetes Gateway Provider now supports [GRPCRoute](https://gateway-api.sigs.k8s.io/api-types/grpcroute/) resources.
Therefore, in the corresponding RBACs (see [KubernetesGateway](../reference/dynamic-configuration/kubernetes-gateway-rbac.yml) provider RBACs),
the `grcroutes` and `grpcroutes/status` rights have to be added.
**Required RBAC Updates:**
```yaml
...
- apiGroups:
- gateway.networking.k8s.io
resources:
- grpcroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- grpcroutes/status
verbs:
- update
...
```
### Kubernetes Gateway Provider Experimental Channel
Due to breaking changes in Kubernetes Gateway [v1.2.0-rc1](https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.2.0-rc1), Traefik v3.3 only supports Kubernetes Gateway v1.2.x when experimental features are enabled.
**New Feature: BackendTLSPolicy Support**
The provider now supports [BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) resources.
Therefore, in the corresponding RBACs (see [KubernetesGateway](../reference/dynamic-configuration/kubernetes-gateway-rbac.yml) provider RBACs),
the `backendtlspolicies` and `backendtlspolicies/status` rights have to be added.
**Required RBAC Updates:**
```yaml
...
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- backendtlspolicies
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- backendtlspolicies/status
verbs:
- update
...
```
---
## v3.2.1
### X-Forwarded-Prefix Header Changes
In v3.2.1, the `X-Forwarded-Prefix` header is now handled like other `X-Forwarded-*` headers - Traefik removes it when sent from untrusted sources.
This change improves security by preventing header spoofing from untrusted clients. Refer to the [Forwarded headers documentation](../routing/entrypoints.md#forwarded-headers) for configuration details.
---
## v3.2.2
### Swarm Provider Label Updates
In v3.2.2, Swarm-specific labels have been deprecated and will be removed in a future version.
**Migration Required:**
| Deprecated Label | New Label |
|------------------|-----------|
| `traefik.docker.network` | `traefik.swarm.network` |
| `traefik.docker.lbswarm` | `traefik.swarm.lbswarm` |
---
## v3.2 to v3.3
### ACME DNS Certificate Resolver
In v3.3, DNS challenge configuration options have been reorganized for better clarity.
**Migration Required:**
| Deprecated Option | New Option |
|-------------------|------------|
| `acme.dnsChallenge.delaybeforecheck` | `acme.dnsChallenge.propagation.delayBeforeChecks` |
| `acme.dnsChallenge.disablepropagationcheck` | `acme.dnsChallenge.propagation.disableChecks` |
### Tracing Global Attributes
In v3.3, the tracing configuration has been clarified to better reflect its purpose.
**Migration Required:**
- **Old:** `tracing.globalAttributes`
- **New:** `tracing.resourceAttributes`
The old option name was misleading as it specifically adds resource attributes for the collector, not global span attributes.
---
## v3.3.4
### OpenTelemetry Request Duration Metric
In v3.3.4, the OpenTelemetry Request Duration metric unit has been standardized to match other providers and naming conventions.
**Change Details:**
- **Metric:** `traefik_(entrypoint|router|service)_request_duration_seconds`
- **Old Unit:** Milliseconds
- **New Unit:** Seconds
This change ensures consistency across all metrics providers and follows standard naming conventions.
---
## v3.3.5
### Compress Middleware Default Encodings
In v3.3.5, the default compression algorithms have been reordered to favor gzip compression.
**New Default:** `gzip, br, zstd`
This change affects requests that either:
- Don't specify preferred algorithms in the `Accept-Encoding` header
- Have no order preference in their `Accept-Encoding` header
The reordering helps ensure better compatibility with older clients that may not support newer compression algorithms.
---
## v3.3.6
### Request Path Sanitization
Starting with v3.3.6, incoming request paths are now automatically cleaned before processing for security and consistency.
**What's Changed:**
The following path segments are now interpreted and collapsed:
- `/../` (parent directory references)
- `/./` (current directory references)
- Duplicate slash segments (`//`)
**Disabling Sanitization:**
```yaml
# EntryPoint HTTP configuration
entryPoints:
web:
address: ":80"
http:
sanitizePath: false # Not recommended
```
!!! danger "Security Warning"
Setting `sanitizePath: false` is not safe. This option should only be used with legacy clients that don't properly URL-encode data. Always ensure requests are properly URL-encoded instead of disabling this security feature.
**Example Risk:**
Base64 data containing "/" characters can lead to unsafe routing when path sanitization is disabled and the data isn't URL-encoded.
---
## v3.3 to v3.4
### Kubernetes CRD Provider
#### Load-Balancing Strategy Updates
Starting with v3.4, HTTP service definitions now support additional load-balancing strategies for better traffic distribution.
**Apply Updated CRDs:**
```shell
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
```
**New Strategy Values:**
- `wrr` (Weighted Round Robin)
- `p2c` (Power of Two Choices)
!!! warning "Deprecation"
The `RoundRobin` strategy is deprecated but still supported (equivalent to `wrr`). It will be removed in the next major release.
Refer to the [HTTP Services Load Balancing documentation](../../routing/services/#load-balancing-strategy) for detailed information.
#### ServersTransport CA Certificate Configuration
A new `rootCAs` option has been added to the `ServersTransport` and `ServersTransportTCP` CRDs. It supports both ConfigMaps and Secrets for CA certificates and replaces the `rootCAsSecrets` option.
**Apply Updates:**
```shell
# Update CRDs
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
# Update RBACs
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.4/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml
```
**New Configuration Format:**
```yaml
---
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: foo
namespace: bar
spec:
rootCAs:
- configMap: ca-config-map
- secret: ca-secret
---
apiVersion: traefik.io/v1alpha1
kind: ServersTransportTCP
metadata:
name: foo
namespace: bar
spec:
rootCAs:
- configMap: ca-config-map
- secret: ca-secret
```
!!! warning "Deprecation"
The `rootCAsSecrets` option (Secrets only) is still supported but deprecated. It will be removed in the next major release.
### Rule Syntax Configuration
In v3.4, rule syntax configuration options will be removed in the next major version.
**Deprecated Options:**
- `core.defaultRuleSyntax` (static configuration)
- `ruleSyntax` (router option)
These options were transitional helpers for migrating from v2 to v3 syntax. Please ensure all router rules use v3 syntax before the next major release.
---
## v3.4.1
### Request Path Normalization
Starting with v3.4.1, request paths are now normalized according to RFC 3986 standards for better consistency and security.
**Normalization Process:**
1. **Unreserved Character Decoding:** Characters like `%2E` (.) are decoded to their literal form
2. **Case Normalization:** Percent-encoded characters are uppercased (`%2e` becomes `%2E`)
This follows [RFC 3986 percent-encoding normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2) and [case normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1) standards.
**Processing Order:**
1. Path normalization (cannot be disabled)
2. Path sanitization (if enabled)
### Reserved Character Handling in Routing
Starting with v3.4.1, reserved characters (per [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2)) remain encoded during router rule matching to prevent routing ambiguity.
**Why This Matters:**
Reserved characters change the meaning of request paths when decoded. Keeping them encoded during routing prevents security vulnerabilities and ensures predictable routing behavior.
### Request Path Matching Examples
The following table illustrates how path matching behavior has changed:
| Request Path | Router Rule | Traefik v3.4.0 | Traefik v3.4.1 | Explanation |
|-------------------|------------------------|----------------|----------------|-------------|
| `/foo%2Fbar` | ```PathPrefix(`/foo/bar`)``` | Match | No match | `%2F` (/) stays encoded, preventing false matches |
| `/foo/../bar` | ```PathPrefix(`/foo`)``` | No match | No match | Path traversal is sanitized away |
| `/foo/../bar` | ```PathPrefix(`/bar`)``` | Match | Match | Resolves to `/bar` after sanitization |
| `/foo/%2E%2E/bar` | ```PathPrefix(`/foo`)``` | Match | No match | Encoded dots normalized then sanitized |
| `/foo/%2E%2E/bar` | ```PathPrefix(`/bar`)``` | No match | Match | Resolves to `/bar` after normalization + sanitization |

View File

@@ -1,77 +0,0 @@
---
title: "Traefik V3 Migration Documentation"
description: "Migrate from Traefik Proxy v2 to v3 and update all the necessary configurations to take advantage of all the improvements. Read the technical documentation."
---
# Migration Guide: From v2 to v3
How to Migrate from Traefik v2 to Traefik v3.
{: .subtitle }
With Traefik v3, we are introducing a streamlined transition process from v2. Minimal breaking changes have been made to specific options in the [static configuration](./v2-to-v3-details.md#static-configuration-changes "Link to static configuration changes"), and we are ensuring backward compatibility with v2 syntax in the [dynamic configuration](./v2-to-v3-details.md#dynamic-configuration-changes "Link to dynamic configuration changes"). This will offer a gradual path for adopting the v3 syntax, allowing users to progressively migrate their Kubernetes ingress resources, Docker labels, etc., to the new format.
Here are the steps to progressively migrate from Traefik v2 to v3:
1. [Prepare configurations and test v3](#step-1-prepare-configurations-and-test-v3)
1. [Migrate production instances to Traefik v3](#step-2-migrate-production-instances-to-traefik-v3)
1. [Progressively migrate dynamic configuration](#step-3-progressively-migrate-dynamic-configuration)
## Step 1: Prepare Configurations and Test v3
Check the changes in [static configurations](./v2-to-v3-details.md#static-configuration-changes "Link to static configuration changes") and [operations](./v2-to-v3-details.md#operations-changes "Link to operations changes") brought by Traefik v3.
Modify your configurations accordingly.
Then, add the following snippet to the static configuration:
```yaml
# static configuration
core:
defaultRuleSyntax: v2
```
This snippet in the static configuration makes the [v2 format](../migration/v2-to-v3-details.md#configure-the-default-syntax-in-static-configuration "Link to configure default syntax in static config") the default rule matchers syntax.
Start Traefik v3 with this new configuration to test it.
If you dont get any error logs while testing, you are good to go!
Otherwise, follow the remaining migration options highlighted in the logs.
Once your Traefik test instances are starting and routing to your applications, proceed to the next step.
## Step 2: Migrate Production Instances to Traefik v3
We strongly advise you to follow a progressive migration strategy ([Kubernetes rolling update mechanism](https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/ "Link to the Kubernetes rolling update documentation"), for example) to migrate your production instances to v3.
!!! Warning
Ensure you have a [real-time monitoring solution](https://traefik.io/blog/capture-traefik-metrics-for-apps-on-kubernetes-with-prometheus/ "Link to the blog on capturing Traefik metrics with Prometheus") for your ingress traffic to detect issues instantly.
During the progressive migration, monitor your ingress traffic for any errors. Be prepared to rollback to a working state in case of any issues.
If you encounter any issues, leverage debug and access logs provided by Traefik to understand what went wrong and how to fix it.
Once every Traefik instance is updated, you will be on Traefik v3!
## Step 3: Progressively Migrate Dynamic Configuration
!!! info
This step can be done later in the process, as Traefik v3 is compatible with the v2 format for [dynamic configuration](./v2-to-v3-details.md#dynamic-configuration-changes "Link to dynamic configuration changes").
Enable Traefik logs to get some help if any deprecated option is in use.
Check the changes in [dynamic configuration](./v2-to-v3-details.md#dynamic-configuration-changes "Link to dynamic configuration changes").
Then, progressively [switch each router to the v3 syntax](./v2-to-v3-details.md#configure-the-syntax-per-router "Link to configuring the syntax per router").
Test and update each Ingress resource and ensure that ingress traffic is not impacted.
Once a v3 Ingress resource migration is validated, deploy the resource and delete the v2 Ingress resource.
Repeat it until all Ingress resources are migrated.
Now, remove the following snippet added to the static configuration in Step 1:
```yaml
# static configuration
core:
defaultRuleSyntax: v2
```
You are now fully migrated to Traefik v3 🎉

View File

@@ -319,3 +319,14 @@ and Traefik now keeps them encoded to avoid any ambiguity.
| `/foo/../bar` | PathPrefix(`/bar`) | Match | Match |
| `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match |
| `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match |
## v3.4.5
### MultiPath TCP
Since `v3.4.5`, the MultiPath TCP support introduced with `v3.4.2` has been removed.
It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message:
- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported`
However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124).

View File

@@ -288,8 +288,6 @@ It is possible to configure the Traefik to timestamp in a specific timezone by e
Example utilizing Docker Compose:
```yaml
version: "3.7"
services:
traefik:
image: traefik:v3.4

View File

@@ -0,0 +1,179 @@
---
title: "Logs and Access Logs"
description: "Logs and Access Logs in Traefik Proxy provide real-time insight into the health of your system. They enable swift error detection and intervention through alerts. By centralizing logs, you can streamline the debugging process during incident resolution."
---
## Logs
Logs concern everything that happens to Traefik itself (startup, configuration, events, shutdown, and so on).
### Configuration Example
To enable and configure logs in Traefik Proxy, you can use the static configuration file or Helm values if you are using the [Helm chart](https://github.com/traefik/traefik-helm-chart).
```yaml tab="Structured (YAML)"
log:
filePath: "/path/to/log-file.log"
format: json
level: INFO
```
```toml tab="Structured (TOML)"
[log]
filePath = "/path/to/log-file.log"
format = "json"
level = "INFO"
```
```yaml tab="Helm Chart Values"
logs:
general:
filePath: "/path/to/log-file.log"
format: json
level: INFO
```
## Access Logs
Access logs concern everything that happens to the requests handled by Traefik.
### Configuration Example
To enable and configure access logs in Traefik Proxy, you can use the static configuration file or Helm values if you are using the [Helm chart](https://github.com/traefik/traefik-helm-chart).
The following example enables access logs in JSON format, filters them to only include specific status codes, and customizes the fields that are kept or dropped.
```yaml tab="Structured (YAML)"
accessLog:
format: json
filters:
statusCodes:
- "200"
- "400-404"
- "500-503"
fields:
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Content-Type: keep
```
```toml tab="Structured (TOML)"
[accessLog]
format = "json"
[accessLog.filters]
statusCodes = ["200", "400-404", "500-503"]
[accessLog.fields]
[accessLog.fields.names]
ClientUsername = "drop"
[accessLog.fields.headers]
defaultMode = "keep"
[accessLog.fields.headers.names]
"User-Agent" = "redact"
"Content-Type" = "keep"
```
```yaml tab="Helm Chart Values"
# values.yaml
logs:
access:
enabled: true
format: json
filters:
statusCodes:
- "200"
- "400-404"
- "500-503"
fields:
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Content-Type: keep
```
## Per-Router Access Logs
You can enable or disable access logs for a specific router. This is useful for turning off logging for noisy routes while keeping it on globally.
Here's an example of disabling access logs on a specific router:
```yaml tab="Structured (YAML)"
http:
routers:
my-router:
rule: "Host(`example.com`)"
service: my-service
observability:
accessLogs: false
```
```toml tab="Structured (TOML)"
[http.routers.my-router.observability]
accessLogs = false
```
```yaml tab="Kubernetes"
# ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-router
spec:
routes:
- kind: Rule
match: Host(`example.com`)
services:
- name: my-service
port: 80
observability:
accessLogs: false
```
```bash tab="Labels"
labels:
- "traefik.http.routers.my-router.observability.accesslogs=false"
```
```json tab="Tags"
{
// ...
"Tags": [
"traefik.http.routers.my-router.observability.accesslogs=false"
]
}
```
When the `observability` options are not defined on a router, it inherits the behavior from the [entrypoint's observability configuration](./overview.md), or the global one.
## Log Formats
Traefik Proxy supports the following log formats:
- Common Log Format (CLF)
- JSON
## Access Log Filters
You can configure Traefik Proxy to only record access logs for requests that match certain criteria. This is useful for reducing the volume of logs and focusing on specific events.
The available filters are:
- **Status Codes:** Keep logs only for requests with specific HTTP status codes or ranges (e.g., `200`, `400-404`).
- **Retry Attempts:** Keep logs only when a request retry has occurred.
- **Minimum Duration:** Keep logs only for requests that take longer than a specified duration.
## Log Fields Customization
When using the `json` format, you can customize which fields are included in your access logs.
- **Request Fields:** You can choose to `keep`, `drop`, or `redact` any of the standard request fields. A complete list of available fields like `ClientHost`, `RequestMethod`, and `Duration` can be found in the [reference documentation](../reference/install-configuration/observability/logs-and-accesslogs.md#available-fields).
- **Request Headers:** You can also specify which request headers should be included in the logs, and whether their values should be `kept`, `dropped`, or `redacted`.
!!! info
For detailed configuration options, refer to the [reference documentation](../reference/install-configuration/observability/logs-and-accesslogs.md).

View File

@@ -0,0 +1,104 @@
---
title: "Metrics"
description: "Metrics in Traefik Proxy offer a comprehensive view of your infrastructure's health. They allow you to monitor critical indicators like incoming traffic volume. Metrics graphs and visualizations are helpful during incident triage in understanding the causes and implementing proactive measures."
---
# Metrics
Metrics in Traefik Proxy offer a comprehensive view of your infrastructure's health. They allow you to monitor critical indicators like incoming traffic volume. Metrics graphs and visualizations are helpful during incident triage in understanding the causes and implementing proactive measures.
## Available Metrics Providers
Traefik Proxy supports the following metrics providers:
- OpenTelemetry
- Prometheus
- Datadog
- InfluxDB 2.X
- StatsD
## Configuration
To enable metrics in Traefik Proxy, you need to configure the metrics provider in your static configuration file or helm values if you are using the [Helm chart](https://github.com/traefik/traefik-helm-chart). The following example shows how to configure the OpenTelemetry provider to send metrics to a collector.
```yaml tab="Structured (YAML)"
metrics:
otlp:
http:
endpoint: http://myotlpcollector:4318/v1/metrics
```
```toml tab="Structured (TOML)"
[metrics.otlp.http]
endpoint = "http://myotlpcollector:4318/v1/metrics"
```
```yaml tab="Helm Chart Values"
# values.yaml
metrics:
# Disable Prometheus (enabled by default)
prometheus: null
# Enable providing OTel metrics
otlp:
enabled: true
http:
enabled: true
endpoint: http://myotlpcollector:4318/v1/metrics
```
## Per-Router Metrics
You can enable or disable metrics collection for a specific router. This can be useful for excluding certain routes from your metrics data.
Here's an example of disabling metrics on a specific router:
```yaml tab="Structured (YAML)"
http:
routers:
my-router:
rule: "Host(`example.com`)"
service: my-service
observability:
metrics: false
```
```toml tab="Structured (TOML)"
[http.routers.my-router.observability]
metrics = false
```
```yaml tab="Kubernetes"
# ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-router
spec:
routes:
- kind: Rule
match: Host(`example.com`)
services:
- name: my-service
port: 80
observability:
metrics: false
```
```bash tab="Labels"
labels:
- "traefik.http.routers.my-router.observability.metrics=false"
```
```json tab="Tags"
{
// ...
"Tags": [
"traefik.http.routers.my-router.observability.metrics=false"
]
}
```
When the `observability` options are not defined on a router, it inherits the behavior from the [entrypoint's observability configuration](./overview.md), or the global one.
!!! info
For detailed configuration options, refer to the [reference documentation](../reference/install-configuration/observability/metrics.md).

View File

@@ -0,0 +1,80 @@
---
title: "Observability Overview"
description: "Traefik Proxy provides comprehensive monitoring and observability capabilities to maintain reliability and efficiency."
---
# Observability Overview
Traefik Proxy provides comprehensive monitoring and observability capabilities to maintain reliability and efficiency:
- [Logs and Access Logs](./logs-and-access-logs.md) provide real-time insight into the health of your system. They enable swift error detection and intervention through alerts. By centralizing logs, you can streamline the debugging process during incident resolution.
- [Metrics](./metrics.md) offer a comprehensive view of your infrastructure's health. They allow you to monitor critical indicators like incoming traffic volume. Metrics graphs and visualizations are helpful during incident triage in understanding the causes and implementing proactive measures.
- [Tracing](./tracing.md) enables tracking the flow of operations within your system. Using traces and spans, you can identify performance bottlenecks and pinpoint applications causing slowdowns to optimize response times effectively.
## Configuration Example
You can enable access logs, metrics, and tracing globally:
```yaml tab="Structured (YAML)"
accessLog: {}
metrics:
otlp: {}
tracing: {}
```
```toml tab="Structured (TOML)"
[accessLog]
[metrics.otlp]
[tracing.otlp]
```
```yaml tab="Helm Chart Values"
# values.yaml
accessLog:
enabled: true
metrics:
otlp:
enabled: true
tracing:
otlp:
enabled: true
```
You can disable access logs, metrics, and tracing for a specific [entrypoint](../reference/install-configuration/entrypoints.md):
```yaml tab="Structured (YAML)"
entryPoints:
EntryPoint0:
address: ':8000/udp'
observability:
accessLogs: false
tracing: false
metrics: false
```
```toml tab="Structured (TOML)"
[entryPoints.EntryPoint0.observability]
accessLogs = false
tracing = false
metrics = false
```
```yaml tab="Helm Chart Values"
additionalArguments:
- "--entrypoints.entrypoint0.observability.accesslogs=false"
- "--entrypoints.entrypoint0.observability.tracing=false"
- "--entrypoints.entrypoint0.observability.metrics=false"
```
!!! note
A router with its own observability configuration will override the global default.
{!traefik-for-business-applications.md!}

View File

@@ -0,0 +1,93 @@
---
title: "Tracing"
description: "Tracing in Traefik Proxy allows you to track the flow of operations within your system. Using traces and spans, you can identify performance bottlenecks and pinpoint applications causing slowdowns to optimize response times effectively."
---
# Tracing
Tracing in Traefik Proxy allows you to track the flow of operations within your system. Using traces and spans, you can identify performance bottlenecks and pinpoint applications causing slowdowns to optimize response times effectively.
Traefik Proxy uses [OpenTelemetry](https://opentelemetry.io/) to export traces. OpenTelemetry is an open-source observability framework. You can send traces to an OpenTelemetry collector, which can then export them to a variety of backends like Jaeger, Zipkin, or Datadog.
## Configuration
To enable tracing in Traefik Proxy, you need to configure it in your static configuration file or Helm values if you are using the [Helm chart](https://github.com/traefik/traefik-helm-chart). The following example shows how to configure the OpenTelemetry provider to send traces to a collector via HTTP.
```yaml tab="Structured (YAML)"
tracing:
otlp:
http:
endpoint: http://myotlpcollector:4318/v1/traces
```
```toml tab="Structured (TOML)"
[tracing.otlp.http]
endpoint = "http://myotlpcollector:4318/v1/traces"
```
```yaml tab="Helm Chart Values"
# values.yaml
tracing:
otlp:
enabled: true
http:
enabled: true
endpoint: http://myotlpcollector:4318/v1/traces
```
!!! info
For detailed configuration options, refer to the [tracing reference documentation](../reference/install-configuration/observability/tracing.md).
## Per-Router Tracing
You can enable or disable tracing for a specific router. This is useful for turning off tracing for specific routes while keeping it on globally.
Here's an example of disabling tracing on a specific router:
```yaml tab="Structured (YAML)"
http:
routers:
my-router:
rule: "Host(`example.com`)"
service: my-service
observability:
tracing: false
```
```toml tab="Structured (TOML)"
[http.routers.my-router.observability]
tracing = false
```
```yaml tab="Kubernetes"
# ingressoute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-router
spec:
routes:
- kind: Rule
match: Host(`example.com`)
services:
- name: my-service
port: 80
observability:
tracing: false
```
```yaml tab="Labels"
labels:
- "traefik.http.routers.my-router.observability.tracing=false"
```
```json tab="Tags"
{
// ...
"Tags": [
"traefik.http.routers.my-router.observability.tracing=false"
]
}
```
When the `observability` options are not defined on a router, it inherits the behavior from the [entrypoint's observability configuration](./overview.md), or the global one.

View File

@@ -40,7 +40,6 @@ This provider works with [Docker (standalone) Engine](https://docs.docker.com/en
Attaching labels to containers (in your docker compose file)
```yaml
version: "3"
services:
my-container:
# ...
@@ -162,8 +161,6 @@ See the [Docker API Access](#docker-api-access) section for more information.
The docker-compose file shares the docker sock with the Traefik container
```yaml
version: '3'
services:
traefik:
image: traefik:v3.4 # The official v3 Traefik docker image

View File

@@ -53,7 +53,6 @@ This provider works with [Docker Swarm Mode](https://docs.docker.com/engine/swar
then that service is automatically assigned to the router.
```yaml
version: "3"
services:
my-container:
deploy:
@@ -176,8 +175,6 @@ docker service create \
```
```yml tab="With Docker Compose"
version: '3'
services:
traefik:
# ...
@@ -208,8 +205,6 @@ See the [Docker Swarm API Access](#docker-api-access) section for more informati
The docker-compose file shares the docker sock with the Traefik container
```yaml
version: '3'
services:
traefik:
image: traefik:v3.4 # The official v3 Traefik docker image
@@ -455,10 +450,7 @@ _Optional, Default=""_
Defines a default docker network to use for connections to all containers.
This option can be overridden on a per-container basis with the `traefik.docker.network` [routing label](../routing/providers/swarm.md#traefikdockernetwork).
!!! warning
The Docker Swarm provider still uses the same per-container mechanism as the Docker provider, so therefore the label still uses the `docker` keyword intentionally.
This option can be overridden on a per-container basis with the `traefik.swarm.network` [routing label](../routing/providers/swarm.md#traefikswarmnetwork).
```yaml tab="File (YAML)"
providers:

View File

@@ -1931,7 +1931,7 @@ spec:
properties:
permanent:
description: Permanent defines whether the redirection is permanent
(301).
(308).
type: boolean
regex:
description: Regex defines the regex used to match and capture
@@ -1950,7 +1950,7 @@ spec:
properties:
permanent:
description: Permanent defines whether the redirection is permanent
(301).
(308).
type: boolean
port:
description: Port defines the port of the new URL.
@@ -2533,7 +2533,7 @@ spec:
type: object
curvePreferences:
description: |-
CurvePreferences defines the preferred elliptic curves in a specific order.
CurvePreferences defines the preferred elliptic curves.
More info: https://doc.traefik.io/traefik/v3.4/https/tls/#curve-preferences
items:
type: string

View File

@@ -2,6 +2,9 @@
CODE GENERATED AUTOMATICALLY
THIS FILE MUST NOT BE EDITED BY HAND
-->
| Key (Path) | Value |
|------------|-------|
| `traefik/http/middlewares/Middleware01/addPrefix/prefix` | `foobar` |
| `traefik/http/middlewares/Middleware02/basicAuth/headerField` | `foobar` |
| `traefik/http/middlewares/Middleware02/basicAuth/realm` | `foobar` |

View File

@@ -8,6 +8,4 @@ description: "Read the technical documentation to learn the Traefik Dynamic Conf
Dynamic configuration with KV stores.
{: .subtitle }
| Key (Path) | Value |
|----------------------------------------------------------------------------------------------|-------------|
--8<-- "content/reference/dynamic-configuration/kv-ref.md"

View File

@@ -0,0 +1,114 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.1
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
names:
kind: TLSOption
listKind: TLSOptionList
plural: tlsoptions
singular: tlsoption
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: |-
TLSOption is the CRD implementation of a Traefik TLS Option, allowing to configure some parameters of the TLS connection.
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#tls-options
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: TLSOptionSpec defines the desired state of a TLSOption.
properties:
alpnProtocols:
description: |-
ALPNProtocols defines the list of supported application level protocols for the TLS handshake, in order of preference.
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#alpn-protocols
items:
type: string
type: array
cipherSuites:
description: |-
CipherSuites defines the list of supported cipher suites for TLS versions up to TLS 1.2.
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#cipher-suites
items:
type: string
type: array
clientAuth:
description: ClientAuth defines the server's policy for TLS Client
Authentication.
properties:
clientAuthType:
description: ClientAuthType defines the client authentication
type to apply.
enum:
- NoClientCert
- RequestClientCert
- RequireAnyClientCert
- VerifyClientCertIfGiven
- RequireAndVerifyClientCert
type: string
secretNames:
description: SecretNames defines the names of the referenced Kubernetes
Secret storing certificate details.
items:
type: string
type: array
type: object
curvePreferences:
description: |-
CurvePreferences defines the preferred elliptic curves.
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
items:
type: string
type: array
maxVersion:
description: |-
MaxVersion defines the maximum TLS version that Traefik will accept.
Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
Default: None.
type: string
minVersion:
description: |-
MinVersion defines the minimum TLS version that Traefik will accept.
Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13.
Default: VersionTLS10.
type: string
preferServerCipherSuites:
description: |-
PreferServerCipherSuites defines whether the server chooses a cipher suite among his own instead of among the client's.
It is enabled automatically when minVersion or maxVersion is set.
Deprecated: https://github.com/golang/go/issues/45430
type: boolean
sniStrict:
description: SniStrict defines whether Traefik allows connections
from clients connections that do not specify a server_name extension.
type: boolean
type: object
required:
- metadata
- spec
type: object
served: true
storage: true

View File

@@ -1163,7 +1163,7 @@ spec:
properties:
permanent:
description: Permanent defines whether the redirection is permanent
(301).
(308).
type: boolean
regex:
description: Regex defines the regex used to match and capture
@@ -1182,7 +1182,7 @@ spec:
properties:
permanent:
description: Permanent defines whether the redirection is permanent
(301).
(308).
type: boolean
port:
description: Port defines the port of the new URL.

View File

@@ -78,7 +78,7 @@ spec:
type: object
curvePreferences:
description: |-
CurvePreferences defines the preferred elliptic curves in a specific order.
CurvePreferences defines the preferred elliptic curves.
More info: https://doc.traefik.io/traefik/v3.4/https/tls/#curve-preferences
items:
type: string

View File

@@ -18,6 +18,10 @@ entryPoints:
to: websecure
scheme: https
permanent: true
observability:
accessLogs: false
metrics: false
tracing: false
websecure:
address: :443
@@ -27,6 +31,28 @@ entryPoints:
- strip@kubernetescrd
```
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.http]
[entryPoints.web.http.redirections]
entryPoint = "websecure"
scheme = "https"
permanent = true
[entryPoints.web.observability]
accessLogs = false
metrics = false
tracing = false
[entryPoints.websecure]
address = ":443"
[entryPoints.websecure.tls]
[entryPoints.websecure.middlewares]
- auth@kubernetescrd
- strip@kubernetescrd
```
```yaml tab="Helm Chart Values"
## Values file
ports:
@@ -43,6 +69,9 @@ additionalArguments:
- --entryPoints.web.http.redirections.to=websecure
- --entryPoints.web.http.redirections.scheme=https
- --entryPoints.web.http.redirections.permanent=true
- --entryPoints.web.observability.accessLogs=false
- --entryPoints.web.observability.metrics=false
- --entryPoints.web.observability.tracing=false
```
!!! tip
@@ -54,39 +83,39 @@ additionalArguments:
## Configuration Options
| Field | Description | Default | Required |
|:----------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
| `address` | Define the port, and optionally the hostname, on which to listen for incoming connections and packets.<br /> It also defines the protocol to use (TCP or UDP).<br /> If no protocol is specified, the default is TCP. The format is:`[host]:port[/tcp\|/udp]`. | - | Yes |
| `accessLogs` | Defines whether a router attached to this EntryPoint produces access-logs by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
| `asDefault` | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
| `forwardedHeaders.trustedIPs` | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
| `forwardedHeaders.insecure` | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
| `http.redirections.`<br />`entryPoint.to` | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
| `http.redirections.`<br />`entryPoint.scheme` | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
| `http.redirections.`<br />`entryPoint.permanent` | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |
| `http.redirections.`<br />`entryPoint.priority` | Default priority applied to the routers attached to the `entryPoint`. | MaxInt32-1 (2147483646) | No |
| `http.encodeQuerySemicolons` | Enable query semicolons encoding. <br /> Use this option to avoid non-encoded semicolons to be interpreted as query parameter separators by Traefik. <br /> When using this option, the non-encoded semicolons characters in query will be transmitted encoded to the backend.<br /> More information [here](#encodequerysemicolons). | false | No |
| `http.sanitizePath` | Defines whether to enable the request path sanitization.<br /> More information [here](#sanitizepath). | false | No |
| `http.middlewares` | Set the list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point. <br />More information [here](#httpmiddlewares). | - | No |
| `http.tls` | Enable TLS on every router attached to the `entryPoint`. <br /> If no certificate are set, a default self-signed certificate is generates by Traefik. <br /> We recommend to not use self signed certificates in production. | - | No |
| `http.tls.options` | Apply TLS options on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../../routing/providers/kubernetes-crd.md#kind-tlsoption). | - | No |
| `http.tls.certResolver` | Apply a certificate resolver on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../install-configuration/tls/certificate-resolvers/overview.md). | - | No |
| `http2.maxConcurrentStreams` | Set the number of concurrent streams per connection that each client is allowed to initiate. <br /> The value must be greater than zero. | 250 | No |
| `http3` | Enable HTTP/3 protocol on the `entryPoint`. <br /> HTTP/3 requires a TCP `entryPoint`. as HTTP/3 always starts as a TCP connection that then gets upgraded to UDP. In most scenarios, this `entryPoint` is the same as the one used for TLS traffic.<br /> More information [here](#http3. | - | No |
| `http3.advertisedPort` | Set the UDP port to advertise as the HTTP/3 authority. <br /> It defaults to the entryPoint's address port. <br /> It can be used to override the authority in the `alt-svc` header, for example if the public facing port is different from where Traefik is listening. | - | No |
| `metrics` | Defines whether a router attached to this EntryPoint produces metrics by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
| `proxyProtocol.trustedIPs` | Enable PROXY protocol with Trusted IPs. <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
| Field | Description | Default | Required |
|:-----------------|:--------|:--------|:---------|
| `address` | Define the port, and optionally the hostname, on which to listen for incoming connections and packets.<br /> It also defines the protocol to use (TCP or UDP).<br /> If no protocol is specified, the default is TCP. The format is:`[host]:port[/tcp\|/udp] | - | Yes |
| `asDefault` | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
| `forwardedHeaders.trustedIPs` | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
| `forwardedHeaders.insecure` | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
| `http.redirections.`<br />`entryPoint.to` | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
| `http.redirections.`<br />`entryPoint.scheme` | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
| `http.redirections.`<br />`entryPoint.permanent` | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |
| `http.redirections.`<br />`entryPoint.priority` | Default priority applied to the routers attached to the `entryPoint`.| MaxInt32-1 (2147483646) | No |
| `http.encodeQuerySemicolons` | Enable query semicolons encoding. <br /> Use this option to avoid non-encoded semicolons to be interpreted as query parameter separators by Traefik. <br /> When using this option, the non-encoded semicolons characters in query will be transmitted encoded to the backend.<br /> More information [here](#encodequerysemicolons). | false | No |
| `http.sanitizePath` | Defines whether to enable the request path sanitization.<br /> More information [here](#sanitizepath). | false | No |
| `http.middlewares` | Set the list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point. <br />More information [here](#httpmiddlewares). | - | No |
| `http.tls` | Enable TLS on every router attached to the `entryPoint`. <br /> If no certificate are set, a default self-signed certificate is generates by Traefik. <br /> We recommend to not use self signed certificates in production.| - | No |
| `http.tls.options` | Apply TLS options on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../../routing/providers/kubernetes-crd.md#kind-tlsoption). | - | No |
| `http.tls.certResolver` | Apply a certificate resolver on every router attached to the `entryPoint`. <br /> The TLS options can be overidden per router. <br /> More information in the [dedicated section](../install-configuration/tls/certificate-resolvers/overview.md). | - | No |
| `http2.maxConcurrentStreams` | Set the number of concurrent streams per connection that each client is allowed to initiate. <br /> The value must be greater than zero. | 250 | No |
| `http3` | Enable HTTP/3 protocol on the `entryPoint`. <br /> HTTP/3 requires a TCP `entryPoint`. as HTTP/3 always starts as a TCP connection that then gets upgraded to UDP. In most scenarios, this `entryPoint` is the same as the one used for TLS traffic.<br /> More information [here](#http3. | - | No |
| `http3.advertisedPort` | Set the UDP port to advertise as the HTTP/3 authority. <br /> It defaults to the entryPoint's address port. <br /> It can be used to override the authority in the `alt-svc` header, for example if the public facing port is different from where Traefik is listening. | - | No |
| `observability.accessLogs` | Defines whether a router attached to this EntryPoint produces access-logs by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
| `observability.metrics` | Defines whether a router attached to this EntryPoint produces metrics by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
| `observability.tracing` | Defines whether a router attached to this EntryPoint produces traces by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
| `proxyProtocol.trustedIPs` | Enable PROXY protocol with Trusted IPs. <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
| `proxyProtocol.insecure` | Enable PROXY protocol trusting every incoming connection. <br /> Every remote client address will be replaced (`trustedIPs`) won't have any effect). <br /> Traefik supports [PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2. <br /> If PROXY protocol header parsing is enabled for the entry point, this entry point can accept connections with or without PROXY protocol headers. <br /> If the PROXY protocol header is passed, then the version is determined automatically.<br />We recommend to use this option only for tests purposes, not in production.<br /> More information [here](#proxyprotocol-and-load-balancers). | - | No |
| `reusePort` | Enable `entryPoints` from the same or different processes listening on the same TCP/UDP port by utilizing the `SO_REUSEPORT` socket option. <br /> It also allows the kernel to act like a load balancer to distribute incoming connections between entry points..<br /> More information [here](#reuseport). | false | No |
| `tracing` | Defines whether a router attached to this EntryPoint produces traces by default. Nonetheless, a router defining its own observability configuration will opt-out from this default. | true | No |
| `transport.`<br />`respondingTimeouts.`<br />`readTimeout` | Set the timeouts for incoming requests to the Traefik instance. This is the maximum duration for reading the entire request, including the body. Setting them has no effect for UDP `entryPoints`.<br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 60s (seconds) | No |
| `transport.`<br />`respondingTimeouts.`<br />`writeTimeout` | Maximum duration before timing out writes of the response. <br /> It covers the time from the end of the request header read to the end of the response write. <br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 0s (seconds) | No |
| `transport.`<br />`respondingTimeouts.`<br />`idleTimeout` | Maximum duration an idle (keep-alive) connection will remain idle before closing itself. <br /> If zero, no timeout exists <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 180s (seconds) | No |
| `transport.`<br />`lifeCycle.`<br />`graceTimeOut` | Set the duration to give active requests a chance to finish before Traefik stops. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds <br /> In this time frame no new requests are accepted. | 10s (seconds) | No |
| `transport.`<br />`lifeCycle.`<br />`requestAcceptGraceTimeout` | Set the duration to keep accepting requests prior to initiating the graceful termination period (as defined by the `transportlifeCycle.graceTimeOut` option). <br /> This option is meant to give downstream load-balancers sufficient time to take Traefik out of rotation. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 0s (seconds) | No |
| `transport.`<br />`keepAliveMaxRequests` | Set the maximum number of requests Traefik can handle before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). <br /> Zero means no limit. | 0 | No |
| `transport.`<br />`keepAliveMaxTime` | Set the maximum duration Traefik can handle requests before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). Zero means no limit. | 0s (seconds) | No |
| `udp.timeout` | Define how long to wait on an idle session before releasing the related resources. <br />The Timeout value must be greater than zero. | 3s (seconds)| No |
| `reusePort` | Enable `entryPoints` from the same or different processes listening on the same TCP/UDP port by utilizing the `SO_REUSEPORT` socket option. <br /> It also allows the kernel to act like a load balancer to distribute incoming connections between entry points..<br /> More information [here](#reuseport). | false | No |
| `transport.`<br />`respondingTimeouts.`<br />`readTimeout` | Set the timeouts for incoming requests to the Traefik instance. This is the maximum duration for reading the entire request, including the body. Setting them has no effect for UDP `entryPoints`.<br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 60s (seconds) | No |
| `transport.`<br />`respondingTimeouts.`<br />`writeTimeout` | Maximum duration before timing out writes of the response. <br /> It covers the time from the end of the request header read to the end of the response write. <br /> If zero, no timeout exists. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds. | 0s (seconds) | No |
| `transport.`<br />`respondingTimeouts.`<br />`idleTimeout` | Maximum duration an idle (keep-alive) connection will remain idle before closing itself. <br /> If zero, no timeout exists <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 180s (seconds) | No |
| `transport.`<br />`lifeCycle.`<br />`graceTimeOut` | Set the duration to give active requests a chance to finish before Traefik stops. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds <br /> In this time frame no new requests are accepted. | 10s (seconds) | No |
| `transport.`<br />`lifeCycle.`<br />`requestAcceptGraceTimeout` | Set the duration to keep accepting requests prior to initiating the graceful termination period (as defined by the `transportlifeCycle.graceTimeOut` option). <br /> This option is meant to give downstream load-balancers sufficient time to take Traefik out of rotation. <br />Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).<br />If no units are provided, the value is parsed assuming seconds | 0s (seconds) | No |
| `transport.`<br />`keepAliveMaxRequests` | Set the maximum number of requests Traefik can handle before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). <br /> Zero means no limit. | 0 | No |
| `transport.`<br />`keepAliveMaxTime` | Set the maximum duration Traefik can handle requests before sending a `Connection: Close` header to the client (for HTTP2, Traefik sends a GOAWAY). Zero means no limit. | 0s (seconds) | No |
| `udp.timeout` | Define how long to wait on an idle session before releasing the related resources. <br />The Timeout value must be greater than zero. | 3s (seconds)| No |
### asDefault
@@ -184,7 +213,7 @@ only routers with TLS enabled will be usable with HTTP/3.
### ProxyProtocol and Load-Balancers
The replacement of the remote client address will occur only for IP addresses listed in `trustedIPs`. This is where yoåu specify your load balancer IPs or CIDR ranges.
The replacement of the remote client address will occur only for IP addresses listed in `trustedIPs`. This is where you specify your load balancer IPs or CIDR ranges.
When queuing Traefik behind another load-balancer, make sure to configure
PROXY protocol on both sides.

View File

@@ -44,8 +44,82 @@ The section below describe how to configure Traefik logs using the static config
| `log.maxBackups` | Maximum number of old log files to retain.<br />The default is to retain all old log files. | 0 | No |
| `log.compress` | Compress log files in gzip after rotation. | false | No |
### OpenTelemetry
Traefik supports OpenTelemetry for logging. To enable OpenTelemetry, you need to set the following in the static configuration:
```yaml tab="File (YAML)"
experimental:
otlpLogs: true
```
```toml tab="File (TOML)"
[experimental]
otlpLogs = true
```
```sh tab="CLI"
--experimental.otlpLogs=true
```
!!! warning
This is an experimental feature.
#### Configuration Example
```yaml tab="File (YAML)"
experimental:
otlpLogs: true
log:
otlp:
http:
endpoint: https://collector:4318/v1/logs
headers:
Authorization: Bearer auth_asKXRhIMplM7El1JENjrotGouS1LYRdL
```
```toml tab="File (TOML)"
[experimental]
otlpLogs = true
[log.otlp]
http.endpoint = "https://collector:4318/v1/logs"
http.headers.Authorization = "Bearer auth_asKXRhIMplM7El1JENjrotGouS1LYRdL"
```
```sh tab="CLI"
--experimental.otlpLogs=true
--log.otlp.http.endpoint=https://collector:4318/v1/logs
--log.otlp.http.headers.Authorization=Bearer auth_asKXRhIMplM7El1JENjrotGouS1LYRdL
```
#### Configuration Options
| Field | Description | Default | Required |
|:-----------|:-----------------------------------------------------------------------------|:--------|:---------|
| `log.otlp.http` | This instructs the exporter to send logs to the OpenTelemetry Collector using HTTP.| | No |
| `log.otlp.http.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<scheme>://<host>:<port><path>`) | `https://localhost:4318/v1/logs` | No |
| `log.otlp.http.headers` | Additional headers sent with logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
| `log.otlp.http.tls` | Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector. | | No |
| `log.otlp.http.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
| `log.otlp.http.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
| `log.otlp.http.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
| `log.otlp.http.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
| `log.otlp.grpc` | This instructs the exporter to send logs to the OpenTelemetry Collector using gRPC.| | No |
| `log.otlp.grpc.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<host>:<port>`) | `localhost:4317` | No |
| `log.otlp.grpc.headers` | Additional headers sent with logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
| `log.otlp.grpc.insecure` | Instructs the exporter to send logs to the OpenTelemetry Collector using an insecure protocol. | false | No |
| `log.otlp.grpc.tls` | Defines the Client TLS configuration used by the exporter to send logs to the OpenTelemetry Collector. | | No |
| `log.otlp.grpc.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
| `log.otlp.grpc.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
| `log.otlp.grpc.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
| `log.otlp.grpc.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
## AccessLogs
Access logs concern everything that happens to the requests handled by Traefik.
### Configuration Example
```yaml tab="File (YAML)"
@@ -111,6 +185,7 @@ accessLog:
--accesslog.fields.headers.names.Authorization=drop
```
### Configuration Options
The section below describes how to configure Traefik access logs using the static configuration.
@@ -121,15 +196,87 @@ The section below describes how to configure Traefik access logs using the stati
| `accesslog.format` | By default, logs are written using the Common Log Format (CLF).<br />To write logs in JSON, use `json` in the `format` option.<br />If the given format is unsupported, the default (CLF) is used instead.<br />More information about CLF fields [here](#clf-format-fields). | "common" | No |
| `accesslog.bufferingSize` | To write the logs in an asynchronous fashion, specify a `bufferingSize` option.<br />This option represents the number of log lines Traefik will keep in memory before writing them to the selected output.<br />In some cases, this option can greatly help performances.| 0 | No |
| `accesslog.addInternals` | Enables access logs for internal resources (e.g.: `ping@internal`). | false | No |
| `accesslog.filters.statusCodes` | Limit the access logs to requests with a status codes in the specified range. | false | No |
| `accesslog.filters.statusCodes` | Limit the access logs to requests with a status codes in the specified range. | [ ] | No |
| `accesslog.filters.retryAttempts` | Keep the access logs when at least one retry has happened. | false | No |
| `accesslog.filters.minDuration` | Keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format, see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration)). | 0 | No |
| `accesslog.fields.defaultMode` | Mode to apply by default to the access logs fields (`keep`, `redact` or `drop`). | keep | No |
| `accesslog.fields.names` | Set the fields list to display in the access logs (format `name:mode`).<br /> Available fields list [here](#available-fields). | - | No |
| `accesslog.fields.names` | Set the fields list to display in the access logs (format `name:mode`).<br /> Available fields list [here](#available-fields). | [ ] | No |
| `accesslog.headers.defaultMode` | Mode to apply by default to the access logs headers (`keep`, `redact` or `drop`). | drop | No |
| `accesslog.headers.names` | Set the headers list to display in the access logs (format `name:mode`). | - | No |
| `accesslog.headers.names` | Set the headers list to display in the access logs (format `name:mode`). | [ ] | No |
#### CLF format fields
### OpenTelemetry
Traefik supports OpenTelemetry for access logs. To enable OpenTelemetry, you need to set the following in the static configuration:
```yaml tab="File (YAML)"
experimental:
otlpLogs: true
```
```toml tab="File (TOML)"
[experimental]
otlpLogs = true
```
```sh tab="CLI"
--experimental.otlpLogs=true
```
!!! warning
This is an experimental feature.
#### Configuration Example
```yaml tab="File (YAML)"
experimental:
otlpLogs: true
accesslog:
otlp:
http:
endpoint: https://collector:4318/v1/logs
headers:
Authorization: Bearer auth_asKXRhIMplM7El1JENjrotGouS1LYRdL
```
```toml tab="File (TOML)"
[experimental]
otlpLogs = true
[accesslog.otlp]
http.endpoint = "https://collector:4318/v1/logs"
http.headers.Authorization = "Bearer auth_asKXRhIMplM7El1JENjrotGouS1LYRdL"
```
```yaml tab="CLI"
--experimental.otlpLogs=true
--accesslog.otlp.http.endpoint=https://collector:4318/v1/logs
--accesslog.otlp.http.headers.Authorization=Bearer auth_asKXRhIMplM7El1JENjrotGouS1LYRdL
```
#### Configuration Options
| Field | Description | Default | Required |
|:-----------|:--------------------------|:--------|:---------|
| `accesslog.otlp.http` | This instructs the exporter to send access logs to the OpenTelemetry Collector using HTTP.| | No |
| `accesslog.otlp.http.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<scheme>://<host>:<port><path>`) | `https://localhost:4318/v1/logs` | No |
| `accesslog.otlp.http.headers` | Additional headers sent with access logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
| `accesslog.otlp.http.tls` | Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector. | | No |
| `accesslog.otlp.http.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
| `accesslog.otlp.http.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
| `accesslog.otlp.http.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
| `accesslog.otlp.http.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
| `accesslog.otlp.grpc` | This instructs the exporter to send access logs to the OpenTelemetry Collector using gRPC.| | No |
| `accesslog.otlp.grpc.endpoint` | The endpoint of the OpenTelemetry Collector. (format=`<host>:<port>`) | `localhost:4317` | No |
| `accesslog.otlp.grpc.headers` | Additional headers sent with access logs by the exporter to the OpenTelemetry Collector. | [ ] | No |
| `accesslog.otlp.grpc.insecure` | Instructs the exporter to send access logs to the OpenTelemetry Collector using an insecure protocol. | false | No |
| `accesslog.otlp.grpc.tls` | Defines the Client TLS configuration used by the exporter to send access logs to the OpenTelemetry Collector. | | No |
| `accesslog.otlp.grpc.tls.ca` | The path to the certificate authority used for the secure connection to the OpenTelemetry Collector, it defaults to the system bundle. | | No |
| `accesslog.otlp.grpc.tls.cert` | The path to the certificate to use for the OpenTelemetry Collector. | | No |
| `accesslog.otlp.grpc.tls.key` | The path to the key to use for the OpenTelemetry Collector. | | No |
| `accesslog.otlp.grpc.tls.insecureSkipVerify` | Instructs the OpenTelemetry Collector to accept any certificate presented by the server regardless of the hostname in the certificate. | false | No |
### CLF format fields
Below the fields displayed with the CLF format:
@@ -140,7 +287,7 @@ Below the fields displayed with the CLF format:
"<Traefik_router_name>" "<Traefik_server_URL>" <request_duration_in_ms>ms
```
#### Available Fields
### Available Fields
| Field | Description |
|-------------------------|------------------|
@@ -179,7 +326,7 @@ Below the fields displayed with the CLF format:
| `TLSCipher` | The TLS cipher used by the connection (e.g. `TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA`) (if connection is TLS). |
| `TLSClientSubject` | The string representation of the TLS client certificate's Subject (e.g. `CN=username,O=organization`). |
#### Log Rotation
### Log Rotation
Traefik close and reopen its log files, assuming they're configured, on receipt of a USR1 signal.
This allows the logs to be rotated and processed by an external program, such as `logrotate`.
@@ -187,7 +334,7 @@ This allows the logs to be rotated and processed by an external program, such as
!!! warning
This does not work on Windows due to the lack of USR signals.
#### Time Zones
### Time Zones
Traefik will timestamp each log line in UTC time by default.
@@ -199,8 +346,6 @@ It is possible to configure the Traefik to timestamp in a specific timezone by e
Example utilizing Docker Compose:
```yaml
version: "3.7"
services:
traefik:
image: traefik:v3.4

View File

@@ -29,7 +29,6 @@ providers:
Attach labels to containers (in your Docker compose file)
```yaml
version: "3"
services:
my-container:
# ...
@@ -67,8 +66,6 @@ See the [Docker API Access](#docker-api-access) section for more information.
The docker-compose file shares the docker sock with the Traefik container
```yaml
version: '3'
services:
traefik:
image: traefik:v3.1 # The official v3 Traefik docker image

View File

@@ -8,6 +8,11 @@ description: "Understand the requirements, routing configuration, and how to set
The Traefik Kubernetes Ingress provider is a Kubernetes Ingress controller; i.e,
it manages access to cluster services by supporting the [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) specification.
??? warning "Ingress Backend Resource not supported"
Referencing backend service endpoints using [`spec.rules.http.paths.backend.resource`](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressBackend) is not supported.
Use `spec.rules.http.paths.backend.service` instead.
## Configuration Example
You can enable the `kubernetesIngress` provider as detailed below:

View File

@@ -33,7 +33,6 @@ When there is only one service, and the router does not specify a service,
then that service is automatically assigned to the router.
```yaml tab="Labels"
version: "3"
services:
my-container:
deploy:
@@ -44,25 +43,25 @@ services:
## Configuration Options
| Field | Description | Default | Required |
|:------|:----------------------------------------------------------|:---------------------|:---------|
| `providers.providersThrottleDuration` | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.<br />If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.<br />**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
| `providers.swarm.endpoint` | Specifies the Docker API endpoint. See [here](#endpoint) for more information| `unix:///var/run/docker.sock` | Yes |
| `providers.swarm.username` | Defines the username for Basic HTTP authentication. This should be used when the Docker daemon socket is exposed through an HTTP proxy that requires Basic HTTP authentication.| "" | No |
| `providers.swarm.password` | Defines the password for Basic HTTP authentication. This should be used when the Docker daemon socket is exposed through an HTTP proxy that requires Basic HTTP authentication.| "" | No |
| `providers.swarm.useBindPortIP` | Instructs Traefik to use the IP/Port attached to the container's binding instead of its inner network IP/Port. See [here](#usebindportip) for more information | false | No |
| `providers.swarm.exposedByDefault` | Expose containers by default through Traefik. See [here](./overview.md#restrict-the-scope-of-service-discovery) for additional information | true | No |
| `providers.swarm.network` | Defines a default docker network to use for connections to all containers. This option can be overridden on a per-container basis with the `traefik.docker.network` label.| "" | No |
| `providers.swarm.defaultRule` | Defines what routing rule to apply to a container if no rule is defined by a label. See [here](#defaultrule) for more information | ```"Host(`{{ normalize .Name }}`)"``` | No |
| `providers.swarm.refreshSeconds` | Defines the polling interval for Swarm Mode. | "15s" | No |
| `providers.swarm.httpClientTimeout` | Defines the client timeout (in seconds) for HTTP connections. If its value is 0, no timeout is set. | 0 | No |
| `providers.swarm.watch` | Instructs Traefik to watch Docker events or not. | True | No |
| `providers.swarm.constraints` | Defines an expression that Traefik matches against the container labels to determine whether to create any route for that container. See [here](#constraints) for more information. | "" | No |
| `providers.swarm.allowEmptyServices` | Instructs the provider to create any [servers load balancer](../../../routing/services/index.md#servers-load-balancer) defined for Docker containers regardless of the [healthiness](https://docs.docker.com/engine/reference/builder/#healthcheck) of the corresponding containers. | false | No |
| `providers.swarm.tls.ca` | Defines the path to the certificate authority used for the secure connection to Docker, it defaults to the system bundle. | "" | No |
| `providers.swarm.tls.cert` | Defines the path to the public certificate used for the secure connection to Docker. When using this option, setting the `key` option is required. | "" | Yes |
| `providers.swarm.tls.key` | Defines the path to the private key used for the secure connection to Docker. When using this option, setting the `cert` option is required. | "" | Yes |
| `providers.swarm.tls.insecureSkipVerify` | Instructs the provider to accept any certificate presented by the Docker server when establishing a TLS connection, regardless of the hostnames the certificate covers. | false | No |
| Field | Description | Default | Required |
|:-----------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------|:---------|
| `providers.providersThrottleDuration` | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.<br />If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.<br />**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
| `providers.swarm.endpoint` | Specifies the Docker API endpoint. See [here](#endpoint) for more information | `unix:///var/run/docker.sock` | Yes |
| `providers.swarm.username` | Defines the username for Basic HTTP authentication. This should be used when the Docker daemon socket is exposed through an HTTP proxy that requires Basic HTTP authentication. | "" | No |
| `providers.swarm.password` | Defines the password for Basic HTTP authentication. This should be used when the Docker daemon socket is exposed through an HTTP proxy that requires Basic HTTP authentication. | "" | No |
| `providers.swarm.useBindPortIP` | Instructs Traefik to use the IP/Port attached to the container's binding instead of its inner network IP/Port. See [here](#usebindportip) for more information | false | No |
| `providers.swarm.exposedByDefault` | Expose containers by default through Traefik. See [here](./overview.md#restrict-the-scope-of-service-discovery) for additional information | true | No |
| `providers.swarm.network` | Defines a default docker network to use for connections to all containers. This option can be overridden on a per-container basis with the `traefik.swarm.network` label. | "" | No |
| `providers.swarm.defaultRule` | Defines what routing rule to apply to a container if no rule is defined by a label. See [here](#defaultrule) for more information | ```"Host(`{{ normalize .Name }}`)"``` | No |
| `providers.swarm.refreshSeconds` | Defines the polling interval for Swarm Mode. | "15s" | No |
| `providers.swarm.httpClientTimeout` | Defines the client timeout (in seconds) for HTTP connections. If its value is 0, no timeout is set. | 0 | No |
| `providers.swarm.watch` | Instructs Traefik to watch Docker events or not. | True | No |
| `providers.swarm.constraints` | Defines an expression that Traefik matches against the container labels to determine whether to create any route for that container. See [here](#constraints) for more information. | "" | No |
| `providers.swarm.allowEmptyServices` | Instructs the provider to create any [servers load balancer](../../../routing/services/index.md#servers-load-balancer) defined for Docker containers regardless of the [healthiness](https://docs.docker.com/engine/reference/builder/#healthcheck) of the corresponding containers. | false | No |
| `providers.swarm.tls.ca` | Defines the path to the certificate authority used for the secure connection to Docker, it defaults to the system bundle. | "" | No |
| `providers.swarm.tls.cert` | Defines the path to the public certificate used for the secure connection to Docker. When using this option, setting the `key` option is required. | "" | Yes |
| `providers.swarm.tls.key` | Defines the path to the private key used for the secure connection to Docker. When using this option, setting the `cert` option is required. | "" | Yes |
| `providers.swarm.tls.insecureSkipVerify` | Instructs the provider to accept any certificate presented by the Docker server when establishing a TLS connection, regardless of the hostnames the certificate covers. | false | No |
### `endpoint`
@@ -73,8 +72,6 @@ See the [Docker Swarm API Access](#docker-api-access) section for more informati
The docker-compose file shares the docker sock with the Traefik container
```yaml
version: '3'
services:
traefik:
image: traefik:v3.1 # The official v3 Traefik docker image
@@ -405,8 +402,6 @@ docker service create \
```
```yml tab="With Docker Compose"
version: '3'
services:
traefik:
# ...

View File

@@ -72,8 +72,6 @@ When using Docker or Amazon ECS, you can define routing configuration using cont
When deploying a Docker container, you can specify labels to define routing rules and services:
```yaml
version: '3'
services:
my-service:
image: my-image

View File

@@ -265,6 +265,10 @@ http:
The mirroring is able to mirror requests sent to a service to other services. Please note that by default the whole request is buffered in memory while it is being mirrored. See the `maxBodySize` option in the example below for how to modify this behaviour. You can also omit the request body by setting the `mirrorBody` option to false.
!!! warning "Default behavior of `percent`"
When configuring a `mirror` service, if the `percent` field is not set, it defaults to `0`, meaning **no traffic will be sent to the mirror**.
!!! info "Supported Providers"
This strategy can be defined currently with the [File](../../../install-configuration/providers/others/file.md) or [IngressRoute](../../../install-configuration/providers/kubernetes/kubernetes-ingress.md) providers.
@@ -285,6 +289,8 @@ http:
maxBodySize: 1024
mirrors:
- name: appv2
# Percent defines the percentage of requests that should be mirrored.
# Default value is 0, which means no traffic will be sent to the mirror.
percent: 10
appv1:

View File

@@ -113,8 +113,8 @@ Here is the list of supported operators:
### Fallback mechanism
The fallback mechanism returns a `HTTP 503 Service Unavailable` to the client instead of calling the target service.
This behavior cannot be configured.
By default the fallback mechanism returns a `HTTP 503 Service Unavailable` to the client instead of calling the target service.
The response code can be configured.
## State

View File

@@ -117,7 +117,7 @@ It only matches the request client IP and does not use the `X-Forwarded-For` hea
RuleSyntax option is deprecated and will be removed in the next major version.
Please do not use this field and rewrite the router rules to use the v3 syntax.
In Traefik v3 a new rule syntax has been introduced ([migration guide](../../../../migration/v3.md)). the `ruleSyntax` option allows to configure the rule syntax to be used for parsing the rule on a per-router basis. This allows to have heterogeneous router configurations and ease migration.
In Traefik v3 a new rule syntax has been introduced ([migration guide](../../../../migrate/v3.md)). the `ruleSyntax` option allows to configure the rule syntax to be used for parsing the rule on a per-router basis. This allows to have heterogeneous router configurations and ease migration.
The default value of the `ruleSyntax` option is inherited from the `defaultRuleSyntax` option in the install configuration (formerly known as static configuration). By default, the `defaultRuleSyntax` static option is v3, meaning that the default rule syntax is also v3

View File

@@ -106,7 +106,7 @@ tls:
### Curve Preferences
This option allows to set the preferred elliptic curves in a specific order.
This option allows to set the preferred elliptic curves.
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.

View File

@@ -51,7 +51,7 @@ spec:
| `minVersion` | Minimum TLS version that is acceptable. | "VersionTLS12" | No |
| `maxVersion` | Maximum TLS version that is acceptable.<br />We do not recommend setting this option to disable TLS 1.3. | | No |
| `cipherSuites` | List of supported [cipher suites](https://godoc.org/crypto/tls#pkg-constants) for TLS versions up to TLS 1.2.<br />[Cipher suites defined for TLS 1.2 and below cannot be used in TLS 1.3, and vice versa.](https://tools.ietf.org/html/rfc8446)<br />With TLS 1.3, [the cipher suites are not configurable](https://golang.org/doc/go1.12#tls_1_3) (all supported cipher suites are safe in this case). | | No |
| `curvePreferences` | List of the elliptic curves references that will be used in an ECDHE handshake, in preference order.<br />Use curves names from [`crypto`](https://godoc.org/crypto/tls#CurveID) or the [RFC](https://tools.ietf.org/html/rfc8446#section-4.2.7).<br />See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. | | No |
| `curvePreferences` | List of the elliptic curves references that will be used in an ECDHE handshake.<br />Use curves names from [`crypto`](https://godoc.org/crypto/tls#CurveID) or the [RFC](https://tools.ietf.org/html/rfc8446#section-4.2.7).<br />See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information. | | No |
| `clientAuth.secretNames` | Client Authentication (mTLS) option.<br />List of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace).<br /> The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. | | No |
| `clientAuth.clientAuthType` | Client Authentication (mTLS) option.<br />Client authentication type to apply. Available values [here](#client-authentication-mtls). | | No |
| `sniStrict` | Allow rejecting connections from clients connections that do not specify a server_name extension.<br />The [default certificate](../../../http/tls/tls-certificates.md#default-certificate) is never served is the option is enabled. | false | No |
@@ -60,7 +60,7 @@ spec:
### Client Authentication (mTLS)
The `clientAuth.clientAuthType` option governs the behaviour as follows:
The `clientAuth.clientAuthType` option governs the behavior as follows:
- `NoClientCert`: disregards any client certificate.
- `RequestClientCert`: asks for a certificate but proceeds anyway if none is provided.

View File

@@ -35,7 +35,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
Attaching labels to containers (in your docker compose file)
```yaml
version: "3"
services:
my-container:
# ...
@@ -48,7 +47,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```yaml
version: "3"
services:
my-container:
# ...
@@ -71,7 +69,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
In this example, requests are forwarded for `http://example-a.com` to `http://<private IP of container>:8000` in addition to `http://example-b.com` forwarding to `http://<private IP of container>:9000`:
```yaml
version: "3"
services:
my-container:
# ...

View File

@@ -48,7 +48,6 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
then that service is automatically assigned to the router.
```yaml
version: "3"
services:
my-container:
deploy:
@@ -67,7 +66,6 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```yaml
version: "3"
services:
my-container:
# ...
@@ -93,7 +91,6 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
In this example, requests are forwarded for `http://example-a.com` to `http://<private IP of container>:8000` in addition to `http://example-b.com` forwarding to `http://<private IP of container>:9000`:
```yaml
version: "3"
services:
my-container:
# ...

View File

@@ -42,7 +42,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
Attaching labels to containers (in your docker compose file)
```yaml
version: "3"
services:
my-container:
# ...
@@ -55,7 +54,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```yaml
version: "3"
services:
my-container:
# ...
@@ -78,7 +76,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
In this example, requests are forwarded for `http://example-a.com` to `http://<private IP of container>:8000` in addition to `http://example-b.com` forwarding to `http://<private IP of container>:9000`:
```yaml
version: "3"
services:
my-container:
# ...

View File

@@ -1671,7 +1671,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre
| [2] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable. |
| [3] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable. |
| [4] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2. |
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order. |
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake. |
| [6] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls). |
| [7] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. |
| [8] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert`. |

View File

@@ -55,7 +55,6 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
then that service is automatically assigned to the router.
```yaml
version: "3"
services:
my-container:
deploy:
@@ -74,7 +73,6 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```yaml
version: "3"
services:
my-container:
# ...
@@ -100,7 +98,6 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
In this example, requests are forwarded for `http://example-a.com` to `http://<private IP of container>:8000` in addition to `http://example-b.com` forwarding to `http://<private IP of container>:9000`:
```yaml
version: "3"
services:
my-container:
# ...

View File

@@ -527,7 +527,7 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul
_Optional, Default=""_
In Traefik v3 a new rule syntax has been introduced ([migration guide](../../migration/v2-to-v3.md#router-rule-matchers)).
In Traefik v3 a new rule syntax has been introduced ([migration guide](../../migrate/v2-to-v3.md#router-rule-matchers)).
`ruleSyntax` option allows to configure the rule syntax to be used for parsing the rule on a per-router basis.
This allows to have heterogeneous router configurations and ease migration.
@@ -1351,7 +1351,7 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul
_Optional, Default=""_
In Traefik v3 a new rule syntax has been introduced ([migration guide](../../migration/v2-to-v3.md#router-rule-matchers)).
In Traefik v3 a new rule syntax has been introduced ([migration guide](../../migrate/v2-to-v3.md#router-rule-matchers)).
`ruleSyntax` option allows to configure the rule syntax to be used for parsing the rule on a per-router basis.
This allows to have heterogeneous router configurations and ease migration.

View File

@@ -1259,6 +1259,10 @@ Please note that by default the whole request is buffered in memory while it is
See the maxBodySize option in the example below for how to modify this behaviour.
You can also omit the request body by setting the mirrorBody option to `false`.
!!! warning "Default behavior of `percent`"
When configuring a `mirror` service, if the `percent` field is not set, it defaults to `0`, meaning **no traffic will be sent to the mirror**.
!!! info "Supported Providers"
This strategy can be defined currently with the [File](../../providers/file.md) or [IngressRoute](../../providers/kubernetes-crd.md) providers.
@@ -1279,6 +1283,8 @@ http:
maxBodySize: 1024
mirrors:
- name: appv2
# Percent defines the percentage of requests that should be mirrored.
# Default value is 0, which means no traffic will be sent to the mirror.
percent: 10
appv1:

View File

@@ -0,0 +1,299 @@
---
title: Setup Traefik Proxy in Docker Standalone
description: "Learn how to Setup Traefik on Docker with HTTP/HTTPS entrypoints, redirects, secure dashboard, basic TLS, metrics, tracing, accesslogs."
---
This guide provides an in-depth walkthrough for installing and configuring Traefik Proxy within a Docker container using the official Traefik Docker image & Docker Compose. In this guide, we'll cover the following:
- Enable the [Docker provider](../reference/install-configuration/providers/docker.md)
- Expose **web** (HTTP :80) and **websecure** (HTTPS :443) entrypoints
- Redirect all HTTP traffic to HTTPS
- Secure the Traefik dashboard with **basicauth**
- Terminate TLS with a selfsigned certificate for `*.docker.localhost`
- Deploy the **whoami** demo service
- Enable accesslogs and Prometheus metrics
## Prerequisites
- Docker Desktop / Engine
- Docker Compose
- `openssl`
- `htpasswd` from `apache2-utils`
## Create a selfsigned certificate
Before Traefik can serve HTTPS locally it needs a certificate. In production youd use one from a trusted CA, but for a singlemachine stack a quick selfsigned cert is enough. We can create one with openssl by running the following commands:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
The `certs` folder now holds `local.crt` and `local.key`, which will be mounted readonly into Traefik.
## Create the Traefik Dashboard Credentials
In production, it is advisable to have some form of authentication/security for the Traefik dashboard. Traefik can be secured with the [basicauth middleware](../reference/routing-configuration/http/middlewares/basicauth.md). To do this, generate a hashed username/password pair that Traefiks middleware will validate:
```bash
htpasswd -nb admin "P@ssw0rd" | sed -e 's/\$/\$\$/g'
```
Copy the full output (e.g., admin:$$apr1$$…) — we'll need this for the middleware configuration.
## Create a docker-compose.yaml
Now define the whole stack in a Compose file. This file declares Traefik, mounts the certificate, sets up a dedicated network, and later hosts the whoami demo service.
!!! note
You can also choose to use the Docker CLI and a configuration file to run Traefik, but for this tutorial, we'll be using Docker Compose.
First, create a folder named `dynamic` and create a file named `tls.yaml` for dynamic configuration. Paste the TLS certificate configuration into the file:
```yaml
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
```
In the same folder as the `dynamic/tls.yaml` file, create a `docker-compose.yaml` file and include the following:
```yaml
services:
traefik:
image: traefik:v3.4
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
# Connect to the 'traefik_proxy' overlay network for inter-container communication across nodes
- proxy
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./certs:/certs:ro
- ./dynamic:/dynamic:ro
command:
# EntryPoints
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
# Attach the static configuration tls.yaml file that contains the tls configuration settings
- "--providers.file.filename=/dynamic/tls.yaml"
# Providers
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
# API & Dashboard
- "--api.dashboard=true"
- "--api.insecure=false"
# Observability
- "--log.level=INFO"
- "--accesslog=true"
- "--metrics.prometheus=true"
# Traefik Dynamic configuration via Docker labels
labels:
# Enable selfrouting
- "traefik.enable=true"
# Dashboard router
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls=true"
# Basicauth middleware
- "traefik.http.middlewares.dashboard-auth.basicauth.users=<PASTE_HASH_HERE>"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"
# Whoami application
whoami:
image: traefik/whoami
container_name: whoami
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls=true"
networks:
proxy:
name: proxy
```
!!! info
- Remember to replace `<PASTE_HASH_HERE>` with the hash generated earlier.
- The `--api.insecure=false` flag is used to secure the API and prevent the dashboard from being exposed on port 8080. This is done because we are exposing the dashboard with a HTTPS router.
## Launch the stack
With the Compose file and supporting assets in place, start the containers and let Docker wire up networking behind the scenes:
```bash
docker compose up -d
```
Traefik will start, read its static configuration from the `command` arguments, connect to the Docker socket, detect its own labels for dynamic configuration (dashboard routing and auth), and begin listening on ports 80 and 443. HTTP requests will be redirected to HTTPS.
## Access the Dashboard
Now that Traefik is deployed, you can access the dashboard at [https://dashboard.docker.localhost](https://dashboard.docker.localhost) and it should prompt for the Basic Authentication credentials you configured:
![Traefik Dashboard](../assets/img/setup/traefik-dashboard-docker.png)
## Test the whoami Application
You can test the application using curl:
```bash
curl -k https://whoami.docker.localhost/
```
```bash
Hostname: whoami-76c9859cfc-k7jzs
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.59
IP: fe80::50d7:a2ff:fed5:2530
RemoteAddr: 10.42.0.60:54148
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: traefik-644b7c67d9-f2tn9
X-Real-Ip: 10.42.0.1
```
Making the same request to the HTTP entrypoint will return the following:
```bash
curl -k http://whoami.docker.localhost
Moved Permanently
```
The above confirms that a redirection has taken place which means our setup works correctly.
You can also open a browser and navigate to [https://whoami.docker.localhost](https://whoami.docker.localhost) to see a JSON dump from the service:
![Whoami](../assets/img/setup/whoami-json-dump.png)
!!! info
You can also navigate to the Traefik Dashboard at [https://dashboard.docker.localhost](https://dashboard.docker.localhost) to see that the route has been created.
### Other Key Configuration Areas
Beyond this initial setup, Traefik offers extensive configuration possibilities. Here are brief introductions and minimal examples using Docker Compose `command` arguments or `labels`. Consult the main documentation linked for comprehensive details.
### TLS Certificate Management (Let's Encrypt)
To make the `websecure` entry point serve valid HTTPS certificates automatically, enable Let's Encrypt (ACME).
*Example `command` additions:*
```yaml
command:
# ... other command arguments ...
- "--certificatesresolvers.le.acme.email=your-email@example.com"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json" # Path inside container volume
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
# - "--certificatesresolvers.le.acme.dnschallenge.provider=your-dns-provider" # Needs provider setup
# Optionally make 'le' the default resolver for TLS-enabled routers
- "--entrypoints.websecure.http.tls.certresolver=le"
```
This defines a resolver named `le`, sets the required email and storage path (within the mounted `/letsencrypt` volume), and enables the HTTP challenge. Refer to the [HTTPS/TLS Documentation](../reference/install-configuration/tls/certificate-resolvers/overview.md) and [Let's Encrypt Documentation](../reference/install-configuration/tls/certificate-resolvers/acme.md) for details on challenges and DNS provider configuration.
### Metrics (Prometheus)
You can expose Traefik's internal metrics for monitoring with Prometheus. We already enabled prometheus in our setup but we can further configure it.
*Example `command` additions:*
```yaml
command:
# If using a dedicated metrics entry point, define it:
- "--entrypoints.metrics.address=:8082"
# ... other command arguments ...
- "--metrics.prometheus=true"
# Optionally change the entry point metrics are exposed on (defaults to 'traefik')
- "--metrics.prometheus.entrypoint=metrics"
# Add labels to metrics for routers/services (can increase cardinality)
- "--metrics.prometheus.addrouterslabels=true"
- "--metrics.prometheus.addserviceslabels=true"
```
This enables the `/metrics` endpoint (typically accessed via the internal API port, often 8080 by default if not secured, or via a dedicated entry point). See the [Metrics Documentation](../reference/install-configuration/observability/metrics.md) for options.
### Tracing (OTel):
You can enable distributed tracing to follow requests through Traefik.
*Example `command` additions:*
```yaml
command:
# ... other command arguments ...
- "--tracing.otel=true"
- "--tracing.otel.grpcendpoint=otel-collector:4317" # Adjust endpoint as needed
- "--tracing.otel.httpendpoint=otel-collector.observability:4318" # Adjust endpoint as needed
```
!!! note
This option requires a running OTEL collector accessible by Traefik. Consult the [Tracing Documentation](../reference/install-configuration/observability/tracing.md).
### Access Logs
You can configure Traefik to log incoming requests for debugging and analysis.
*Example `command` additions:*
```yaml
command:
# ... other command arguments ...
- "--accesslog=true" # Enable access logs to stdout
# Optionally change format or output file (requires volume)
- "--accesslog.format=json"
- "--accesslog.filepath=/path/to/access.log"
# Optionally filter logs
- "--accesslog.filters.statuscodes=400-599"
```
This enables access logs to the container's standard output (viewable via `docker compose logs <traefik-container-id>`). See the [Access Logs Documentation](../reference/install-configuration/observability/logs-and-accesslogs.md).
### Conclusion
You now have a basic Traefik setup in Docker with secure dashboard access and HTTP-to-HTTPS redirection.
{!traefik-for-business-applications.md!}

View File

@@ -0,0 +1,398 @@
---
title: "Setup Traefik on Kubernetes"
description: "Learn how to Setup Traefik on Kubernetes with HTTP/HTTPS entrypoints, redirects, secure dashboard, basic TLS, metrics, tracing, accesslogs."
---
This guide provides an in-depth walkthrough for installing and configuring Traefik Proxy within a Kubernetes cluster using the official Helm chart. In this guide, we'll cover the following:
- Configure standard HTTP (`web`) and HTTPS (`websecure`) entry points,
- Implement automatic redirection from HTTP to HTTPS
- Secure the Traefik Dashboard using Basic Authentication.
- Deploy a demo application to test the setup
- Explore some other key configuration options
## Prerequisites
- A Kubernetes cluster
- Helm v3,
- Kubectl
## Create the Cluster
If you do not have a Kubernetes cluster already, you can spin up one with K3d:
```bash
k3d cluster create traefik \
--port 80:80@loadbalancer \
--port 443:443@loadbalancer \
--port 8000:8000@loadbalancer \
--k3s-arg "--disable=traefik@server:0"
```
Ports `80` and `443` reach Traefik from the host, while port `8000` remains free for later demos. The built-in Traefik shipped with k3s is disabled to avoid conflicts.
Check the context:
```bash
kubectl cluster-info --context k3d-traefik
```
You should see something like this:
```bash
Kubernetes control plane is running at https://0.0.0.0:56049
CoreDNS is running at https://0.0.0.0:56049/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://0.0.0.0:56049/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```
## Add the chart repo and namespace
Using Helm streamlines Kubernetes application deployment. Helm packages applications into "charts," which are collections of template files describing Kubernetes resources. We use the official Traefik Helm chart for a managed and customizable installation.
```bash
helm repo add traefik https://traefik.github.io/charts
helm repo update
kubectl create namespace traefik
```
The first command registers the `traefik` repository alias pointing to the official chart location. The second command refreshes your local cache to ensure you have the latest list of charts and versions available from all configured repositories.
## Create a Local SelfSigned TLS Secret
Traefik's Gateway listeners require a certificate whenever a listener uses `protocol: HTTPS`.
For local development create a throwaway selfsigned certificate and
store it in a Kubernetes Secret named **localselfsignedtls**.
The Gateway references this secret to terminate TLS on the `websecure` listener.
```bash
# 1) Generate a selfsigned certificate valid for *.docker.localhost
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=*.docker.localhost"
# 2) Create the TLS secret in the traefik namespace
kubectl create secret tls local-selfsigned-tls \
--cert=tls.crt --key=tls.key \
--namespace traefik
```
### Why Do We Need To Do This
The Gateway's HTTPS listener references this secret via `certificateRefs`.
Without it, the helm chart validation fails and the HTTP→HTTPS redirect chain breaks.
!!! info "Production tip"
The self-signed certificate above is **only for local development**. For production, either store a certificate issued by your organization's CA in a Secret or let an automated issuer such as cert-manager or Traefik's ACME (Let's Encrypt) generate certificates on demand. Update the `certificateRefs` in the `websecure` listener—or use `traefik.io/tls.certresolver`—so clients receive a trusted certificate and no longer see browser warnings.
## Prepare Helm Chart Configuration Values
Create a `values.yaml` file with the following content:
```yaml
# Configure Network Ports and EntryPoints
# EntryPoints are the network listeners for incoming traffic.
ports:
# Defines the HTTP entry point named 'web'
web:
port: 80
nodePort: 30000
# Instructs this entry point to redirect all traffic to the 'websecure' entry point
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
# Defines the HTTPS entry point named 'websecure'
websecure:
port: 443
nodePort: 30001
# Enables the dashboard in Secure Mode
api:
dashboard: true
insecure: false
ingressRoute:
dashboard:
enabled: true
matchRule: Host(`dashboard.docker.localhost`)
entryPoints:
- websecure
middlewares:
- name: dashboard-auth
# Creates a BasiAuth Middleware and Secret for the Dashboard Security
extraObjects:
- apiVersion: v1
kind: Secret
metadata:
name: dashboard-auth-secret
type: kubernetes.io/basic-auth
stringData:
username: admin
password: "P@ssw0rd" # Replace with an Actual Password
- apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: dashboard-auth
spec:
basicAuth:
secret: dashboard-auth-secret
# We will route with Gateway API instead.
ingressClass:
enabled: false
# Enable Gateway API Provider & Disables the KubernetesIngress provider
# Providers tell Traefik where to find routing configuration.
providers:
kubernetesIngress:
enabled: false
kubernetesGateway:
enabled: true
## Gateway Listeners
gateway:
listeners:
web: # HTTP listener that matches entryPoint `web`
port: 80
protocol: HTTP
namespacePolicy: All
websecure: # HTTPS listener that matches entryPoint `websecure`
port: 443
protocol: HTTPS # TLS terminates inside Traefik
namespacePolicy: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls # the Secret we created before the installation
group: ""
# Enable Observability
logs:
general:
level: INFO
# This enables access logs, outputting them to Traefik's standard output by default. The [Access Logs Documentation](https://doc.traefik.io/traefik/observability/access-logs/) covers formatting, filtering, and output options.
access:
enabled: true
# Enables Prometheus for Metrics
metrics:
prometheus:
enabled: true
```
## Install the Traefik Using the Helm Values
Now, apply the configuration using the Helm client.
```bash
# Install the chart into the 'traefik' namespace
helm install traefik traefik/traefik \
--namespace traefik \
--values values.yaml
```
**Command Breakdown:**
- `helm install traefik`: Instructs Helm to install a new release named `traefik`.
- `traefik/traefik`: Specifies the chart to use (`traefik` chart from the `traefik` repository added earlier).
- `--namespace traefik`: Specifies the Kubernetes namespace to install into. Using a dedicated namespace is recommended practice.
- `--values values.yaml`: Applies the custom configuration from your `values.yaml` file.
## Accessing the Dashboard
Now that Traefik is deployed, you can access its dashboard at [https://dashboard.docker.localhost/](https://dashboard.docker.localhost/). When you access this link, your browser will prompt for the username and password. Ensure you use the credentials set in the `values.yaml` file to log in. Upon successful login, the dashboard will be displayed as shown below:
![Traefik Dashboard](../assets/img/setup/traefik-dashboard.png)
## Deploy a Demo Application
To test the setup, deploy the [Traefik whoami](https://github.com/traefik/whoami) application in the Kubernetes cluster. Create a file named `whoami.yaml` and paste the following:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: traefik
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: traefik
spec:
selector:
app: whoami
ports:
- port: 80
```
Apply the manifest:
```bash
kubectl apply -f whoami.yaml
```
After deploying the application, you can expose the application by creating a [Gateway API HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/). To do this, create a file named `whoami-route.yaml` and paste the following:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: traefik
spec:
parentRefs:
- name: traefik-gateway # Name of the Gateway that Traefik creates when you enable the Gateway API provider
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Apply the manifest:
```bash
kubectl apply -f whoami-route.yaml
```
After you apply the manifest, navigate tothe Routes in the Traefik Dashboard; youll see that the[https://whoami.docker.localhost](https://whoami.docker.localhost)route has been created.
![Route](../assets/img/setup/route-in-dashboard.png)
You can test the application using curl:
```bash
curl -k https://whoami.docker.localhost/
```
```bash
Hostname: whoami-76c9859cfc-k7jzs
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.59
IP: fe80::50d7:a2ff:fed5:2530
RemoteAddr: 10.42.0.60:54148
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: traefik-644b7c67d9-f2tn9
X-Real-Ip: 10.42.0.1
```
You can also open a browser and navigate to [https://whoami.docker.localhost](https://whoami.docker.localhost) to see a JSON dump from the service.
![Whoami](../assets/img/setup/whoami-json-dump.png)
## Other Key Configuration Areas
The above setup provides a secure base, but Traefik offers much more. Here's a brief overview of other essential configurations, with minimal examples using Helm `values.yaml` overrides.
These examples illustrate how to enable features; consult the main documentation for detailed options.
### TLS Certificate Management (Let's Encrypt)
On the `websecure` entry point TLS is enabled by default. However, it currently lacks a valid certificate. Traefik can automatically obtain and renew TLS certificates from Let's Encrypt using the ACME protocol.
*Example `values.yaml` addition:*
```yaml
additionalArguments:
- "--certificatesresolvers.le.acme.email=your-email@example.com"
- "--certificatesresolvers.le.acme.storage=/data/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
# - "--certificatesresolvers.le.acme.dnschallenge.provider=your-dns-provider" # Requires provider-specific config, adjust if you control your DNS provider
# Enable persistence for ACME data (certificates, account) to ensure it survives pod restarts:
persistence:
enabled: true
name: data
size: 1Gi
storageClass: ""
```
This enables a certificate resolver named `le`, configures the mandatory email and storage file, and sets up the HTTP challenge (requires port 80 access). Refer to the [HTTPS/TLS Documentation](../reference/install-configuration/tls/certificate-resolvers/overview.md) and [Let's Encrypt Documentation](../reference/install-configuration/tls/certificate-resolvers/acme.md) for full details, including DNS challenge configuration.
!!!info "Let's Encrypt in Production"
Let's Encrypt can only issue certificates for hostnames that point to a public IP address reachable on ports 80 (HTTP01) or via your DNS provider's API (DNS01). Replace the `*.docker.localhost` examples with a real domain you control, create the DNS records, and keep ports 80/443 open to your cluster so the validation can succeed.
### Gateway API & ACME
Traefiks builtin ACME/LetsEncrypt integration works for IngressRoute and Ingress resources, but it does not issue certificates for GatewayAPI listeners.
If youre using the GatewayAPI, install [certmanager](https://cert-manager.io/docs/) (or another certificate controller) and reference the secret it creates in `gateway.listeners.websecure.certificateRefs`.
### Metrics (Prometheus)
Traefik can expose detailed metrics in Prometheus format, essential for monitoring its performance and the traffic it handles.
*Example `values.yaml` addition:*
```yaml
# Enable metrics endpoint
metrics:
prometheus:
# The entry point metrics will be available on (usually internal/admin)
entryPoint: metrics
# Add standard Prometheus metrics
addRoutersLabels: true
addServicesLabels: true
# ... other options available
```
This enables the Prometheus endpoint on a dedicated `metrics` entry point (port 9100). See the [Metrics Documentation](../reference/install-configuration/observability/metrics.md) for configuration details and available metrics.
### Tracing (OTel)
Distributed tracing helps understand request latency and flow through your system, including Traefik itself.
*Example `values.yaml` addition:*
```yaml
additionalArguments:
- "--tracing.otel=true"
- "--tracing.otel.grpcendpoint=otel-collector.observability:4317" # Adjust endpoint as needed
- "--tracing.otel.httpendpoint=otel-collector.observability:4318" # Adjust endpoint as needed
```
This enables OTel tracing and specifies the collector endpoint. Consult the [Tracing Documentation](../reference/install-configuration/observability/tracing.md) for details on OTel tracing.
## Conclusion
This setup establishes Traefik with secure dashboard access and HTTPS redirection, along with pointers to enable observability & TLS.
{!traefik-for-business-applications.md!}

330
docs/content/setup/swarm.md Normal file
View File

@@ -0,0 +1,330 @@
---
title: Setup Traefik Proxy in Docker Swarm
description: "Learn how to run Traefik v3 in Docker Swarm with HTTP/HTTPS entrypoints, redirects, a secured dashboard, selfsigned TLS, metrics, tracing, and accesslogs."
---
This guide provides an indepth walkthrough for installing and configuring Traefik Proxy as a **Swarm service** using `docker stack deploy`. It follows the same structure as the standaloneDocker tutorial and covers:
- Enable the [Swarm provider](../reference/install-configuration/providers/swarm.md)
- Expose **web** (HTTP :80) and **websecure** (HTTPS :443) entrypoints
- Redirect all HTTP traffic to HTTPS
- Secure the Traefik dashboard with **basicauth**
- Terminate TLS with a selfsigned certificate for `*.swarm.localhost`
- Deploy the **whoami** demo service
- Enable accesslogs and Prometheus metrics
## Prerequisites
- Docker Engine with **Swarm mode** initialised (`docker swarm init`)
- Docker Compose
- `openssl`
- `htpasswd`
## Create a selfsigned certificate
Before Traefik can serve HTTPS locally it needs a certificate. In production youd use one from a trusted CA, but for a multinode dev swarm a quick selfsigned cert is enough:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
```
## Create the Traefik Dashboard Credentials
Generate a hashed username/password pair that Traefiks middleware will validate:
```bash
htpasswd -nb admin "P@ssw0rd" | sed -e 's/\$/\$\$/g'
```
Copy the full output (e.g., `admin:$$apr1$$…`) — well paste it into the middleware label.
## Create a dockercomposeswarm.yaml
!!! note
Swarm uses `docker stack deploy`. The compose file can be named anything; well use `dockercomposeswarm.yaml`.
First, create a folder named **dynamic** and add **tls.yaml** for dynamic TLS configuration:
```yaml
# dynamic/tls.yaml
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
```
In the same directory, create `dockercomposeswarm.yaml`:
```yaml
services:
traefik:
image: traefik:v3.4
networks:
# Connect to the 'traefik_proxy' overlay network for inter-container communication across nodes
- traefik_proxy
ports:
# Expose Traefik's entry points to the Swarm
# Swarm requires the long syntax for ports.
- target: 80 # Container port (Traefik web entry point)
published: 80 # Host port exposed on the nodes
protocol: tcp
# 'host' mode binds directly to the node's IP where the task runs.
# 'ingress' mode uses Swarm's Routing Mesh (load balances across nodes).
# Choose based on your load balancing strategy. 'host' is often simpler if using an external LB.
mode: host
- target: 443 # Container port ( Traefik websecure entry point)
published: 443 # Host port
protocol: tcp
mode: host
volumes:
# Mount the Docker socket for the Swarm provider
# This MUST be run from a manager node to access the Swarm API via the socket.
- /var/run/docker.sock:/var/run/docker.sock:ro # Swarm API socket
- ./certs:/certs:ro
- ./dynamic:/dynamic:ro
# Traefik Static configuration via command-line arguments
command:
# HTTP EntryPoint
- "--entrypoints.web.address=:80"
# Configure HTTP to HTTPS Redirection
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
# HTTPS EntryPoint
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
# Attach dynamic TLS file
- "--providers.file.filename=/dynamic/tls.yaml"
# Providers
# Enable the Docker Swarm provider (instead of Docker provider)
- "--providers.swarm.endpoint=unix:///var/run/docker.sock"
# Watch for Swarm service changes (requires socket access)
- "--providers.swarm.watch=true"
# Recommended: Don't expose services by default; require explicit labels
- "--providers.swarm.exposedbydefault=false"
# Specify the default network for Traefik to connect to services
- "--providers.swarm.network=traefik_traefik_proxy"
# API & Dashboard
- "--api.dashboard=true" # Enable the dashboard
- "--api.insecure=false" # Explicitly disable insecure API mod
# Observability
- "--log.level=INFO" # Set the Log Level e.g INFO, DEBUG
- "--accesslog=true" # Enable Access Logs
- "--metrics.prometheus=true" # Enable Prometheus
deploy:
mode: replicated
replicas: 1
placement:
# Placement constraints restrict where Traefik tasks can run.
# Running on manager nodes is common for accessing the Swarm API via the socket.
constraints:
- node.role == manager
# Traefik Dynamic configuration via labels
# In Swarm, labels on the service definition configure Traefik routing for that service.
labels:
- "traefik.enable=true"
# Dashboard router
- "traefik.http.routers.dashboard.rule=Host(`dashboard.swarm.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls=true"
# Basicauth middleware
- "traefik.http.middlewares.dashboard-auth.basicauth.users=<PASTE_HASH_HERE>"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@swarm"
# Service hint
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
# Deploy the Whoami application
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
labels:
# Enable Service discovery for Traefik
- "traefik.enable=true"
# Define the WHoami router rule
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
# Expose Whoami on the HTTPS entrypoint
- "traefik.http.routers.whoami.entrypoints=websecure"
# Enable TLS
- "traefik.http.routers.whoami.tls=true"
# Expose the whoami port number to Traefik
- traefik.http.services.whoami.loadbalancer.server.port=80
# Define the overlay network for Swarm
networks:
traefik_proxy:
driver: overlay
attachable: true
```
!!! info
- Replace `<PASTE_HASH_HERE>` with the escaped hash from the previous step.
- The password hash is stored directly in a service label. This is fine for local development, but anyone with access to the Docker API can view it using `docker service inspect`. For production, use a more secure method to store secrets.
## Launch the stack
Create the overlay network once (if it doesnt exist) and deploy:
```bash
docker network create --driver overlay --attachable traefik_proxy || true
docker stack deploy -c docker-compose-swarm.yaml traefik
```
Swarm schedules the services on a manager node and binds ports 80/443.
## Access the Dashboard
Open **https://dashboard.swarm.localhost/** in your browser — the dashboard should prompt for the basicauth credentials you configured.
![Traefik Dashboard](../assets/img/setup/traefik-dashboard-swarm.png)
## Test the whoami Application
You can test the application using curl:
```bash
curl -k https://whoami.swarm.localhost/
```
```bash
Hostname: whoami-76c9859cfc-k7jzs
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.59
IP: fe80::50d7:a2ff:fed5:2530
RemoteAddr: 10.42.0.60:54148
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/8.7.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: traefik-644b7c67d9-f2tn9
X-Real-Ip: 10.42.0.1
```
Making the same request to the HTTP entrypoint will return the following:
```bash
curl -k http://whoami.swarm.localhost
Moved Permanently
```
Requesting the HTTP endpoint redirects to HTTPS, confirming the setup works.
You can also open a browser and navigate to [https://whoami.swarm.localhost](https://whoami.swarm.localhost) to see a JSON dump from the service:
![Whoami](../assets/img/setup/whoami-json-dump.png)
### Other Key Configuration Areas
Beyond this initial setup, Traefik offers extensive configuration possibilities. Here are brief introductions and minimal examples using Docker Compose `command` arguments or `labels`. Consult the main documentation linked for comprehensive details.
#### TLS Certificate Management (Lets Encrypt)
To make the `websecure` entry point serve valid HTTPS certificates automatically, enable Let's Encrypt (ACME).
```yaml
command:
# ...
- "--certificatesresolvers.le.acme.email=you@example.com"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
- "--entrypoints.websecure.http.tls.certresolver=le"
```
This defines a resolver named `le`, sets the required email and storage path (within the mounted `/letsencrypt` volume), and enables the HTTP challenge. Refer to the [HTTPS/TLS Documentation](../reference/install-configuration/tls/certificate-resolvers/overview.md) and [Let's Encrypt Documentation](../reference/install-configuration/tls/certificate-resolvers/acme.md) for details on challenges and DNS provider configuration.
!!! note
- Ensure the `/letsencrypt` path is on a **shared volume** or NFS so all nodes can read certificates.
- Ensure to mount the `/letsencrypt` volume in the `traefik` service in the `docker-compose-swarm.yaml` file.
#### Metrics (Prometheus)
You can expose Traefik's internal metrics for monitoring with Prometheus. We already enabled prometheus in our setup but we can further configure it.
*Example `command` additions:*
```yaml
command:
# If using a dedicated metrics entry point, define it:
- "--entrypoints.metrics.address=:8082"
- "--metrics.prometheus=true"
# Optionally change the entry point metrics are exposed on (defaults to 'traefik')
- "--metrics.prometheus.entrypoint=metrics"
# Add labels to metrics for routers/services (can increase cardinality)
- "--metrics.prometheus.addrouterslabels=true"
```
This enables the `/metrics` endpoint (typically accessed via the internal API port, often 8080 by default if not secured, or via a dedicated entry point). See the [Metrics Documentation](../reference/install-configuration/observability/metrics.md) for options.
#### Tracing (OTel)
You can enable distributed tracing to follow requests through Traefik.
*Example `command` additions:*
```yaml
command:
# ...
- "--tracing.otel=true"
- "--tracing.otel.grpcendpoint=otel-collector:4317"
```
!!! note
This option requires a running OTEL collector accessible by Traefik. Consult the [Tracing Documentation](../reference/install-configuration/observability/tracing.md).
#### Access Logs
You can configure Traefik to log incoming requests for debugging and analysis.
*Example `command` additions:*
```yaml
command:
# ... other command arguments ...
- "--accesslog=true" # Enable access logs to stdout
# Optionally change format or output file (requires volume)
- "--accesslog.format=json"
- "--accesslog.filepath=/path/to/access.log"
# Optionally filter logs
- "--accesslog.filters.statuscodes=400-599"
```
### Conclusion
You now have Traefik running on Docker Swarm with HTTPS, a secured dashboard, automatic HTTPHTTPS redirects, and foundational observability. Expand this stack with LetsEncrypt, additional middlewares, or multiple Traefik replicas as your Swarm grows.
{!traefik-for-business-applications.md!}

View File

@@ -1,5 +1,3 @@
version: "3.3"
services:
traefik:

View File

@@ -1,5 +1,3 @@
version: "3.3"
secrets:
ovh_endpoint:
file: "./secrets/ovh_endpoint.secret"

View File

@@ -1,5 +1,3 @@
version: "3.3"
services:
traefik:

View File

@@ -1,5 +1,3 @@
version: "3.3"
services:
traefik:

View File

@@ -1,5 +1,3 @@
version: "3.3"
services:
traefik:

View File

@@ -23,8 +23,6 @@ Create a `docker-compose.yml` file with the following content:
You can use a [pre-existing network](https://docs.docker.com/compose/networking/#use-a-pre-existing-network "Link to Docker Compose networking docs") too.
```yaml
version: "3.3"
networks:
traefiknet: {}

View File

@@ -0,0 +1,355 @@
---
title: "Traefik WebSocket Documentation"
description: "How to configure WebSocket and WebSocket Secure (WSS) connections with Traefik Proxy."
---
# WebSocket
Configuring Traefik to handle WebSocket and WebSocket Secure (WSS) connections.
{: .subtitle }
## Overview
WebSocket is a communication protocol that provides full-duplex communication channels over a single TCP connection.
WebSocket Secure (WSS) is the encrypted version of WebSocket, using TLS/SSL encryption.
Traefik supports WebSocket and WebSocket Secure (WSS) out of the box. This guide will walk through examples of how to configure Traefik for different WebSocket scenarios.
## Basic WebSocket Configuration
A basic WebSocket configuration only requires defining a router and a service that points to your WebSocket server.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.routers.my-websocket.rule=Host(`ws.example.com`)"
- "traefik.http.routers.my-websocket.service=my-websocket-service"
- "traefik.http.services.my-websocket-service.loadbalancer.server.port=8000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-websocket-route
spec:
entryPoints:
- web
routes:
- match: Host(`ws.example.com`)
kind: Rule
services:
- name: my-websocket-service
port: 8000
```
```yaml tab="File (YAML)"
http:
routers:
my-websocket:
rule: "Host(`ws.example.com`)"
service: my-websocket-service
services:
my-websocket-service:
loadBalancer:
servers:
- url: "http://my-websocket-server:8000"
```
```toml tab="File (TOML)"
[http.routers]
[http.routers.my-websocket]
rule = "Host(`ws.example.com`)"
service = "my-websocket-service"
[http.services]
[http.services.my-websocket-service]
[http.services.my-websocket-service.loadBalancer]
[[http.services.my-websocket-service.loadBalancer.servers]]
url = "http://my-websocket-server:8000"
```
## WebSocket Secure (WSS) Configuration
WebSocket Secure (WSS) requires TLS configuration.
The client connects using the `wss://` protocol instead of `ws://`.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.routers.my-websocket-secure.rule=Host(`wss.example.com`)"
- "traefik.http.routers.my-websocket-secure.service=my-websocket-service"
- "traefik.http.routers.my-websocket-secure.tls=true"
- "traefik.http.services.my-websocket-service.loadbalancer.server.port=8000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-websocket-secure-route
spec:
entryPoints:
- websecure
routes:
- match: Host(`wss.example.com`)
kind: Rule
services:
- name: my-websocket-service
port: 8000
tls: {}
```
```yaml tab="File (YAML)"
http:
routers:
my-websocket-secure:
rule: "Host(`wss.example.com`)"
service: my-websocket-service
tls: {}
services:
my-websocket-service:
loadBalancer:
servers:
- url: "http://my-websocket-server:8000"
```
```toml tab="File (TOML)"
[http.routers]
[http.routers.my-websocket-secure]
rule = "Host(`wss.example.com`)"
service = "my-websocket-service"
[http.routers.my-websocket-secure.tls]
[http.services]
[http.services.my-websocket-service]
[http.services.my-websocket-service.loadBalancer]
[[http.services.my-websocket-service.loadBalancer.servers]]
url = "http://my-websocket-server:8000"
```
## SSL Termination for WebSockets
In this scenario, clients connect to Traefik using WSS (encrypted), but Traefik connects to your backend server using WS (unencrypted).
This is called SSL termination.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.routers.my-wss-termination.rule=Host(`wss.example.com`)"
- "traefik.http.routers.my-wss-termination.service=my-ws-service"
- "traefik.http.routers.my-wss-termination.tls=true"
- "traefik.http.services.my-ws-service.loadbalancer.server.port=8000"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-wss-termination-route
spec:
entryPoints:
- websecure
routes:
- match: Host(`wss.example.com`)
kind: Rule
services:
- name: my-ws-service
port: 8000
tls: {}
```
```yaml tab="File (YAML)"
http:
routers:
my-wss-termination:
rule: "Host(`wss.example.com`)"
service: my-ws-service
tls: {}
services:
my-ws-service:
loadBalancer:
servers:
- url: "http://my-ws-server:8000"
```
```toml tab="File (TOML)"
[http.routers]
[http.routers.my-wss-termination]
rule = "Host(`wss.example.com`)"
service = "my-ws-service"
[http.routers.my-wss-termination.tls]
[http.services]
[http.services.my-ws-service]
[http.services.my-ws-service.loadBalancer]
[[http.services.my-ws-service.loadBalancer.servers]]
url = "http://my-ws-server:8000"
```
## End-to-End WebSocket Secure (WSS)
For end-to-end encryption, Traefik can be configured to connect to your backend using HTTPS.
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.routers.my-wss-e2e.rule=Host(`wss.example.com`)"
- "traefik.http.routers.my-wss-e2e.service=my-wss-service"
- "traefik.http.routers.my-wss-e2e.tls=true"
- "traefik.http.services.my-wss-service.loadbalancer.server.port=8443"
# If the backend uses a self-signed certificate
- "traefik.http.serversTransports.insecureTransport.insecureSkipVerify=true"
- "traefik.http.services.my-wss-service.loadBalancer.serversTransport=insecureTransport"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: insecure-transport
spec:
insecureSkipVerify: true
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-wss-e2e-route
spec:
entryPoints:
- websecure
routes:
- match: Host(`wss.example.com`)
kind: Rule
services:
- name: my-wss-service
port: 8443
serversTransport: insecure-transport
tls: {}
```
```yaml tab="File (YAML)"
http:
serversTransports:
insecureTransport:
insecureSkipVerify: true
routers:
my-wss-e2e:
rule: "Host(`wss.example.com`)"
service: my-wss-service
tls: {}
services:
my-wss-service:
loadBalancer:
serversTransport: insecureTransport
servers:
- url: "https://my-wss-server:8443"
```
```toml tab="File (TOML)"
[http.serversTransports]
[http.serversTransports.insecureTransport]
insecureSkipVerify = true
[http.routers]
[http.routers.my-wss-e2e]
rule = "Host(`wss.example.com`)"
service = "my-wss-service"
[http.routers.my-wss-e2e.tls]
[http.services]
[http.services.my-wss-service]
[http.services.my-wss-service.loadBalancer]
serversTransport = "insecureTransport"
[[http.services.my-wss-service.loadBalancer.servers]]
url = "https://my-wss-server:8443"
```
## EntryPoints Configuration for WebSockets
In your Traefik static configuration, you'll need to define entryPoints for both WS and WSS:
```yaml tab="File (YAML)"
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
```
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
```
## Testing WebSocket Connections
You can test your WebSocket configuration using various tools:
1. Browser Developer Tools: Most modern browsers include WebSocket debugging in their developer tools.
2. WebSocket client tools like [wscat](https://github.com/websockets/wscat) or online tools like [Piesocket's WebSocket Tester](https://www.piesocket.com/websocket-tester).
Example wscat commands:
```bash
# Test standard WebSocket
wscat -c ws://ws.example.com
# Test WebSocket Secure
wscat -c wss://wss.example.com
```
## Common Issues and Solutions
### Headers and Origin Checks
Some WebSocket servers implement origin checking. Traefik passes the original headers to your backend, including the `Origin` header.
If you need to manipulate headers for WebSocket connections, you can use Traefik's Headers middleware:
```yaml tab="Docker & Swarm"
labels:
- "traefik.http.middlewares.my-headers.headers.customrequestheaders.Origin=https://allowed-origin.com"
- "traefik.http.routers.my-websocket.middlewares=my-headers"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: my-headers
spec:
headers:
customRequestHeaders:
Origin: "https://allowed-origin.com"
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-websocket-route
spec:
routes:
- match: Host(`ws.example.com`)
kind: Rule
middlewares:
- name: my-headers
services:
- name: my-websocket-service
port: 8000
```
### Certificate Issues with WSS
If you're experiencing certificate issues with WSS:
1. Ensure your certificates are valid and not expired
2. For testing with self-signed certificates, configure your clients to accept them
3. When using Let's Encrypt, ensure your domain is properly configured
For backends with self-signed certificates, use the `insecureSkipVerify` option in the ServersTransport configuration as shown in the examples above.

View File

@@ -1,4 +1,4 @@
FROM alpine:3.21
FROM alpine:3.22
ENV PATH="${PATH}:/venv/bin"

View File

@@ -50,6 +50,7 @@ markdown_extensions:
- pymdownx.inlinehilite
- pymdownx.highlight:
use_pygments: false # hljs is used instead of pygment for TOML highlighting support
- pymdownx.smartsymbols
- pymdownx.superfences
- pymdownx.tabbed
@@ -66,13 +67,33 @@ markdown_extensions:
nav:
- 'What is Traefik': 'index.md'
- 'Getting Started':
- 'Concepts' : 'getting-started/concepts.md'
- 'Overview': 'getting-started/index.md'
- 'Quick Start':
- 'Docker': 'getting-started/quick-start.md'
- 'Kubernetes': 'getting-started/quick-start-with-kubernetes.md'
- 'Kubernetes': 'getting-started/kubernetes.md'
- 'Docker': 'getting-started/docker.md'
- 'Configuration Introduction': 'getting-started/configuration-overview.md'
- 'Install Traefik': 'getting-started/install-traefik.md'
- 'Frequently Asked Questions': 'getting-started/faq.md'
- 'Setup':
- 'Kubernetes': 'setup/kubernetes.md'
- 'Docker': 'setup/docker.md'
- 'Swarm': 'setup/swarm.md'
- 'Expose':
- 'Overview': 'expose/overview.md'
- 'Kubernetes': 'expose/kubernetes.md'
- 'Docker': 'expose/docker.md'
- 'Swarm': 'expose/swarm.md'
- 'Observe':
- 'Overview': 'observe/overview.md'
- 'Logs & Access Logs': 'observe/logs-and-access-logs.md'
- 'Metrics': 'observe/metrics.md'
- 'Tracing': 'observe/tracing.md'
- 'Migrate':
- 'Traefik v3': 'migrate/v3.md'
- 'Traefik v2 to v3':
- 'Migration guide': 'migrate/v2-to-v3.md'
- 'Configuration changes for v3': 'migrate/v2-to-v3-details.md'
- 'Traefik v2': 'migrate/v2.md'
- 'Traefik v1 to v2': 'migrate/v1-to-v2.md'
- 'Configuration Discovery':
- 'Overview': 'providers/overview.md'
- 'Docker': 'providers/docker.md'
@@ -171,19 +192,13 @@ nav:
- 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md'
- 'Kubernetes and cert-manager': 'user-guides/cert-manager.md'
- 'gRPC Examples': 'user-guides/grpc.md'
- 'WebSocket Examples': 'user-guides/websocket.md'
- 'Docker':
- 'Basic Example': 'user-guides/docker-compose/basic-example/index.md'
- 'HTTPS with Let''s Encrypt':
- 'TLS Challenge': 'user-guides/docker-compose/acme-tls/index.md'
- 'HTTP Challenge': 'user-guides/docker-compose/acme-http/index.md'
- 'DNS Challenge': 'user-guides/docker-compose/acme-dns/index.md'
- 'Migration':
- 'Traefik v3 minor migrations': 'migration/v3.md'
- 'Traefik v2 to v3':
- 'Migration guide': 'migration/v2-to-v3.md'
- 'Configuration changes for v3': 'migration/v2-to-v3-details.md'
- 'Traefik v2 minor migrations': 'migration/v2.md'
- 'Traefik v1 to v2': 'migration/v1-to-v2.md'
- 'Contributing':
- 'Thank You!': 'contributing/thank-you.md'
- 'Submitting Issues': 'contributing/submitting-issues.md'

9
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/traefik/traefik/v3
go 1.23.0
go 1.24.0
require (
github.com/BurntSushi/toml v1.5.0
@@ -55,7 +55,7 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // No tag on the repo.
github.com/prometheus/client_golang v1.19.1
github.com/prometheus/client_model v0.6.1
github.com/quic-go/quic-go v0.48.2
github.com/quic-go/quic-go v0.54.0
github.com/redis/go-redis/v9 v9.7.3
github.com/rs/zerolog v1.33.0
github.com/sirupsen/logrus v1.9.3
@@ -205,8 +205,7 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.16.0 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
github.com/go-zookeeper/zk v1.0.3 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gofrs/flock v0.12.1 // indirect
@@ -361,7 +360,7 @@ require (
go.opentelemetry.io/contrib/propagators/ot v1.28.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/mock v0.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/ratelimit v0.3.0 // indirect
go.uber.org/zap v1.26.0 // indirect

13
go.sum
View File

@@ -423,10 +423,11 @@ github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptd
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
@@ -1035,8 +1036,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
@@ -1349,8 +1350,8 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=

View File

@@ -2,7 +2,6 @@ package integration
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
@@ -43,7 +42,7 @@ func (s *ConsulSuite) SetupSuite() {
s.consulURL = fmt.Sprintf("http://%s", consulAddr)
kv, err := valkeyrie.NewStore(
context.Background(),
s.T().Context(),
consul.StoreName,
[]string{consulAddr},
&consul.Config{
@@ -63,7 +62,7 @@ func (s *ConsulSuite) TearDownSuite() {
}
func (s *ConsulSuite) TearDownTest() {
err := s.kvClient.DeleteTree(context.Background(), "traefik")
err := s.kvClient.DeleteTree(s.T().Context(), "traefik")
if err != nil && !errors.Is(err, store.ErrKeyNotFound) {
require.ErrorIs(s.T(), err, store.ErrKeyNotFound)
}
@@ -118,7 +117,7 @@ func (s *ConsulSuite) TestSimpleConfiguration() {
}
for k, v := range data {
err := s.kvClient.Put(context.Background(), k, []byte(v), nil)
err := s.kvClient.Put(s.T().Context(), k, []byte(v), nil)
require.NoError(s.T(), err)
}
@@ -178,7 +177,7 @@ func (s *ConsulSuite) TestDeleteRootKey() {
file := s.adaptFile("fixtures/consul/simple.toml", struct{ ConsulAddress string }{s.consulURL})
ctx := context.Background()
ctx := s.T().Context()
svcaddr := net.JoinHostPort(s.getComposeServiceIP("whoami"), "80")
data := map[string]string{

View File

@@ -2,7 +2,6 @@ package integration
import (
"bytes"
"context"
"encoding/json"
"net"
"net/http"
@@ -41,7 +40,7 @@ func (s *EtcdSuite) SetupSuite() {
var err error
s.etcdAddr = net.JoinHostPort(s.getComposeServiceIP("etcd"), "2379")
s.kvClient, err = valkeyrie.NewStore(
context.Background(),
s.T().Context(),
etcdv3.StoreName,
[]string{s.etcdAddr},
&etcdv3.Config{
@@ -108,7 +107,7 @@ func (s *EtcdSuite) TestSimpleConfiguration() {
}
for k, v := range data {
err := s.kvClient.Put(context.Background(), k, []byte(v), nil)
err := s.kvClient.Put(s.T().Context(), k, []byte(v), nil)
require.NoError(s.T(), err)
}

View File

@@ -1931,7 +1931,7 @@ spec:
properties:
permanent:
description: Permanent defines whether the redirection is permanent
(301).
(308).
type: boolean
regex:
description: Regex defines the regex used to match and capture
@@ -1950,7 +1950,7 @@ spec:
properties:
permanent:
description: Permanent defines whether the redirection is permanent
(301).
(308).
type: boolean
port:
description: Port defines the port of the new URL.
@@ -2533,7 +2533,7 @@ spec:
type: object
curvePreferences:
description: |-
CurvePreferences defines the preferred elliptic curves in a specific order.
CurvePreferences defines the preferred elliptic curves.
More info: https://doc.traefik.io/traefik/v3.4/https/tls/#curve-preferences
items:
type: string

View File

@@ -108,7 +108,9 @@ func getHelloClientGRPCh2c() (helloworld.GreeterClient, func() error, error) {
return helloworld.NewGreeterClient(conn), conn.Close, nil
}
func callHelloClientGRPC(name string, secure bool) (string, error) {
func callHelloClientGRPC(t *testing.T, name string, secure bool) (string, error) {
t.Helper()
var client helloworld.GreeterClient
var closer func() error
var err error
@@ -123,24 +125,26 @@ func callHelloClientGRPC(name string, secure bool) (string, error) {
if err != nil {
return "", err
}
r, err := client.SayHello(context.Background(), &helloworld.HelloRequest{Name: name})
r, err := client.SayHello(t.Context(), &helloworld.HelloRequest{Name: name})
if err != nil {
return "", err
}
return r.GetMessage(), nil
}
func callStreamExampleClientGRPC() (helloworld.Greeter_StreamExampleClient, func() error, error) {
func callStreamExampleClientGRPC(t *testing.T) (helloworld.Greeter_StreamExampleClient, func() error, error) {
t.Helper()
client, closer, err := getHelloClientGRPC()
if err != nil {
return nil, closer, err
}
t, err := client.StreamExample(context.Background(), &helloworld.StreamExampleRequest{})
s, err := client.StreamExample(t.Context(), &helloworld.StreamExampleRequest{})
if err != nil {
return nil, closer, err
}
return t, closer, nil
return s, closer, nil
}
func (s *GRPCSuite) TestGRPC() {
@@ -172,7 +176,7 @@ func (s *GRPCSuite) TestGRPC() {
var response string
err = try.Do(1*time.Second, func() error {
response, err = callHelloClientGRPC("World", true)
response, err = callHelloClientGRPC(s.T(), "World", true)
return err
})
assert.NoError(s.T(), err)
@@ -204,7 +208,7 @@ func (s *GRPCSuite) TestGRPCh2c() {
var response string
err = try.Do(1*time.Second, func() error {
response, err = callHelloClientGRPC("World", false)
response, err = callHelloClientGRPC(s.T(), "World", false)
return err
})
assert.NoError(s.T(), err)
@@ -240,7 +244,7 @@ func (s *GRPCSuite) TestGRPCh2cTermination() {
var response string
err = try.Do(1*time.Second, func() error {
response, err = callHelloClientGRPC("World", true)
response, err = callHelloClientGRPC(s.T(), "World", true)
return err
})
assert.NoError(s.T(), err)
@@ -276,7 +280,7 @@ func (s *GRPCSuite) TestGRPCInsecure() {
var response string
err = try.Do(1*time.Second, func() error {
response, err = callHelloClientGRPC("World", true)
response, err = callHelloClientGRPC(s.T(), "World", true)
return err
})
assert.NoError(s.T(), err)
@@ -314,7 +318,7 @@ func (s *GRPCSuite) TestGRPCBuffer() {
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
assert.NoError(s.T(), err)
var client helloworld.Greeter_StreamExampleClient
client, closer, err := callStreamExampleClientGRPC()
client, closer, err := callStreamExampleClientGRPC(s.T())
defer func() { _ = closer() }()
assert.NoError(s.T(), err)
@@ -367,7 +371,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval() {
assert.NoError(s.T(), err)
var client helloworld.Greeter_StreamExampleClient
client, closer, err := callStreamExampleClientGRPC()
client, closer, err := callStreamExampleClientGRPC(s.T())
defer func() {
_ = closer()
stopStreamExample <- true
@@ -422,7 +426,7 @@ func (s *GRPCSuite) TestGRPCWithRetry() {
var response string
err = try.Do(1*time.Second, func() error {
response, err = callHelloClientGRPC("World", true)
response, err = callHelloClientGRPC(s.T(), "World", true)
return err
})
assert.NoError(s.T(), err)

View File

@@ -106,7 +106,7 @@ func (s *BaseSuite) displayTraefikLogFile(path string) {
}
func (s *BaseSuite) SetupSuite() {
if isDockerDesktop(context.Background(), s.T()) {
if isDockerDesktop(s.T()) {
_, err := os.Stat(tailscaleSecretFilePath)
require.NoError(s.T(), err, "Tailscale need to be configured when running integration tests with Docker Desktop: (https://doc.traefik.io/traefik/v2.11/contributing/building-testing/#testing)")
}
@@ -116,7 +116,6 @@ func (s *BaseSuite) SetupSuite() {
// TODO
// stdlog.SetOutput(log.Logger)
ctx := context.Background()
// Create docker network
// docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24
var opts []network.NetworkCustomizer
@@ -129,18 +128,18 @@ func (s *BaseSuite) SetupSuite() {
},
},
}))
dockerNetwork, err := network.New(ctx, opts...)
dockerNetwork, err := network.New(s.T().Context(), opts...)
require.NoError(s.T(), err)
s.network = dockerNetwork
s.hostIP = "172.31.42.1"
if isDockerDesktop(ctx, s.T()) {
s.hostIP = getDockerDesktopHostIP(ctx, s.T())
if isDockerDesktop(s.T()) {
s.hostIP = getDockerDesktopHostIP(s.T())
s.setupVPN(tailscaleSecretFilePath)
}
}
func getDockerDesktopHostIP(ctx context.Context, t *testing.T) string {
func getDockerDesktopHostIP(t *testing.T) string {
t.Helper()
req := testcontainers.ContainerRequest{
@@ -151,13 +150,13 @@ func getDockerDesktopHostIP(ctx context.Context, t *testing.T) string {
Cmd: []string{"getent", "hosts", "host.docker.internal"},
}
con, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
con, err := testcontainers.GenericContainer(t.Context(), testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
require.NoError(t, err)
closer, err := con.Logs(ctx)
closer, err := con.Logs(t.Context())
require.NoError(t, err)
all, err := io.ReadAll(closer)
@@ -170,15 +169,15 @@ func getDockerDesktopHostIP(ctx context.Context, t *testing.T) string {
return matches[0]
}
func isDockerDesktop(ctx context.Context, t *testing.T) bool {
func isDockerDesktop(t *testing.T) bool {
t.Helper()
cli, err := testcontainers.NewDockerClientWithOpts(ctx)
cli, err := testcontainers.NewDockerClientWithOpts(t.Context())
if err != nil {
t.Fatalf("failed to create docker client: %s", err)
}
info, err := cli.Info(ctx)
info, err := cli.Info(t.Context())
if err != nil {
t.Fatalf("failed to get docker info: %s", err)
}
@@ -191,7 +190,7 @@ func (s *BaseSuite) TearDownSuite() {
err := try.Do(5*time.Second, func() error {
if s.network != nil {
err := s.network.Remove(context.Background())
err := s.network.Remove(s.T().Context())
if err != nil {
return err
}
@@ -218,7 +217,7 @@ func (s *BaseSuite) createComposeProject(name string) {
s.containers = map[string]testcontainers.Container{}
}
ctx := context.Background()
ctx := s.T().Context()
for id, containerConfig := range composeConfigData.Services {
var mounts []mount.Mount
@@ -273,7 +272,7 @@ func (s *BaseSuite) createContainer(ctx context.Context, containerConfig compose
if containerConfig.CapAdd != nil {
config.CapAdd = containerConfig.CapAdd
}
if !isDockerDesktop(ctx, s.T()) {
if !isDockerDesktop(s.T()) {
config.ExtraHosts = append(config.ExtraHosts, "host.docker.internal:"+s.hostIP)
}
config.Mounts = mounts
@@ -292,7 +291,7 @@ func (s *BaseSuite) createContainer(ctx context.Context, containerConfig compose
func (s *BaseSuite) composeUp(services ...string) {
for name, con := range s.containers {
if len(services) == 0 || slices.Contains(services, name) {
err := con.Start(context.Background())
err := con.Start(s.T().Context())
require.NoError(s.T(), err)
}
}
@@ -303,7 +302,7 @@ func (s *BaseSuite) composeStop(services ...string) {
for name, con := range s.containers {
if len(services) == 0 || slices.Contains(services, name) {
timeout := 10 * time.Second
err := con.Stop(context.Background(), &timeout)
err := con.Stop(s.T().Context(), &timeout)
require.NoError(s.T(), err)
}
}
@@ -312,7 +311,7 @@ func (s *BaseSuite) composeStop(services ...string) {
// composeDown stops all compose project services and removes the corresponding containers.
func (s *BaseSuite) composeDown() {
for _, c := range s.containers {
err := c.Terminate(context.Background())
err := c.Terminate(s.T().Context())
require.NoError(s.T(), err)
}
s.containers = map[string]testcontainers.Container{}
@@ -383,7 +382,7 @@ func (s *BaseSuite) displayLogK3S() {
func (s *BaseSuite) displayLogCompose() {
for name, ctn := range s.containers {
readCloser, err := ctn.Logs(context.Background())
readCloser, err := ctn.Logs(s.T().Context())
require.NoError(s.T(), err)
for {
b := make([]byte, 1024)
@@ -451,7 +450,7 @@ func (s *BaseSuite) getComposeServiceIP(name string) string {
if !ok {
return ""
}
ip, err := container.ContainerIP(context.Background())
ip, err := container.ContainerIP(s.T().Context())
if err != nil {
return ""
}
@@ -501,7 +500,7 @@ func (s *BaseSuite) setupVPN(keyFile string) {
func (s *BaseSuite) composeExec(service string, args ...string) string {
require.Contains(s.T(), s.containers, service)
_, reader, err := s.containers[service].Exec(context.Background(), args)
_, reader, err := s.containers[service].Exec(s.T().Context(), args)
require.NoError(s.T(), err)
content, err := io.ReadAll(reader)

View File

@@ -1,7 +1,6 @@
package integration
import (
"context"
"fmt"
"io"
"io/fs"
@@ -74,7 +73,7 @@ func (s *K8sConformanceSuite) SetupSuite() {
s.T().Fatal(err)
}
ctx := context.Background()
ctx := s.T().Context()
// Ensure image is available locally.
images, err := provider.ListImages(ctx)
@@ -146,7 +145,7 @@ func (s *K8sConformanceSuite) SetupSuite() {
}
func (s *K8sConformanceSuite) TearDownSuite() {
ctx := context.Background()
ctx := s.T().Context()
if s.T().Failed() || *showLog {
k3sLogs, err := s.k3sContainer.Logs(ctx)
@@ -173,7 +172,7 @@ func (s *K8sConformanceSuite) TearDownSuite() {
func (s *K8sConformanceSuite) TestK8sGatewayAPIConformance() {
// Wait for traefik to start
k3sContainerIP, err := s.k3sContainer.ContainerIP(context.Background())
k3sContainerIP, err := s.k3sContainer.ContainerIP(s.T().Context())
require.NoError(s.T(), err)
err = try.GetRequest("http://"+k3sContainerIP+":9000/api/entrypoints", 10*time.Second, try.BodyContains(`"name":"web"`))

View File

@@ -2,7 +2,6 @@ package integration
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net"
@@ -51,7 +50,7 @@ func (s *RedisSentinelSuite) SetupSuite() {
net.JoinHostPort(s.getComposeServiceIP("sentinel3"), "26379"),
}
kv, err := valkeyrie.NewStore(
context.Background(),
s.T().Context(),
redis.StoreName,
s.redisEndpoints,
&redis.Config{
@@ -157,7 +156,7 @@ func (s *RedisSentinelSuite) TestSentinelConfiguration() {
}
for k, v := range data {
err := s.kvClient.Put(context.Background(), k, []byte(v), nil)
err := s.kvClient.Put(s.T().Context(), k, []byte(v), nil)
require.NoError(s.T(), err)
}

View File

@@ -2,7 +2,6 @@ package integration
import (
"bytes"
"context"
"encoding/json"
"net"
"net/http"
@@ -43,7 +42,7 @@ func (s *RedisSuite) SetupSuite() {
s.redisEndpoints = append(s.redisEndpoints, net.JoinHostPort(s.getComposeServiceIP("redis"), "6379"))
kv, err := valkeyrie.NewStore(
context.Background(),
s.T().Context(),
redis.StoreName,
s.redisEndpoints,
&redis.Config{},
@@ -112,7 +111,7 @@ func (s *RedisSuite) TestSimpleConfiguration() {
}
for k, v := range data {
err := s.kvClient.Put(context.Background(), k, []byte(v), nil)
err := s.kvClient.Put(s.T().Context(), k, []byte(v), nil)
require.NoError(s.T(), err)
}

View File

@@ -1,4 +1,3 @@
version: "3.8"
services:
server0:
image: traefik/whoami

View File

@@ -1,4 +1,3 @@
version: "3.8"
services:
noOverrideAllowlist:
image: traefik/whoami

View File

@@ -1,4 +1,3 @@
version: "3.8"
services:
whoami1:
image: traefik/whoami

View File

@@ -1,4 +1,3 @@
version: "3.8"
services:
consul:
image: consul:1.6

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