Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ba0f7364f1 | ||
|
43162507e3 | ||
|
9bf14b6764 | ||
|
16d43aefd7 | ||
|
c6daab54e3 | ||
|
a59bcb29b5 | ||
|
6486cf95d8 | ||
|
50931813f2 | ||
|
96386b1d78 | ||
|
5ef853a0c5 | ||
|
b2b4b66b08 | ||
|
27326e6569 | ||
|
f2b7d7f6e1 | ||
|
95434e870b | ||
|
aa1c0d8686 | ||
|
7ca90a4b18 | ||
|
a3685ee9fa | ||
|
ba595bfa98 | ||
|
9a46d35169 | ||
|
955f484d33 | ||
|
cdacf0bca8 | ||
|
d674b393a8 | ||
|
137efedba7 | ||
|
c69a8b5cdb | ||
|
b0e246cea9 | ||
|
c9c8cd6b50 | ||
|
a519180665 | ||
|
e223116225 | ||
|
8ae0379171 | ||
|
4daf13b866 | ||
|
c2c488ffc5 | ||
|
107efb8a5a | ||
|
0f862f4792 | ||
|
74eafcd044 | ||
|
b0d8e08e2b | ||
|
917771739e | ||
|
ae79d4e5f0 | ||
|
aac8bc69ad | ||
|
bfcef58a4f | ||
|
f7a6f32784 | ||
|
fe5c7fdc65 | ||
|
92f798dfcd | ||
|
bd4bfd8919 | ||
|
f174014d96 | ||
|
2fdee25bb3 | ||
|
cd16321dd9 | ||
|
0b4058dde0 | ||
|
6a54f1f66c |
2
.github/workflows/build.yaml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
2
.github/workflows/experimental.yaml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
- v*
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
2
.github/workflows/release.yaml
vendored
@@ -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"
|
||||
|
35
.github/workflows/test-integration.yaml
vendored
@@ -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
|
||||
|
33
.github/workflows/test-unit.yaml
vendored
@@ -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
|
||||
|
2
.github/workflows/validate.yaml
vendored
@@ -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
|
||||
|
||||
|
83
CHANGELOG.md
@@ -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)
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
2
Makefile
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
|
BIN
docs/content/assets/img/getting-started/docker-router.png
Normal file
After Width: | Height: | Size: 520 KiB |
BIN
docs/content/assets/img/getting-started/kubernetes-gateway.png
Normal file
After Width: | Height: | Size: 610 KiB |
BIN
docs/content/assets/img/getting-started/providers.png
Normal file
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 878 KiB |
BIN
docs/content/assets/img/getting-started/traefik-dashboard.png
Normal file
After Width: | Height: | Size: 791 KiB |
BIN
docs/content/assets/img/getting-started/whoami-localhost.png
Normal file
After Width: | Height: | Size: 603 KiB |
BIN
docs/content/assets/img/setup/route-in-dashboard.png
Normal file
After Width: | Height: | Size: 482 KiB |
BIN
docs/content/assets/img/setup/traefik-dashboard-docker.png
Normal file
After Width: | Height: | Size: 731 KiB |
BIN
docs/content/assets/img/setup/traefik-dashboard-swarm.png
Normal file
After Width: | Height: | Size: 715 KiB |
BIN
docs/content/assets/img/setup/traefik-dashboard.png
Normal file
After Width: | Height: | Size: 733 KiB |
BIN
docs/content/assets/img/setup/whoami-json-dump.png
Normal file
After Width: | Height: | Size: 358 KiB |
@@ -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."
|
||||
|
||||
|
462
docs/content/expose/docker.md
Normal 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
|
1012
docs/content/expose/kubernetes.md
Normal file
22
docs/content/expose/overview.md
Normal 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)
|
401
docs/content/expose/swarm.md
Normal 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
|
162
docs/content/getting-started/docker.md
Normal 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/)
|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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!}
|
25
docs/content/getting-started/index.md
Normal 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
|
331
docs/content/getting-started/kubernetes.md
Normal 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/)
|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
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!}
|
@@ -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"
|
||||
|
@@ -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 }
|
||||
|
||||

|
||||
|
||||
## 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"
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -7,18 +7,15 @@ description: "Traefik Proxy, an open-source Edge Router, auto-discovers configur
|
||||
|
||||

|
||||
|
||||
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, there’s 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).
|
||||
Here’s 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).
|
||||
|
@@ -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`
|
||||
|
||||
|
161
docs/content/migrate/v2-to-v3.md
Normal 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!}
|
@@ -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
@@ -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 |
|
@@ -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 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
|
||||
|
||||
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 🎉
|
@@ -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).
|
||||
|
@@ -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
|
||||
|
179
docs/content/observe/logs-and-access-logs.md
Normal 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).
|
104
docs/content/observe/metrics.md
Normal 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).
|
80
docs/content/observe/overview.md
Normal 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!}
|
93
docs/content/observe/tracing.md
Normal 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.
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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` |
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
# ...
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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:
|
||||
# ...
|
||||
|
@@ -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:
|
||||
# ...
|
||||
|
@@ -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:
|
||||
# ...
|
||||
|
@@ -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`. |
|
||||
|
@@ -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:
|
||||
# ...
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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:
|
||||
|
299
docs/content/setup/docker.md
Normal 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, access‑logs."
|
||||
---
|
||||
|
||||
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 **basic‑auth**
|
||||
- Terminate TLS with a self‑signed certificate for `*.docker.localhost`
|
||||
- Deploy the **whoami** demo service
|
||||
- Enable access‑logs and Prometheus metrics
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Desktop / Engine
|
||||
- Docker Compose
|
||||
- `openssl`
|
||||
- `htpasswd` from `apache2-utils`
|
||||
|
||||
## Create a self‑signed certificate
|
||||
|
||||
Before Traefik can serve HTTPS locally it needs a certificate. In production you’d use one from a trusted CA, but for a single‑machine stack a quick self‑signed 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 read‑only 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 [basic‑auth middleware](../reference/routing-configuration/http/middlewares/basicauth.md). To do this, generate a hashed username / password pair that Traefik’s 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 self‑routing
|
||||
- "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"
|
||||
|
||||
# Basic‑auth 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:
|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||

|
||||
|
||||
!!! 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!}
|
398
docs/content/setup/kubernetes.md
Normal 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, access‑logs."
|
||||
---
|
||||
|
||||
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 Self‑Signed TLS Secret
|
||||
|
||||
Traefik's Gateway listeners require a certificate whenever a listener uses `protocol: HTTPS`.
|
||||
|
||||
For local development create a throw‑away self‑signed certificate and
|
||||
store it in a Kubernetes Secret named **local‑selfsigned‑tls**.
|
||||
The Gateway references this secret to terminate TLS on the `websecure` listener.
|
||||
|
||||
```bash
|
||||
# 1) Generate a self‑signed 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:
|
||||
|
||||

|
||||
|
||||
## 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 to the Routes in the Traefik Dashboard; you’ll see that the [https://whoami.docker.localhost](https://whoami.docker.localhost) route has been created.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
## 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 (HTTP‑01) or via your DNS provider's API (DNS‑01). 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
|
||||
|
||||
Traefik’s built‑in ACME/Let’s Encrypt integration works for IngressRoute and Ingress resources, but it does not issue certificates for Gateway API listeners.
|
||||
If you’re using the Gateway API, install [cert‑manager](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
@@ -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, self‑signed TLS, metrics, tracing, and access‑logs."
|
||||
---
|
||||
|
||||
This guide provides an in‑depth walkthrough for installing and configuring Traefik Proxy as a **Swarm service** using `docker stack deploy`. It follows the same structure as the standalone‑Docker 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 **basic‑auth**
|
||||
- Terminate TLS with a self‑signed certificate for `*.swarm.localhost`
|
||||
- Deploy the **whoami** demo service
|
||||
- Enable access‑logs and Prometheus metrics
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Engine with **Swarm mode** initialised (`docker swarm init`)
|
||||
- Docker Compose
|
||||
- `openssl`
|
||||
- `htpasswd`
|
||||
|
||||
## Create a self‑signed certificate
|
||||
|
||||
Before Traefik can serve HTTPS locally it needs a certificate. In production you’d use one from a trusted CA, but for a multi‑node dev swarm a quick self‑signed 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 Traefik’s middleware will validate:
|
||||
|
||||
```bash
|
||||
htpasswd -nb admin "P@ssw0rd" | sed -e 's/\$/\$\$/g'
|
||||
```
|
||||
|
||||
Copy the full output (e.g., `admin:$$apr1$$…`) — we’ll paste it into the middleware label.
|
||||
|
||||
## Create a docker‑compose‑swarm.yaml
|
||||
|
||||
!!! note
|
||||
Swarm uses `docker stack deploy`. The compose file can be named anything; we’ll use `docker‑compose‑swarm.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 `docker‑compose‑swarm.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"
|
||||
|
||||
# Basic‑auth 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 doesn’t 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 basic‑auth credentials you configured.
|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
```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 HTTP → HTTPS redirects, and foundational observability. Expand this stack with Let’s Encrypt, additional middlewares, or multiple Traefik replicas as your Swarm grows.
|
||||
|
||||
{!traefik-for-business-applications.md!}
|
@@ -1,5 +1,3 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
|
||||
traefik:
|
||||
|
@@ -1,5 +1,3 @@
|
||||
version: "3.3"
|
||||
|
||||
secrets:
|
||||
ovh_endpoint:
|
||||
file: "./secrets/ovh_endpoint.secret"
|
||||
|
@@ -1,5 +1,3 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
|
||||
traefik:
|
||||
|
@@ -1,5 +1,3 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
|
||||
traefik:
|
||||
|
@@ -1,5 +1,3 @@
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
|
||||
traefik:
|
||||
|
@@ -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: {}
|
||||
|
||||
|
355
docs/content/user-guides/websocket.md
Normal 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.
|
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
ENV PATH="${PATH}:/venv/bin"
|
||||
|
||||
|
@@ -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
@@ -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
@@ -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=
|
||||
|
@@ -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{
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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"`))
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
server0:
|
||||
image: traefik/whoami
|
||||
|
@@ -1,4 +1,3 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
noOverrideAllowlist:
|
||||
image: traefik/whoami
|
||||
|
@@ -1,4 +1,3 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
whoami1:
|
||||
image: traefik/whoami
|
||||
|
@@ -1,4 +1,3 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
consul:
|
||||
image: consul:1.6
|
||||
|