Merge branch 'master' into tlsstoreresilient

This commit is contained in:
David 2026-01-29 19:23:50 +01:00 committed by GitHub
commit fb04224835
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
168 changed files with 6868 additions and 5625 deletions

View file

@ -52,12 +52,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
env:
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
with:
@ -65,7 +65,7 @@ jobs:
check-latest: true
- name: Artifact webui
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz

View file

@ -16,7 +16,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
@ -28,7 +28,7 @@ jobs:
run: ./docs/scripts/lint.sh docs
- name: Setup python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: 'pip'
@ -41,7 +41,7 @@ jobs:
mkdocs build --strict
- name: Setup ruby
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
with:
ruby-version: '3.4'
@ -54,7 +54,7 @@ jobs:
# Comes from https://github.com/gjtorikian/html-proofer?tab=readme-ov-file#caching-with-continuous-integration
- name: Cache HTMLProofer
uses: actions/cache@v4
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: tmp/.htmlproofer
key: ${{ runner.os }}-htmlproofer

View file

@ -29,17 +29,17 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: setup go
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
if: ${{ matrix.language == 'go' }}
with:
go-version-file: 'go.mod'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@38e701f46e33fb233075bf4238cb1e5d68e429e4 # v3.31.11
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@38e701f46e33fb233075bf4238cb1e5d68e429e4 # v3.31.11
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@ -66,6 +66,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@38e701f46e33fb233075bf4238cb1e5d68e429e4 # v3.31.11
with:
category: "/language:${{matrix.language}}"

View file

@ -21,12 +21,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Login to DockerHub
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

View file

@ -24,12 +24,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
env:
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
with:
@ -43,19 +43,19 @@ jobs:
run: echo ${GITHUB_REF##*/}
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Artifact webui
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz

View file

@ -31,12 +31,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
env:
# Ensure cache consistency on Linux, see https://github.com/actions/setup-go/pull/383
ImageOS: ${{ matrix.os }}
@ -45,7 +45,7 @@ jobs:
check-latest: true
- name: Artifact webui
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz
@ -64,7 +64,7 @@ jobs:
echo "GORELEASER_CONFIG_FILE_PATH=$GORELEASER_CONFIG_FILE_PATH" >> $GITHUB_ENV
- name: Build with goreleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
distribution: goreleaser
# 'latest', 'nightly', or a semver
@ -72,7 +72,7 @@ jobs:
args: release --clean --timeout="90m" --config "${{ env.GORELEASER_CONFIG_FILE_PATH }}"
- name: Artifact binaries
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ${{ matrix.os }}-binaries
path: |
@ -91,12 +91,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Artifact webui
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: webui.tar.gz
@ -113,7 +113,7 @@ jobs:
echo "${TRAEFIKER_RSA}" | base64 --decode > ~/.ssh/traefiker_rsa
- name: Download All Artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
path: dist/
pattern: "*-binaries"

View file

@ -15,9 +15,9 @@ jobs:
if: github.repository == 'traefik/traefik'
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: imjasonh/setup-crane@v0.4
- uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4
- name: Sync
run: |

View file

@ -11,7 +11,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
@ -19,7 +19,7 @@ jobs:
run: corepack enable
- name: Setup node
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: webui/.nvmrc
cache: yarn
@ -42,7 +42,7 @@ jobs:
tar czvf webui.tar.gz ./webui/static/
- name: Artifact webui
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: webui.tar.gz
path: webui.tar.gz

View file

@ -23,12 +23,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}

View file

@ -21,12 +21,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@ -39,14 +39,14 @@ jobs:
run: make binary-linux-amd64
- name: Save go cache build
uses: actions/cache/save@v4
uses: actions/cache/save@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.cache/go-build
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
- name: Artifact traefik binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: traefik
path: ./dist/linux/amd64/traefik
@ -65,18 +65,18 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
- name: Download traefik binary
uses: actions/download-artifact@v7
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: traefik
path: ./dist/linux/amd64/
@ -85,7 +85,7 @@ jobs:
run: chmod +x ./dist/linux/amd64/traefik
- name: Restore go cache build
uses: actions/cache/restore@v4
uses: actions/cache/restore@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
with:
path: |
~/.cache/go-build
@ -93,7 +93,7 @@ jobs:
- name: Generate go test Slice
id: test_split
uses: hashicorp-forge/go-test-split-action@v2.0.0
uses: hashicorp-forge/go-test-split-action@ddb2685fb140c29505663b405af7eb2cd953dd13 # v2.0.1
with:
packages: ./integration
total: ${{ matrix.parallel }}

View file

@ -23,17 +23,17 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Set up KO
uses: ko-build/setup-ko@v0.6
uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6
env:
KO_DOCKER_REPO: ko.local

View file

@ -21,12 +21,12 @@ jobs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@ -48,12 +48,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@ -68,7 +68,7 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
@ -76,7 +76,7 @@ jobs:
run: corepack enable
- name: Set up Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: webui/.nvmrc
cache: 'yarn'

View file

@ -18,18 +18,18 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
version: "${{ env.GOLANGCI_LINT_VERSION }}"
@ -39,12 +39,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@ -61,12 +61,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v6
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true

View file

@ -82,6 +82,7 @@ linters:
toolchain-pattern: go1\.\d+\.\d+$
tool-forbidden: true
go-version-pattern: ^1\.\d+(\.0)?$
replace-local: true
replace-allow-list:
- github.com/abbot/go-http-auth
- github.com/gorilla/mux

View file

@ -103,7 +103,7 @@ test-integration:
#? test-gateway-api-conformance: Run the Gateway API conformance tests
test-gateway-api-conformance: build-image-dirty
# In case of a new Minor/Major version, the traefikVersion needs to be updated.
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -v -tags gatewayAPIConformance -test.run GatewayAPIConformanceSuite -traefikVersion="v3.6" $(TESTFLAGS)
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -v -tags gatewayAPIConformance -test.run GatewayAPIConformanceSuite -traefikVersion="v3.7" $(TESTFLAGS)
.PHONY: test-knative-conformance
#? test-knative-conformance: Run the Knative conformance tests

View file

@ -21,7 +21,7 @@ docs: docs-clean docs-image docs-lint docs-build docs-verify
# Writer Mode: build and serve docs on http://localhost:8000 with livereload
.PHONY: docs-serve
docs-serve: docs-image
docker run $(DOCKER_RUN_DOC_OPTS) $(TRAEFIK_DOCS_BUILD_IMAGE) mkdocs serve
docker run $(DOCKER_RUN_DOC_OPTS) $(TRAEFIK_DOCS_BUILD_IMAGE) mkdocs serve -a 0.0.0.0:8000
## Pull image for doc building
.PHONY: docs-pull-images

View file

@ -23,6 +23,7 @@ description: "Traefik Proxy is an open source software with a thriving community
* Simon Delicata [@sdelicata](https://github.com/sdelicata)
* Baptiste Mayelle [@youkoulayley](https://github.com/youkoulayley)
* Jesper Noordsij [@jnoordsij](https://github.com/jnoordsij)
* Gina Adzani [@gndz07](https://github.com/gndz07)
## Past Maintainers

View file

@ -1,252 +1,29 @@
# Exposing Services with Traefik on Docker
# Exposing Services with Traefik on Docker - Advanced
This guide will help you expose your services securely through Traefik Proxy using Docker. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Docker before proceeding.
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for hierarchical routing with a complex authentication based routing example
## Prerequisites
- Completed the [Basic Guide](basic.md)
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the Traefik Docker Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service in `docker-compose.yml`:
```yaml
labels:
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
@ -255,10 +32,10 @@ labels:
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply middlewares to whoami router
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
@ -288,7 +65,7 @@ curl -k -I -H "Host: whoami.docker.localhost" https://localhost/
In the response headers, you should see security headers set by the middleware:
- `X-Frame-Options: DENY`
- `X-Frame-Options: DENY`
- `X-Content-Type-Options: nosniff`
- `X-XSS-Protection: 1; mode=block`
- `Strict-Transport-Security` with the appropriate settings
@ -438,28 +215,191 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "Provider Requirement"
Multi-layer routing requires the File provider, as Docker labels do not support the `parentRefs` field. However, you can use **both Docker and File providers together** - Docker labels for service discovery and File configuration for multi-layer routing.
### Setup Multi-Layer Routing with Docker
To use multi-layer routing with Docker, you need to enable the File provider alongside the Docker provider.
Update your Traefik service in `docker-compose.yml`:
```yaml
services:
traefik:
image: "traefik:latest"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic" # Enable File provider
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./dynamic:/etc/traefik/dynamic:ro" # Mount directory for dynamic config
```
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent router authenticates requests, and child routers direct traffic based on user roles.
First, keep your Docker services defined with labels as usual:
```yaml
# In docker-compose.yml
services:
# ... traefik service from above ...
# Mock authentication service that adds X-User-Role header
auth-service:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=Auth Service
labels:
- "traefik.enable=true"
- "traefik.http.services.auth-service.loadbalancer.server.port=80"
# Admin backend service
admin-backend:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=Admin Backend
labels:
- "traefik.enable=true"
- "traefik.http.services.admin-backend.loadbalancer.server.port=80"
# User backend service
user-backend:
image: "traefik/whoami"
networks:
- proxy
environment:
- WHOAMI_NAME=User Backend
labels:
- "traefik.enable=true"
- "traefik.http.services.user-backend.loadbalancer.server.port=80"
```
Now create the multi-layer routing configuration in a file. Create `dynamic/mlr.yml`:
```yaml
http:
routers:
# Parent router with authentication middleware
api-parent:
rule: "Host(`api.docker.localhost`) && PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
# Note: No service and no TLS config - this is a parent router
# Child router for admin users
api-admin:
rule: "HeadersRegexp(`X-Auth-User`, `admin`)"
service: admin-backend@docker # Reference Docker service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
# Child router for regular users
api-user:
rule: "HeadersRegexp(`X-Auth-User`, `user`)"
service: user-backend@docker # Reference Docker service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
middlewares:
auth-middleware:
basicAuth:
users:
- "admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0"
- "user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI."
headerField: X-Auth-User
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
!!! important "Cross-Provider References"
Notice the `@docker` suffix on service names and the `@file` suffix in `parentRefs`. When using the File provider to orchestrate multi-layer routing with Docker services:
- Use `service-name@docker` to reference Docker services
- Use `parent-name@file` in `parentRefs` to reference the parent router in the File provider
The `@provider` suffix tells Traefik which provider namespace to look in for the resource.
Apply the changes:
```bash
docker compose up -d
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.docker.localhost/api`
2. **Parent router** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child router** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Docker service
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Docker
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Docker. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Docker, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../../reference/install-configuration/providers/docker.md) for more details about the Docker integration

View file

@ -0,0 +1,250 @@
# Exposing Services with Traefik on Docker - Basic
This guide will help you get started with exposing your services through Traefik Proxy using Docker. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
## Prerequisites
- Docker and Docker Compose installed
- Basic understanding of Docker concepts
- Traefik deployed using the [Traefik Docker Setup guide](../../setup/docker.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create a `docker-compose.yml` file:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--entryPoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
networks:
proxy:
name: proxy
```
Save this as `docker-compose.yml` and start the services:
```bash
docker compose up -d
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.3
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 172.18.0.2:55108
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 172.18.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: "traefik/whoami"
networks:
- proxy
container_name: "whoami-api"
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web"
```
Apply the changes:
```bash
docker compose up -d
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
mkdir -p certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.docker.localhost"
```
Create a directory for dynamic configuration and add a TLS configuration file:
```bash
mkdir -p dynamic
cat > dynamic/tls.yml << EOF
tls:
certificates:
- certFile: /certs/local.crt
keyFile: /certs/local.key
EOF
```
Update your `docker-compose.yml` file with the following changes:
```yaml
services:
traefik:
image: "traefik:v3.4"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
command:
- "--api.insecure=false"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=proxy"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--entryPoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
# Add the following volumes
- "./certs:/certs:ro"
- "./dynamic:/etc/traefik/dynamic:ro"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`dashboard.docker.localhost`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
# Add the following label
- "traefik.http.routers.dashboard.tls=true"
whoami:
image: "traefik/whoami"
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami.tls=true"
whoami-api:
image: "traefik/whoami"
container_name: "whoami-api"
restart: unless-stopped
networks:
- proxy
environment:
- WHOAMI_NAME=API Service
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami-api.rule=Host(`whoami.docker.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=websecure"
# Add the following label
- "traefik.http.routers.whoami-api.tls=true"
networks:
proxy:
name: proxy
```
Apply the changes:
```bash
docker compose up -d
```
Your browser can access https://whoami.docker.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Docker, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing

View file

@ -1,432 +1,25 @@
# Exposing Services with Traefik on Kubernetes
# Exposing Services with Traefik on Kubernetes - Advanced
This guide will help you expose your services securely through Traefik Proxy on Kubernetes. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding security middleware, and configuring sticky sessions. For routing, this guide gives you two options:
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Kubernetes before proceeding.
- [Gateway API](../reference/routing-configuration/kubernetes/gateway-api.md)
- [IngressRoute](../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
Feel free to choose the one that fits your needs best.
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management (IngressRoute)
- **cert-manager** for automated certificate management (Gateway API)
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for hierarchical routing with complex authentication scenarios (IngressRoute only)
## Prerequisites
- Completed the [Basic Guide](basic.md)
- A Kubernetes cluster with Traefik Proxy installed
- `kubectl` configured to interact with your cluster
- Traefik deployed using the Traefik Kubernetes Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://github.com/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create the deployment and service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
```
Save this as `whoami.yaml` and apply it:
```bash
kubectl apply -f whoami.yaml
```
Now, let's create routes using either Gateway API or IngressRoute.
### Using Gateway API
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # This Gateway is automatically created by Traefik
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Save this as `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### Using IngressRoute
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
!!! info
Make sure to remove the `ports.web.redirections` block from the `values.yaml` file if you followed the Kubernetes Setup Guide to install Traefik otherwise you will be redirected to the HTTPS entrypoint:
```yaml
redirections:
entryPoint:
to: websecure
```
You should see output similar to:
```bash
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on URL paths. This is useful for API versioning, frontend/backend separation, or organizing microservices.
First, deploy a second service to represent an API:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
```
Save this as `whoami-api.yaml` and apply it:
```bash
kubectl apply -f whoami-api.yaml
```
Now set up path-based routing:
### Gateway API with Path Rules
Update your existing `HTTPRoute` to include path-based routing:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with Path Rules
Update your existing IngressRoute to include path-based routing:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly:
```bash
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
```
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
```
Create a TLS secret in Kubernetes:
```bash
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
```
!!! important "Prerequisite for Gateway API with TLS"
Before using the Gateway API with TLS, you must define the `websecure` listener in your Traefik installation. This is typically done in your Helm values.
Example configuration in `values.yaml`:
```yaml
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
```
See the Traefik Kubernetes Setup Guide for complete installation details.
### Gateway API with TLS
Update your existing `HTTPRoute` to use the secured gateway listener:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # The HTTPS listener
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with TLS
Update your existing IngressRoute to use TLS:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # Changed from 'web' to 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # Added TLS configuration
```
Update the file `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify HTTPS Access
Now you can access your service securely. Since we're using a self-signed certificate, you'll need to skip certificate verification:
```bash
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
Your browser can also access https://whoami.docker.localhost/ (you'll need to accept the security warning for the self-signed certificate).
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
### Create Middlewares
@ -469,37 +62,6 @@ kubectl apply -f middlewares.yaml
In Gateway API, you can apply middlewares using the `ExtensionRef` filter type. This is the preferred and standard way to use Traefik middlewares with Gateway API, as it integrates directly with the HTTPRoute specification.
First, make sure you have the same middlewares defined:
```yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: secure-headers
namespace: default
spec:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ip-allowlist
namespace: default
spec:
ipAllowList:
sourceRange:
- 127.0.0.1/32
- 10.0.0.0/8 # Typical cluster network range
- 192.168.0.0/16 # Common local network range
```
Now, update your `HTTPRoute` to reference these middlewares using the `ExtensionRef` filter:
```yaml
@ -525,7 +87,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@ -543,7 +105,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@ -854,7 +416,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@ -876,7 +438,7 @@ spec:
group: traefik.io
kind: Middleware
name: secure-headers
- type: ExtensionRef
- type: ExtensionRef
extensionRef: # IP AllowList Middleware Definition
group: traefik.io
kind: Middleware
@ -986,29 +548,283 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Setup Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "IngressRoute Support"
Multi-layer routing is **natively supported** by Kubernetes IngressRoute (CRD) using the `spec.parentRefs` field. This feature is not available when using standard Kubernetes Ingress or Gateway API resources.
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent IngressRoute authenticates requests, and child IngressRoutes direct traffic based on user roles.
!!! important "Parent Router Requirements"
Parent routers in multi-layer routing must not have a service defined. The child routers will handle the service selection based on their matching rules. Make sure all child IngressRoutes reference the parent correctly using `parentRefs`.
First, deploy your backend services:
```yaml
# whoami-backends.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: admin-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: admin-backend
template:
metadata:
labels:
app: admin-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "Admin Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: admin-backend
namespace: default
spec:
selector:
app: admin-backend
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-backend
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: user-backend
template:
metadata:
labels:
app: user-backend
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "User Backend"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: user-backend
namespace: default
spec:
selector:
app: user-backend
ports:
- port: 80
```
Apply the backend services:
```bash
kubectl apply -f whoami-backends.yaml
```
Now create the middleware and IngressRoutes for multi-layer routing:
```yaml
# mlr-ingressroute.yaml
apiVersion: v1
kind: Secret
metadata:
name: auth-secret
namespace: default
type: Opaque
stringData:
users: |
admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0
user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI.
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: default
spec:
basicAuth:
secret: auth-secret
headerField: X-Auth-User
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.docker.localhost`) && PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
# Note: No services and no TLS config - this is a parent IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-admin
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `admin`)
kind: Rule
services:
- name: admin-backend
port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-user
namespace: default
spec:
parentRefs:
- name: api-parent
namespace: default # Optional, defaults to same namespace
routes:
- match: HeadersRegexp(`X-Auth-User`, `user`)
kind: Rule
services:
- name: user-backend
port: 80
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
Apply the multi-layer routing configuration:
```bash
kubectl apply -f mlr-ingressroute.yaml
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.docker.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.docker.localhost/api`
2. **Parent IngressRoute** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child IngressRoute** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Kubernetes service
### Cross-Namespace Parent References
You can reference parent IngressRoutes in different namespaces by specifying the `namespace` field:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: app-namespace
spec:
parentRefs:
- name: api-parent
namespace: shared-namespace # Parent in different namespace
routes:
- match: Path(`/child`)
kind: Rule
services:
- name: child-service
port: 80
```
!!! important "Cross-Namespace Requirement"
To use cross-namespace parent references, you must enable the `allowCrossNamespace` option in your Traefik Helm values:
```yaml
providers:
kubernetesCRD:
allowCrossNamespace: true
```
### Multiple Parent References
Child IngressRoutes can reference multiple parent IngressRoutes:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-child
namespace: default
spec:
parentRefs:
- name: parent-one
- name: parent-two
routes:
- match: Path(`/api`)
kind: Rule
services:
- name: child-service
port: 80
```
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Kubernetes using both Gateway API and IngressRoute
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Automate certificate management with Let's Encrypt (IngressRoute) and cert-manager (Gateway API)
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing (IngressRoute only)
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Kubernetes. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Kubernetes. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Kubernetes, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Kubernetes Provider documentation](../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) for more details about the Kubernetes integration.
- [Gateway API provider documentation](../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md) for more details about the Gateway API integration.
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Kubernetes Provider documentation](../../reference/install-configuration/providers/kubernetes/kubernetes-crd.md) for more details about the Kubernetes integration
- [Gateway API provider documentation](../../reference/install-configuration/providers/kubernetes/kubernetes-gateway.md) for more details about the Gateway API integration

View file

@ -0,0 +1,438 @@
# Exposing Services with Traefik on Kubernetes - Basic
This guide will help you get started with exposing your services through Traefik Proxy on Kubernetes. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
For routing, this guide gives you two options:
- [Gateway API](../../reference/routing-configuration/kubernetes/gateway-api.md)
- [IngressRoute](../../reference/routing-configuration/kubernetes/crd/http/ingressroute.md)
Feel free to choose the one that fits your needs best.
## Prerequisites
- A Kubernetes cluster with Traefik Proxy installed
- `kubectl` configured to interact with your cluster
- Traefik deployed using the [Traefik Kubernetes Setup guide](../../setup/kubernetes.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://github.com/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, create the deployment and service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
selector:
app: whoami
ports:
- port: 80
```
Save this as `whoami.yaml` and apply it:
```bash
kubectl apply -f whoami.yaml
```
Now, let's create routes using either Gateway API or IngressRoute.
### Using Gateway API
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway # This Gateway is automatically created by Traefik
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Save this as `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### Using IngressRoute
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify Your Service
Your service is now available at http://whoami.docker.localhost/. Test that it works:
```bash
curl -H "Host: whoami.docker.localhost" http://localhost/
```
!!! info
Make sure to remove the `ports.web.redirections` block from the `values.yaml` file if you followed the Kubernetes Setup Guide to install Traefik otherwise you will be redirected to the HTTPS entrypoint:
```yaml
redirections:
entryPoint:
to: websecure
```
You should see output similar to:
```bash
Hostname: whoami-6d5d964cb-8pv4k
IP: 127.0.0.1
IP: ::1
IP: 10.42.0.18
IP: fe80::d4c0:3bff:fe20:b0a3
RemoteAddr: 10.42.0.17:39872
GET / HTTP/1.1
Host: whoami.docker.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.0.1
X-Forwarded-Host: whoami.docker.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-76cbd5b89c-rx5xn
X-Real-Ip: 10.42.0.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on URL paths. This is useful for API versioning, frontend/backend separation, or organizing microservices.
First, deploy a second service to represent an API:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-api
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: whoami-api
template:
metadata:
labels:
app: whoami-api
spec:
containers:
- name: whoami
image: traefik/whoami
env:
- name: WHOAMI_NAME
value: "API Service"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami-api
namespace: default
spec:
selector:
app: whoami-api
ports:
- port: 80
```
Save this as `whoami-api.yaml` and apply it:
```bash
kubectl apply -f whoami-api.yaml
```
Now set up path-based routing:
### Gateway API with Path Rules
Update your existing `HTTPRoute` to include path-based routing:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with Path Rules
Update your existing IngressRoute to include path-based routing:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
```
Save this as `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.docker.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.docker.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly:
```bash
{"hostname":"whoami-api-67d97b4868-dvvll","ip":["127.0.0.1","::1","10.42.0.9","fe80::10aa:37ff:fe74:31f2"],"headers":{"Accept":["*/*"],"Accept-Encoding":["gzip"],"User-Agent":["curl/8.7.1"],"X-Forwarded-For":["10.42.0.1"],"X-Forwarded-Host":["whoami.docker.localhost"],"X-Forwarded-Port":["80"],"X-Forwarded-Proto":["http"],"X-Forwarded-Server":["traefik-669c479df8-vkj22"],"X-Real-Ip":["10.42.0.1"]},"url":"/api","host":"whoami.docker.localhost","method":"GET","name":"API Service","remoteAddr":"10.42.0.13:36592"}
```
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=whoami.docker.localhost"
```
Create a TLS secret in Kubernetes:
```bash
kubectl create secret tls whoami-tls --cert=tls.crt --key=tls.key
```
!!! important "Prerequisite for Gateway API with TLS"
Before using the Gateway API with TLS, you must define the `websecure` listener in your Traefik installation. This is typically done in your Helm values.
Example configuration in `values.yaml`:
```yaml
gateway:
listeners:
web:
port: 80
protocol: HTTP
namespacePolicy:
from: All
websecure:
port: 443
protocol: HTTPS
namespacePolicy:
from: All
mode: Terminate
certificateRefs:
- kind: Secret
name: local-selfsigned-tls
group: ""
```
See the Traefik Kubernetes Setup Guide for complete installation details.
### Gateway API with TLS
Update your existing `HTTPRoute` to use the secured gateway listener:
```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: whoami
namespace: default
spec:
parentRefs:
- name: traefik-gateway
sectionName: websecure # The HTTPS listener
hostnames:
- "whoami.docker.localhost"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: whoami-api
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: whoami
port: 80
```
Update the file `whoami-route.yaml` and apply it:
```bash
kubectl apply -f whoami-route.yaml
```
### IngressRoute with TLS
Update your existing IngressRoute to use TLS:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: default
spec:
entryPoints:
- websecure # Changed from 'web' to 'websecure'
routes:
- match: Host(`whoami.docker.localhost`) && Path(`/api`)
kind: Rule
services:
- name: whoami-api
port: 80
- match: Host(`whoami.docker.localhost`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls # Added TLS configuration
```
Update the file `whoami-ingressroute.yaml` and apply it:
```bash
kubectl apply -f whoami-ingressroute.yaml
```
### Verify HTTPS Access
Now you can access your service securely. Since we're using a self-signed certificate, you'll need to skip certificate verification:
```bash
curl -k -H "Host: whoami.docker.localhost" https://localhost/
```
Your browser can also access https://whoami.docker.localhost/ (you'll need to accept the security warning for the self-signed certificate).
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Kubernetes, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt (IngressRoute) or cert-manager (Gateway API)
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing with IngressRoute

View file

@ -17,6 +17,100 @@ Following these guides, you'll learn how to:
For detailed steps tailored to your environment, follow the guide for your platform:
- [Kubernetes](./kubernetes.md)
- [Docker](./docker.md)
- [Docker Swarm](./swarm.md)
- [Kubernetes](./kubernetes/basic.md)
- [Docker](./docker/basic.md)
- [Docker Swarm](./swarm/basic.md)
## Advanced Use Cases
### Exposing gRPC Services
Traefik Proxy supports gRPC applications without requiring specific configuration. You can expose gRPC services using either HTTP (h2c) or HTTPS.
??? example "Using HTTP (h2c)"
For unencrypted gRPC communication, configure your service to use the `h2c://` protocol scheme:
```yaml
http:
routers:
grpc-router:
service: grpc-service
rule: Host(`grpc.example.com`)
services:
grpc-service:
loadBalancer:
servers:
- url: h2c://backend:8080
```
!!! note
For providers with labels (Docker, Kubernetes), specify the scheme using:
`traefik.http.services.<service-name>.loadbalancer.server.scheme=h2c`
??? example "Using HTTPS"
For encrypted gRPC communication, use standard HTTPS URLs. Traefik will use HTTP/2 over TLS to communicate with your gRPC backend:
```yaml
http:
routers:
grpc-router:
service: grpc-service
rule: Host(`grpc.example.com`)
tls: {}
services:
grpc-service:
loadBalancer:
servers:
- url: https://backend:8080
```
Traefik handles the protocol negotiation automatically. Configure TLS certificates for your backends using [ServersTransport](../reference/routing-configuration/http/load-balancing/serverstransport.md) if needed.
### Exposing WebSocket Services
Traefik Proxy supports WebSocket (WS) and WebSocket Secure (WSS) connections out of the box. No special configuration is required beyond standard HTTP routing.
??? example "Basic WebSocket"
Configure a router and service pointing to your WebSocket server. Traefik automatically detects and handles the WebSocket upgrade:
```yaml
http:
routers:
websocket-router:
rule: Host(`ws.example.com`)
service: websocket-service
services:
websocket-service:
loadBalancer:
servers:
- url: http://websocket-backend:8000
```
??? example "WebSocket Secure (WSS)"
For encrypted WebSocket connections, enable TLS on your router. Clients connect using `wss://` while you can choose whether backends use encrypted or unencrypted connections:
```yaml
http:
routers:
websocket-secure-router:
rule: Host(`wss.example.com`)
service: websocket-service
tls: {}
services:
websocket-service:
loadBalancer:
servers:
- url: http://websocket-backend:8000 # SSL termination at Traefik
# OR
# - url: https://websocket-backend:8443 # End-to-end encryption
```
Traefik preserves WebSocket headers including `Origin`, `Sec-WebSocket-Key`, and `Sec-WebSocket-Version`. Use the [Headers middleware](../reference/routing-configuration/http/middlewares/headers.md) if you need to modify headers for origin checking or other requirements.

View file

@ -1,186 +1,23 @@
# Exposing Services with Traefik on Docker Swarm
# Exposing Services with Traefik on Docker Swarm - Advanced
This guide will help you expose your services securely through Traefik Proxy using Docker Swarm. We'll cover routing HTTP and HTTPS traffic, implementing TLS, adding middlewares, Let's Encrypt integration, and sticky sessions.
This guide builds on the concepts and setup from the [Basic Guide](basic.md). Make sure you've completed the basic guide and have a working Traefik setup with Docker Swarm before proceeding.
In this advanced guide, you'll learn how to enhance your Traefik deployment with:
- **Middlewares** for security headers and access control
- **Let's Encrypt** for automated certificate management
- **Sticky sessions** for stateful applications
- **Multi-layer routing** for complex authentication scenarios
## Prerequisites
- Completed the [Basic Guide](basic.md)
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the Traefik Docker Swarm Setup guide
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
- Working Traefik setup from the basic guide
## Add Middlewares
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Middlewares allow you to modify requests or responses as they pass through Traefik. Let's add two useful middlewares: [Headers](../../reference/routing-configuration/http/middlewares/headers.md) for security and [IP allowlisting](../../reference/routing-configuration/http/middlewares/ipallowlist.md) for access control.
Add the following labels to your whoami service deployment section in `docker-compose.yml`:
@ -189,7 +26,7 @@ deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Secure Headers Middleware
- "traefik.http.middlewares.secure-headers.headers.frameDeny=true"
- "traefik.http.middlewares.secure-headers.headers.sslRedirect=true"
@ -198,10 +35,10 @@ deploy:
- "traefik.http.middlewares.secure-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secure-headers.headers.stsPreload=true"
- "traefik.http.middlewares.secure-headers.headers.stsSeconds=31536000"
# IP Allowlist Middleware
- "traefik.http.middlewares.ip-allowlist.ipallowlist.sourceRange=127.0.0.1/32,192.168.0.0/16,10.0.0.0/8"
# Apply the middlewares
- "traefik.http.routers.whoami.middlewares=secure-headers,ip-allowlist"
```
@ -332,7 +169,7 @@ deploy:
# ... existing configuration ...
labels:
# ... existing labels ...
# Sticky Sessions Configuration
- "traefik.http.services.whoami.loadbalancer.sticky.cookie=true"
- "traefik.http.services.whoami.loadbalancer.sticky.cookie.name=sticky_cookie"
@ -374,28 +211,195 @@ You should see different `Hostname` values in these responses, as each request i
!!! important "Browser Testing"
When testing in browsers, you need to use the same browser session to maintain the cookie. The cookie is set with `httpOnly` and `secure` flags for security, so it will only be sent over HTTPS connections and won't be accessible via JavaScript.
For more advanced configuration options, see the [reference documentation](../reference/routing-configuration/http/load-balancing/service.md).
For more advanced configuration options, see the [reference documentation](../../reference/routing-configuration/http/load-balancing/service.md).
## Multi-Layer Routing
Multi-layer routing enables hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions. This is particularly useful for authentication-based routing or staged middleware application.
!!! info "Provider Requirement"
Multi-layer routing requires the File provider, as Docker Swarm labels do not support the `parentRefs` field. However, you can use **both Docker Swarm and File providers together** - Swarm labels for service discovery and File configuration for multi-layer routing.
### Setup Multi-Layer Routing with Docker Swarm
To use multi-layer routing with Docker Swarm, you need to enable the File provider alongside the Docker provider.
Update your Traefik service in `docker-compose.yml`:
```yaml
services:
traefik:
image: traefik:v3.4
command:
- "--api.dashboard=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik_proxy"
- "--providers.file.directory=/etc/traefik/dynamic" # Enable File provider
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
configs:
- source: mlr-config
target: /etc/traefik/dynamic/mlr.yml
networks:
- traefik_proxy
deploy:
placement:
constraints:
- node.role == manager
configs:
mlr-config:
file: ./dynamic/mlr.yml
networks:
traefik_proxy:
external: true
```
### Authentication-Based Routing Example
Let's create a multi-layer routing setup where a parent router authenticates requests, and child routers direct traffic based on user roles.
First, keep your Docker Swarm services defined with labels as usual:
```yaml
# In docker-compose.yml
services:
# ... traefik service from above ...
# Admin backend service
admin-backend:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=Admin Backend
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.services.admin-backend.loadbalancer.server.port=80"
# User backend service
user-backend:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=User Backend
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.services.user-backend.loadbalancer.server.port=80"
```
Now create the multi-layer routing configuration in a file. Create `dynamic/mlr.yml`:
```yaml
http:
routers:
# Parent router with authentication middleware
api-parent:
rule: "Host(`api.swarm.localhost`) && PathPrefix(`/api`)"
middlewares:
- auth-middleware
entryPoints:
- websecure
# Note: No service and no TLS config - this is a parent router
# Child router for admin users
api-admin:
rule: "HeadersRegexp(`X-Auth-User`, `admin`)"
service: admin-backend@swarm # Reference Swarm service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
# Child router for regular users
api-user:
rule: "HeadersRegexp(`X-Auth-User`, `user`)"
service: user-backend@swarm # Reference Swarm service
parentRefs:
- api-parent@file # Explicit reference to parent in file provider
middlewares:
auth-middleware:
basicAuth:
users:
- "admin:$apr1$DmXR3Add$wfdbGw6RWIhFb0ffXMM4d0"
- "user:$apr1$GJtcIY1o$mSLdsWYeXpPHVsxGDqadI."
headerField: X-Auth-User
```
!!! note "Generating Password Hashes"
The password hashes above are generated using `htpasswd`. To create your own user credentials:
```bash
# Using htpasswd (Apache utils)
htpasswd -nb admin yourpassword
```
!!! important "Cross-Provider References"
Notice the `@swarm` suffix on service names and the `@file` suffix in `parentRefs`. When using the File provider to orchestrate multi-layer routing with Swarm services:
- Use `service-name@swarm` to reference Swarm services
- Use `parent-name@file` in `parentRefs` to reference the parent router in the File provider
The `@provider` suffix tells Traefik which provider namespace to look in for the resource.
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test Multi-Layer Routing
Test the routing behavior:
```bash
# Request goes through parent router → auth middleware → admin child router
curl -k -u admin:test -H "Host: api.swarm.localhost" https://localhost/api
```
You should see the response from the admin-backend service when authenticating as `admin`. Try with `user:test` credentials to reach the user-backend service instead.
### How It Works
1. **Request arrives** at `api.swarm.localhost/api`
2. **Parent router** (`api-parent`) matches based on host and path
3. **BasicAuth middleware** authenticates the user and sets the `X-Auth-User` header with the username
4. **Child router** (`api-admin` or `api-user`) matches based on the header value
5. **Request forwarded** to the appropriate Swarm service
For more details about multi-layer routing, see the [Multi-Layer Routing documentation](../../reference/routing-configuration/http/routing/multi-layer-routing.md).
## Conclusion
In this guide, you've learned how to:
In this advanced guide, you've learned how to:
- Expose HTTP services through Traefik in Docker Swarm
- Set up path-based routing to direct traffic to different backend services
- Secure your services with TLS using self-signed certificates
- Add security with middlewares like secure headers and IP allow listing
- Automate certificate management with Let's Encrypt
- Implement sticky sessions for stateful applications
- Setup multi-layer routing for authentication-based routing
These fundamental capabilities provide a solid foundation for exposing any application through Traefik Proxy in Docker Swarm. Each of these can be further customized to meet your specific requirements.
These advanced capabilities allow you to build production-ready Traefik deployments with Docker Swarm. Each of these can be further customized to meet your specific requirements.
### Next Steps
Now that you understand the basics of exposing services with Traefik Proxy, you might want to explore:
Now that you've mastered both basic and advanced Traefik features with Docker Swarm, you might want to explore:
- [Advanced routing options](../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../reference/install-configuration/providers/docker.md) for more details about the Docker integration
- [Advanced routing options](../../reference/routing-configuration/http/routing/rules-and-priority.md) like query parameter matching, header-based routing, and more
- [Additional middlewares](../../reference/routing-configuration/http/middlewares/overview.md) for authentication, rate limiting, and request modifications
- [Observability features](../../reference/install-configuration/observability/metrics.md) for monitoring and debugging your Traefik deployment
- [TCP services](../../reference/routing-configuration/tcp/service.md) for exposing TCP services
- [UDP services](../../reference/routing-configuration/udp/service.md) for exposing UDP services
- [Docker provider documentation](../../reference/install-configuration/providers/docker.md) for more details about the Docker integration

View file

@ -0,0 +1,191 @@
# Exposing Services with Traefik on Docker Swarm - Basic
This guide will help you get started with exposing your services through Traefik Proxy using Docker Swarm. You'll learn the fundamentals of routing HTTP traffic, setting up path-based routing, and securing your services with TLS.
## Prerequisites
- Docker Swarm cluster initialized
- Basic understanding of Docker Swarm concepts
- Traefik deployed using the [Traefik Docker Swarm Setup guide](../../setup/swarm.md)
## Expose Your First HTTP Service
Let's expose a simple HTTP service using the [whoami](https://hub.docker.com/r/traefik/whoami) application. This will demonstrate basic routing to a backend service.
First, update your existing `docker-compose.yml` file if you haven't already:
```yaml
services:
whoami:
image: traefik/whoami
networks:
- traefik_proxy
deploy:
replicas: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.swarm.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web,websecure"
```
Save this as `docker-compose.yml` and deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Verify Your Service
Your service is now available at http://whoami.swarm.localhost/. Test that it works:
```bash
curl -H "Host: whoami.swarm.localhost" http://localhost/
```
You should see output similar to:
```bash
Hostname: whoami.1.7c8f7tr56q3p949rscxrkp80e
IP: 127.0.0.1
IP: ::1
IP: 10.0.1.8
IP: fe80::215:5dff:fe00:c9e
RemoteAddr: 10.0.1.2:45098
GET / HTTP/1.1
Host: whoami.swarm.localhost
User-Agent: curl/7.68.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.0.1.1
X-Forwarded-Host: whoami.swarm.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 5789f594e7d5
X-Real-Ip: 10.0.1.1
```
This confirms that Traefik is successfully routing requests to your whoami application.
## Add Routing Rules
Now we'll enhance our routing by directing traffic to different services based on [URL paths](../../reference/routing-configuration/http/routing/rules-and-priority.md#path-pathprefix-and-pathregexp). This is useful for API versioning, frontend/backend separation, or organizing microservices.
Update your `docker-compose.yml` to add another service:
```yaml
# ...
# New service
whoami-api:
image: traefik/whoami
networks:
- traefik_proxy
environment:
- WHOAMI_NAME=API Service
deploy:
replicas: 2
labels:
- "traefik.enable=true"
# Path-based routing
- "traefik.http.routers.whoami-api.rule=Host(`whoami.swarm.localhost`) && PathPrefix(`/api`)"
- "traefik.http.routers.whoami-api.entrypoints=web,websecure"
- "traefik.http.routers.whoami-api.service=whoami-api-svc"
- "traefik.http.services.whoami-api-svc.loadbalancer.server.port=80"
# ...
```
Apply the changes:
```bash
docker stack deploy -c docker-compose.yml traefik
```
### Test the Path-Based Routing
Verify that different paths route to different services:
```bash
# Root path should go to the main whoami service
curl -H "Host: whoami.swarm.localhost" http://localhost/
# /api path should go to the whoami-api service
curl -H "Host: whoami.swarm.localhost" http://localhost/api
```
For the `/api` requests, you should see the response showing "API Service" in the environment variables section, confirming that your path-based routing is working correctly.
## Enable TLS
Let's secure our service with HTTPS by adding TLS. We'll start with a self-signed certificate for local development.
### Create a Self-Signed Certificate
Generate a self-signed certificate and dynamic config file to tell Traefik where the cert lives:
```bash
mkdir -p certs
# key + cert (valid for one year)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/local.key -out certs/local.crt \
-subj "/CN=*.swarm.localhost"
# dynamic config that tells Traefik where the cert lives
cat > certs/tls.yml <<'EOF'
tls:
certificates:
- certFile: /certificates/local.crt
keyFile: /certificates/local.key
EOF
```
Create a Docker config for the certificate files:
```bash
docker config create swarm-cert.crt certs/local.crt
docker config create swarm-cert.key certs/local.key
docker config create swarm-tls.yml certs/tls.yml
```
Update your `docker-compose.yml` file with the following changes:
```yaml
# Add to the Traefik command section:
command:
# ... existing commands ...
- "--entryPoints.websecure.address=:443"
- "--entryPoints.websecure.http.tls=true"
- "--providers.file.directory=/etc/traefik/dynamic"
```
```yaml
# Add to the root of your docker-compose.yml file:
configs:
swarm-cert.crt:
file: ./certs/local.crt
swarm-cert.key:
file: ./certs/local.key
swarm-tls.yml:
file: ./certs/tls.yml
```
Deploy the stack:
```bash
docker stack deploy -c docker-compose.yml traefik
```
Your browser can access https://whoami.swarm.localhost/ for the service. You'll need to accept the security warning for the self-signed certificate.
## Next Steps
Now that you've mastered the basics of exposing services with Traefik on Docker Swarm, you're ready to explore more advanced features like middlewares, Let's Encrypt certificates, sticky sessions, and multi-layer routing.
Continue to the [Advanced Guide](advanced.md) to learn about:
- Adding middlewares for security and access control
- Generating certificates with Let's Encrypt
- Configuring sticky sessions for stateful applications
- Setting up multi-layer routing for authentication-based routing

View file

@ -847,14 +847,14 @@ _Optional, Default=2160_
It defaults to `2160` (90 days) to follow Let's Encrypt certificates' duration.
| Certificate Duration | Renew Period | Renew Interval |
|----------------------|-------------------|-------------------------|
| >= 1 year | 4 months | 1 week |
| >= 90 days | 30 days | 1 day |
| >= 30 days | 10 days | 12 hours |
| >= 7 days | 1 day | 1 hour |
| >= 24 hours | 6 hours | 10 min |
| < 24 hours | 20 min | 1 min |
| Certificate Duration | Renew Period | Renew Interval |
|----------------------|--------------|----------------|
| >= 1 year | 4 months | 1 week |
| >= 90 days | 30 days | 1 day |
| >= 30 days | 10 days | 12 hours |
| >= 6 days | 2 days | 2 hours |
| >= 24 hours | 6 hours | 10 min |
| < 24 hours | 20 min | 1 min |
!!! warning "Traefik cannot manage certificates with a duration lower than 1 hour."

View file

@ -13,7 +13,7 @@ The GrpcWeb middleware converts gRPC Web requests to HTTP/2 gRPC requests before
!!! tip
Please note, that Traefik needs to communicate using gRPC with the backends (h2c or HTTP/2 over TLS).
Check out the [gRPC](../../user-guides/grpc.md) user guide for more details.
Check out [Exposing gRPC Services](../../expose/overview.md#exposing-grpc-services) for more details.
## Configuration Examples

View file

@ -636,6 +636,10 @@ The `Headers` and `HeadersRegexp` matchers have been renamed to `Header` and `He
`PathPrefix` no longer uses regular expressions to match path prefixes.
`Path` and `PathPrefix` no longer support path parameter placeholders (e.g., `{id}`, `{name}`).
Routes using placeholders like ``Path(`/route/{id}`)`` will not match in v3 syntax.
Use `PathRegexp` instead for dynamic path segments.
`QueryRegexp` has been introduced to match query values using a regular expression.
`HeaderRegexp`, `HostRegexp`, `PathRegexp`, `QueryRegexp`, and `HostSNIRegexp` matchers now uses the [Go regexp syntax](https://golang.org/pkg/regexp/syntax/).
@ -716,6 +720,40 @@ http:
ruleSyntax = "v2"
```
##### Migrate Path Placeholders to PathRegexp
In v2, `Path` and `PathPrefix` supported path parameter placeholders like `{id}` for matching dynamic path segments.
In v3, this is no longer supported and `PathRegexp` should be used instead.
??? example "Migrating a route with path placeholders"
v2 syntax (no longer works in v3):
```yaml
match: Host(`example.com`) && Path(`/products/{id}`)
```
v3 syntax using `PathRegexp`:
```yaml
match: Host(`example.com`) && PathRegexp(`^/products/[^/]+$`)
```
For more complex patterns with multiple placeholders:
v2 syntax:
```yaml
match: Host(`example.com`) && Path(`/users/{userId}/orders/{orderId}`)
```
v3 syntax:
```yaml
match: Host(`example.com`) && PathRegexp(`^/users/[^/]+/orders/[^/]+$`) ## matches any non-slash characters
match: Host(`example.com`) && PathRegexp(`^/users/[a-zA-Z0-9_-]+/orders/[a-zA-Z0-9_-]+$`) ## restricts to alphanumeric, hyphens, and underscores
```
### IPWhiteList
In v3, we renamed the `IPWhiteList` middleware to `IPAllowList` without changing anything to the configuration.

View file

@ -568,12 +568,12 @@ Here is the list of the encoded characters that are rejected by default, along w
| Encoded Character | Character | Config option to allow the encoded character |
|-------------------|-------------------------|--------------------------------------------------------------------------------------|
| `%2f` or `%2F` | `/` (slash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSlash` |
| `%5c` or `%5C` | `\` (backslash) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedBackSlash` |
| `%00` | `NULL` (null character) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedNullCharacter` |
| `%3b` or `%3B` | `;` (semicolon) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSemicolon` |
| `%25` | `%` (percent) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedPercent` |
| `%3f` or `%3F` | `?` (question mark) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedQuestionMark` |
| `%23` | `#` (hash) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedHash` |
| `%5c` or `%5C` | `\` (backslash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedBackSlash` |
| `%00` | `NULL` (null character) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedNullCharacter` |
| `%3b` or `%3B` | `;` (semicolon) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSemicolon` |
| `%25` | `%` (percent) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedPercent` |
| `%3f` or `%3F` | `?` (question mark) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedQuestionMark` |
| `%23` | `#` (hash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedHash` |
Please check out the entrypoint [encodedCharacters option](../reference/install-configuration/entrypoints.md#opt-http-encodedCharacters) documentation for more details.
@ -590,12 +590,12 @@ Here is the list of the encoded characters that can be configured to `false` to
| Encoded Character | Character | Config options | Default value |
|-------------------|-------------------------|--------------------------------------------------------------------------------------|---------------|
| `%2f` or `%2F` | `/` (slash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSlash` | `true` |
| `%5c` or `%5C` | `\` (backslash) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedBackSlash` | `true` |
| `%00` | `NULL` (null character) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedNullCharacter` | `true` |
| `%3b` or `%3B` | `;` (semicolon) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSemicolon` | `true` |
| `%25` | `%` (percent) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedPercent` | `true` |
| `%3f` or `%3F` | `?` (question mark) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedQuestionMark` | `true` |
| `%23` | `#` (hash) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedHash` | `true` |
| `%5c` or `%5C` | `\` (backslash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedBackSlash` | `true` |
| `%00` | `NULL` (null character) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedNullCharacter` | `true` |
| `%3b` or `%3B` | `;` (semicolon) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSemicolon` | `true` |
| `%25` | `%` (percent) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedPercent` | `true` |
| `%3f` or `%3F` | `?` (question mark) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedQuestionMark` | `true` |
| `%23` | `#` (hash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedHash` | `true` |
Note: This check is not done against query parameters,
but only against the request path as defined

View file

@ -42,7 +42,7 @@ metrics:
_Required, Default=""_
Token with which to connect to InfluxDB v2.
Token with which to connect to InfluxDB v2. It accepts either a token value or a file path to the token.
```yaml tab="File (YAML)"
metrics:

View file

@ -363,6 +363,6 @@ providers:
## Full Example
For additional information, refer to the [full example](../user-guides/crd-acme/index.md) with Let's Encrypt.
For additional information on exposing services with Kubernetes, refer to the [Kubernetes guide](../expose/kubernetes/basic.md).
{% include-markdown "includes/traefik-for-business-applications.md" %}

View file

@ -222,6 +222,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of
the referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -1232,6 +1251,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references to
Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -2974,6 +3012,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -3211,6 +3268,24 @@ spec:
Default value is -1, which means unlimited size.
format: int64
type: integer
middlewares:
description: Middlewares defines the list of references to Middleware
resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware resource.
properties:
name:
description: Name defines the name of the referenced Middleware
resource.
type: string
namespace:
description: Namespace defines the namespace of the referenced
Middleware resource.
type: string
required:
- name
type: object
type: array
mirrorBody:
description: |-
MirrorBody defines whether the body of the request should be mirrored.
@ -3298,6 +3373,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -3686,6 +3780,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.

View file

@ -223,6 +223,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of
the referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.

View file

@ -387,6 +387,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references to
Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.

View file

@ -131,6 +131,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -368,6 +387,24 @@ spec:
Default value is -1, which means unlimited size.
format: int64
type: integer
middlewares:
description: Middlewares defines the list of references to Middleware
resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware resource.
properties:
name:
description: Name defines the name of the referenced Middleware
resource.
type: string
namespace:
description: Namespace defines the namespace of the referenced
Middleware resource.
type: string
required:
- name
type: object
type: array
mirrorBody:
description: |-
MirrorBody defines whether the body of the request should be mirrored.
@ -455,6 +492,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -843,6 +899,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.

View file

@ -202,7 +202,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-metrics-influxdb2-bucket" href="#opt-metrics-influxdb2-bucket" title="#opt-metrics-influxdb2-bucket">metrics.influxdb2.bucket</a> | InfluxDB v2 bucket ID. | |
| <a id="opt-metrics-influxdb2-org" href="#opt-metrics-influxdb2-org" title="#opt-metrics-influxdb2-org">metrics.influxdb2.org</a> | InfluxDB v2 org ID. | |
| <a id="opt-metrics-influxdb2-pushinterval" href="#opt-metrics-influxdb2-pushinterval" title="#opt-metrics-influxdb2-pushinterval">metrics.influxdb2.pushinterval</a> | InfluxDB v2 push interval. | 10 |
| <a id="opt-metrics-influxdb2-token" href="#opt-metrics-influxdb2-token" title="#opt-metrics-influxdb2-token">metrics.influxdb2.token</a> | InfluxDB v2 access token. | |
| <a id="opt-metrics-influxdb2-token" href="#opt-metrics-influxdb2-token" title="#opt-metrics-influxdb2-token">metrics.influxdb2.token</a> | InfluxDB v2 access token. It accepts either a token value or a file path to the token. | |
| <a id="opt-metrics-otlp" href="#opt-metrics-otlp" title="#opt-metrics-otlp">metrics.otlp</a> | OpenTelemetry metrics exporter type. | false |
| <a id="opt-metrics-otlp-addentrypointslabels" href="#opt-metrics-otlp-addentrypointslabels" title="#opt-metrics-otlp-addentrypointslabels">metrics.otlp.addentrypointslabels</a> | Enable metrics on entry points. | true |
| <a id="opt-metrics-otlp-addrouterslabels" href="#opt-metrics-otlp-addrouterslabels" title="#opt-metrics-otlp-addrouterslabels">metrics.otlp.addrouterslabels</a> | Enable metrics on routers. | false |
@ -399,6 +399,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-providers-kubernetesingressnginx-endpoint" href="#opt-providers-kubernetesingressnginx-endpoint" title="#opt-providers-kubernetesingressnginx-endpoint">providers.kubernetesingressnginx.endpoint</a> | Kubernetes server endpoint (required for external cluster client). | |
| <a id="opt-providers-kubernetesingressnginx-ingressclass" href="#opt-providers-kubernetesingressnginx-ingressclass" title="#opt-providers-kubernetesingressnginx-ingressclass">providers.kubernetesingressnginx.ingressclass</a> | Name of the ingress class this controller satisfies. | nginx |
| <a id="opt-providers-kubernetesingressnginx-ingressclassbyname" href="#opt-providers-kubernetesingressnginx-ingressclassbyname" title="#opt-providers-kubernetesingressnginx-ingressclassbyname">providers.kubernetesingressnginx.ingressclassbyname</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false |
| <a id="opt-providers-kubernetesingressnginx-proxyconnecttimeout" href="#opt-providers-kubernetesingressnginx-proxyconnecttimeout" title="#opt-providers-kubernetesingressnginx-proxyconnecttimeout">providers.kubernetesingressnginx.proxyconnecttimeout</a> | Amount of time to wait until a connection to a server can be established. Timeout value is unitless and in seconds. | 60 |
| <a id="opt-providers-kubernetesingressnginx-publishservice" href="#opt-providers-kubernetesingressnginx-publishservice" title="#opt-providers-kubernetesingressnginx-publishservice">providers.kubernetesingressnginx.publishservice</a> | Service fronting the Ingress controller. Takes the form 'namespace/name'. | |
| <a id="opt-providers-kubernetesingressnginx-publishstatusaddress" href="#opt-providers-kubernetesingressnginx-publishstatusaddress" title="#opt-providers-kubernetesingressnginx-publishstatusaddress">providers.kubernetesingressnginx.publishstatusaddress</a> | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | |
| <a id="opt-providers-kubernetesingressnginx-throttleduration" href="#opt-providers-kubernetesingressnginx-throttleduration" title="#opt-providers-kubernetesingressnginx-throttleduration">providers.kubernetesingressnginx.throttleduration</a> | Ingress refresh throttle duration. | 0 |

View file

@ -1,19 +1,18 @@
---
title: "Traefik FastProxy Experimental Configuration"
description: "This section of the Traefik Proxy documentation explains how to use the new FastProxy option."
description: "This section of the Traefik Proxy documentation explains how to use the new FastProxy install configuration option."
---
# Traefik FastProxy Experimental Configuration
## Overview
This guide provides instructions on how to configure and use the new experimental `fastProxy` static configuration option in Traefik.
The `fastProxy` option introduces a high-performance reverse proxy designed to enhance the performance of routing.
This guide provides instructions on how to configure and use the new experimental `fastProxy` install configuration option in Traefik. The `fastProxy` option introduces a high-performance reverse proxy designed to enhance the performance of routing.
!!! info "Limitations"
Please note that the new fast proxy implementation does not work with HTTP/2.
This means that when a H2C or HTTPS request with [HTTP2 enabled](../routing/services/index.md#disablehttp2) is sent to a backend, the fallback proxy is the regular one.
This means that when a H2C or HTTPS request with [HTTP2 enabled](../../routing-configuration/http/load-balancing/service.md#disablehttp2) is sent to a backend, the fallback proxy is the regular one.
Additionnaly, observability features like tracing and OTEL semconv metrics are not supported for the moment.
@ -22,10 +21,10 @@ The `fastProxy` option introduces a high-performance reverse proxy designed to e
The `fastProxy` option is currently experimental and subject to change in future releases.
Use with caution in production environments.
### Enabling FastProxy
## Enabling FastProxy
The fastProxy option is a static configuration parameter.
To enable it, you need to configure it in your Traefik static configuration
The fastProxy option is an install configuration parameter.
To enable it, you need to configure it in your Traefik install configuration
```yaml tab="File (YAML)"
experimental:

View file

@ -0,0 +1,43 @@
---
title: "Traefik Plugins Experimental Configuration"
description: "This section of the Traefik Proxy documentation explains how to use the new Plugins install configuration option."
---
# Traefik Plugins Experimental Configuration
## Overview
This guide provides instructions on how to configure and use the new experimental `plugins` install configuration option in Traefik. The `plugins` option introduces a system to extend Traefik capabilities with custom middlewares and providers.
!!! warning "Experimental"
The `plugins` option is currently experimental and subject to change in future releases.
Use with caution in production environments.
## Enabling Plugins
The plugins option is an install configuration parameter.
To enable a plugin, you need to define it in your Traefik install configuration
```yaml tab="File (YAML)"
experimental:
plugins:
plugin-name: # The name of the plugin in the routing configuration
moduleName: "github.com/github-organization/github-repository" # The plugin module name
version: "vX.XX.X" # The version to use
```
```toml tab="File (TOML)"
[experimental.plugins.plugin-name]
moduleName = "github.com/github-organization/github-repository" # The plugin module name
version = "vX.XX.X" # The version to use
```
```bash tab="CLI"
# The plugin module name
# With plugin-name the name of the plugin in the routing configuration
--experimental.plugins.plugin-name.modulename=github.com/github-organization/github-repository
--experimental.plugins.plugin-name.version=vX.XX.X # The version to use
```
To learn more about how to add a new plugin to a Traefik instance, please refer to the [developer documentation](https://plugins.traefik.io/install).

View file

@ -128,6 +128,6 @@ See the dedicated section in [routing](../../../../routing/providers/kubernetes-
## Full Example
For additional information, refer to the [full example](../../../../user-guides/crd-acme/index.md) with Let's Encrypt.
For additional information on exposing services with Kubernetes, refer to the [Kubernetes guide](../../../../expose/kubernetes/basic.md).
{% include-markdown "includes/traefik-for-business-applications.md" %}

View file

@ -114,23 +114,24 @@ This provider watches for incoming Ingress events and automatically translates N
## Configuration Options
<!-- markdownlint-disable MD013 -->
| Field | Description | Default | Required |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------|:--------|:---------|
| <a id="opt-providers-providers-ThrottleDuration" href="#opt-providers-providers-ThrottleDuration" title="#opt-providers-providers-ThrottleDuration">`providers.providers`<br/>`ThrottleDuration`</a> | 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 |
| <a id="opt-providers-kubernetesIngressNGINX-endpoint" href="#opt-providers-kubernetesIngressNGINX-endpoint" title="#opt-providers-kubernetesIngressNGINX-endpoint">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`endpoint`</a> | Server endpoint URL.<br />More information [here](#endpoint). | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-token" href="#opt-providers-kubernetesIngressNGINX-token" title="#opt-providers-kubernetesIngressNGINX-token">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`token`</a> | Bearer token used for the Kubernetes client configuration. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-certAuthFilePath" href="#opt-providers-kubernetesIngressNGINX-certAuthFilePath" title="#opt-providers-kubernetesIngressNGINX-certAuthFilePath">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`certAuthFilePath`</a> | Path to the certificate authority file.<br />Used for the Kubernetes client configuration. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-throttleDuration" href="#opt-providers-kubernetesIngressNGINX-throttleDuration" title="#opt-providers-kubernetesIngressNGINX-throttleDuration">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`throttleDuration`</a> | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.<br />This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.<br />If empty, every event is caught. | 0s | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespace" href="#opt-providers-kubernetesIngressNGINX-watchNamespace" title="#opt-providers-kubernetesIngressNGINX-watchNamespace">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespace`</a> | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" href="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" title="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespaceSelector`</a> | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-ingressClass" href="#opt-providers-kubernetesIngressNGINX-ingressClass" title="#opt-providers-kubernetesIngressNGINX-ingressClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClass`</a> | Name of the ingress class this controller satisfies. | "nginx" | No |
| <a id="opt-providers-kubernetesIngressNGINX-controllerClass" href="#opt-providers-kubernetesIngressNGINX-controllerClass" title="#opt-providers-kubernetesIngressNGINX-controllerClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`controllerClass`</a> | Ingress Class Controller value this controller satisfies. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" href="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" title="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchIngressWithoutClass`</a> | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-ingressClassByName" href="#opt-providers-kubernetesIngressNGINX-ingressClassByName" title="#opt-providers-kubernetesIngressNGINX-ingressClassByName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClassByName`</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-publishService" href="#opt-providers-kubernetesIngressNGINX-publishService" title="#opt-providers-kubernetesIngressNGINX-publishService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishService`</a> | Service fronting the Ingress controller. Takes the form `namespace/name`. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-publishStatusAddress" href="#opt-providers-kubernetesIngressNGINX-publishStatusAddress" title="#opt-providers-kubernetesIngressNGINX-publishStatusAddress">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishStatusAddress`</a> | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-defaultBackendService" href="#opt-providers-kubernetesIngressNGINX-defaultBackendService" title="#opt-providers-kubernetesIngressNGINX-defaultBackendService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`defaultBackendService`</a> | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-disableSvcExternalName" href="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName" title="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`disableSvcExternalName`</a> | Disable support for Services of type ExternalName. | false | No |
| Field | Description | Default | Required |
|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------|:---------|
| <a id="opt-providers-providers-ThrottleDuration" href="#opt-providers-providers-ThrottleDuration" title="#opt-providers-providers-ThrottleDuration">`providers.providers`<br/>`ThrottleDuration`</a> | 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 |
| <a id="opt-providers-kubernetesIngressNGINX-endpoint" href="#opt-providers-kubernetesIngressNGINX-endpoint" title="#opt-providers-kubernetesIngressNGINX-endpoint">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`endpoint`</a> | Server endpoint URL.<br />More information [here](#endpoint). | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-token" href="#opt-providers-kubernetesIngressNGINX-token" title="#opt-providers-kubernetesIngressNGINX-token">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`token`</a> | Bearer token used for the Kubernetes client configuration. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-certAuthFilePath" href="#opt-providers-kubernetesIngressNGINX-certAuthFilePath" title="#opt-providers-kubernetesIngressNGINX-certAuthFilePath">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`certAuthFilePath`</a> | Path to the certificate authority file.<br />Used for the Kubernetes client configuration. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-throttleDuration" href="#opt-providers-kubernetesIngressNGINX-throttleDuration" title="#opt-providers-kubernetesIngressNGINX-throttleDuration">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`throttleDuration`</a> | Minimum amount of time to wait between two Kubernetes events before producing a new configuration.<br />This prevents a Kubernetes cluster that updates many times per second from continuously changing your Traefik configuration.<br />If empty, every event is caught. | 0s | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespace" href="#opt-providers-kubernetesIngressNGINX-watchNamespace" title="#opt-providers-kubernetesIngressNGINX-watchNamespace">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespace`</a> | Namespace the controller watches for updates to Kubernetes objects. All namespaces are watched if this parameter is left empty. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" href="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector" title="#opt-providers-kubernetesIngressNGINX-watchNamespaceSelector">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchNamespaceSelector`</a> | Selector selects namespaces the controller watches for updates to Kubernetes objects. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-ingressClass" href="#opt-providers-kubernetesIngressNGINX-ingressClass" title="#opt-providers-kubernetesIngressNGINX-ingressClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClass`</a> | Name of the ingress class this controller satisfies. | "nginx" | No |
| <a id="opt-providers-kubernetesIngressNGINX-controllerClass" href="#opt-providers-kubernetesIngressNGINX-controllerClass" title="#opt-providers-kubernetesIngressNGINX-controllerClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`controllerClass`</a> | Ingress Class Controller value this controller satisfies. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" href="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass" title="#opt-providers-kubernetesIngressNGINX-watchIngressWithoutClass">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`watchIngressWithoutClass`</a> | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-ingressClassByName" href="#opt-providers-kubernetesIngressNGINX-ingressClassByName" title="#opt-providers-kubernetesIngressNGINX-ingressClassByName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`ingressClassByName`</a> | Define if Ingress Controller should watch for Ingress Class by Name together with Controller Class. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-publishService" href="#opt-providers-kubernetesIngressNGINX-publishService" title="#opt-providers-kubernetesIngressNGINX-publishService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishService`</a> | Service fronting the Ingress controller. Takes the form `namespace/name`. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-publishStatusAddress" href="#opt-providers-kubernetesIngressNGINX-publishStatusAddress" title="#opt-providers-kubernetesIngressNGINX-publishStatusAddress">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`publishStatusAddress`</a> | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-defaultBackendService" href="#opt-providers-kubernetesIngressNGINX-defaultBackendService" title="#opt-providers-kubernetesIngressNGINX-defaultBackendService">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`defaultBackendService`</a> | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form 'namespace/name'. | "" | No |
| <a id="opt-providers-kubernetesIngressNGINX-disableSvcExternalName" href="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName" title="#opt-providers-kubernetesIngressNGINX-disableSvcExternalName">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`disableSvcExternalName`</a> | Disable support for Services of type ExternalName. | false | No |
| <a id="opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" href="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout" title="#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout">`providers.`<br/>`kubernetesIngressNGINX.`<br/>`proxyConnectTimeout`</a> | Amount of time to wait until a connection to a server can be established. The value is unitless and in seconds. This is used as the global connection timeout when no ingress-specific timeout is configured. An ingress-specific timeout can be configured using [`nginx.ingress.kubernetes.io/proxy-connect-timeout`](../../../../routing-configuration/kubernetes/ingress-nginx/#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout) annotation. | 60 | No |
<!-- markdownlint-enable MD013 -->

View file

@ -4,14 +4,23 @@ description: "A service is in charge of connecting incoming requests to the Serv
---
Traefik services define how to distribute incoming traffic across your backend servers.
Each service implements one of the load balancing strategies detailed on this page to ensure optimal traffic distribution and high availability.
This page covers two main concepts:
- **Service Load Balancer**: Routes traffic to backend servers using various load balancing strategies
- **Advanced Service Types**: Compose multiple services together for weighted distribution, mirroring, or failover
## Service Load Balancer
The load balancers are able to load balance the requests between multiple instances of your programs.
The `loadBalancer` service type routes incoming requests to a list of backend servers.
Each service has a load-balancer, even if there is only one server to forward traffic to.
The load balancer supports multiple **strategies** for distributing traffic among servers:
- `wrr` (Weighted Round Robin) - Default strategy, distributes requests evenly across servers in rotation
- `p2c` (Power of Two Choices) - Selects two random servers and routes to the one with fewer active connections
- `hrw` (Highest Random Weight) - Uses consistent hashing based on client IP for session affinity
- `leasttime` - Routes to the server with lowest response time combined with fewest active connections
### Configuration Example
```yaml tab="Structured (YAML)"
@ -19,6 +28,7 @@ http:
services:
my-service:
loadBalancer:
strategy: "wrr"
servers:
- url: "http://private-ip-server-1/"
weight: 2
@ -42,6 +52,7 @@ http:
```toml tab="Structured (TOML)"
[http.services]
[http.services.my-service.loadBalancer]
strategy = "wrr"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
@ -66,6 +77,7 @@ http:
```yaml tab="Labels"
labels:
- "traefik.http.services.my-service.loadBalancer.strategy=wrr"
- "traefik.http.services.my-service.loadBalancer.servers[0].url=http://private-ip-server-1/"
- "traefik.http.services.my-service.loadBalancer.servers[0].weight=2"
- "traefik.http.services.my-service.loadBalancer.servers[0].preservePath=true"
@ -83,6 +95,7 @@ labels:
```json tab="Tags"
{
"Tags": [
"traefik.http.services.my-service.loadBalancer.strategy=wrr",
"traefik.http.services.my-service.loadBalancer.servers[0].url=http://private-ip-server-1/",
"traefik.http.services.my-service.loadBalancer.servers[0].weight=2",
"traefik.http.services.my-service.loadBalancer.servers[0].preservePath=true",
@ -104,6 +117,7 @@ labels:
| Field | Description | Required |
|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|
| <a id="opt-servers" href="#opt-servers" title="#opt-servers">`servers`</a> | Represents individual backend instances for your service | Yes |
| <a id="opt-strategy" href="#opt-strategy" title="#opt-strategy">`strategy`</a> | Load balancing strategy for distributing traffic among servers. Valid values: `wrr` (default), `p2c`, `hrw`, `leasttime`. | No |
| <a id="opt-sticky" href="#opt-sticky" title="#opt-sticky">`sticky`</a> | Defines a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response. | No |
| <a id="opt-healthcheck" href="#opt-healthcheck" title="#opt-healthcheck">`healthcheck`</a> | Configures health check to remove unhealthy servers from the load balancing rotation. | No |
| <a id="opt-passiveHealthcheck" href="#opt-passiveHealthcheck" title="#opt-passiveHealthcheck">`passiveHealthcheck`</a> | Configures the passive health check to remove unhealthy servers from the load balancing rotation. | No |
@ -124,7 +138,151 @@ Servers represent individual backend instances for your service. The [service lo
| <a id="opt-weight" href="#opt-weight" title="#opt-weight">`weight`</a> | Allows for weighted load balancing on the servers. | No |
| <a id="opt-preservePath" href="#opt-preservePath" title="#opt-preservePath">`preservePath`</a> | Allows to preserve the URL path. | No |
#### Health Check
### Load Balancing Strategies
The `strategy` option on the load balancer determines how traffic is distributed among the backend servers.
#### Weighted Round Robin (wrr)
The default strategy. Distributes requests evenly across all servers in rotation, respecting server weights.
This strategy uses Earliest Deadline First (EDF) scheduling to provide weighted round-robin behavior.
??? example "WRR Load Balancing -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Routing configuration
http:
services:
my-service:
loadBalancer:
strategy: "wrr"
servers:
- url: "http://private-ip-server-1/"
weight: 3
- url: "http://private-ip-server-2/"
weight: 1
```
```toml tab="Structured (TOML)"
## Routing configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "wrr"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
weight = 3
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
weight = 1
```
#### Power of Two Choices (p2c)
Selects two servers at random and routes the request to the one with the fewest active connections.
This algorithm provides better load distribution when servers have varying response times.
??? example "P2C Load Balancing -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Routing configuration
http:
services:
my-service:
loadBalancer:
strategy: "p2c"
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
```
```toml tab="Structured (TOML)"
## Routing configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "p2c"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
```
#### Highest Random Weight (hrw)
Uses consistent hashing (Rendezvous Hashing) based on the client's IP address to ensure requests from the same client are consistently routed to the same server.
This provides session affinity without requiring sticky cookies.
The algorithm computes a score for each available backend using a hash of the client's source IP combined with the backend's identifier, and assigns the client to the backend with the highest score.
??? example "HRW Load Balancing -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Routing configuration
http:
services:
my-service:
loadBalancer:
strategy: "hrw"
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
```
```toml tab="Structured (TOML)"
## Routing configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "hrw"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
```
#### Least-Time
Selects the server with the lowest average response time (Time To First Byte - TTFB), combined with the fewest active connections, weighted by server capacity.
This strategy is ideal for heterogeneous backend environments where servers have varying performance characteristics, different hardware capabilities, or varying network latency.
The algorithm continuously measures each backend's response time and tracks active connection counts.
When routing a request, it calculates a score for each healthy server using the formula: `(avg_response_time × (1 + active_connections)) / weight`.
The server with the lowest score receives the request.
When multiple servers have identical scores, Weighted Round Robin (WRR) with Earliest Deadline First (EDF) scheduling is used as a tie-breaker.
??? example "Least-Time Load Balancing -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Routing configuration
http:
services:
my-service:
loadBalancer:
strategy: "leasttime"
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
```
```toml tab="Structured (TOML)"
## Routing configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "leasttime"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
```
### Health Check
The `healthcheck` option configures health check to remove unhealthy servers from the load balancing rotation.
Traefik will consider HTTP(s) servers healthy as long as they return a status code to the health check request (carried out every interval) between `2XX` and `3XX`, or matching the configured status.
@ -146,42 +304,41 @@ Below are the available options for the health check mechanism:
| <a id="opt-timeout" href="#opt-timeout" title="#opt-timeout">`timeout`</a> | Defines the maximum duration Traefik will wait for a health check request before considering the server unhealthy. | 5s | No |
| <a id="opt-headers" href="#opt-headers" title="#opt-headers">`headers`</a> | Defines custom headers to be sent to the health check endpoint. | | No |
| <a id="opt-followRedirects" href="#opt-followRedirects" title="#opt-followRedirects">`followRedirects`</a> | Defines whether redirects should be followed during the health check calls. | true | No |
| <a id="opt-hostname-2" href="#opt-hostname-2" title="#opt-hostname-2">`hostname`</a> | Defines the value of hostname in the Host header of the health check request. | "" | No |
| <a id="opt-method" href="#opt-method" title="#opt-method">`method`</a> | Defines the HTTP method that will be used while connecting to the endpoint. | GET | No |
| <a id="opt-status" href="#opt-status" title="#opt-status">`status`</a> | Defines the expected HTTP status code of the response to the health check request. | | No |
#### Sticky sessions
### Sticky Sessions
When sticky sessions are enabled, a `Set-Cookie` header is set on the initial response to let the client know which server handles the first response.
On subsequent requests, to keep the session alive with the same server, the client should send the cookie with the value set.
##### Stickiness on multiple levels
#### Stickiness on multiple levels
When chaining or mixing load-balancers (e.g. a load-balancer of servers is one of the "children" of a load-balancer of services), for stickiness to work all the way, the option needs to be specified at all required levels. Which means the client needs to send a cookie with as many key/value pairs as there are sticky levels.
##### Stickiness & Unhealthy Servers
#### Stickiness & Unhealthy Servers
If the server specified in the cookie becomes unhealthy, the request will be forwarded to a new server (and the cookie will keep track of the new server).
##### Cookie Name
#### Cookie Name
The default cookie name is an abbreviation of a sha1 (ex: `_1d52e`).
##### MaxAge
#### MaxAge
By default, the affinity cookie will never expire as the `MaxAge` option is set to zero.
This option indicates the number of seconds until the cookie expires.
When set to a negative number, the cookie expires immediately.
##### Secure & HTTPOnly & SameSite flags
#### Secure & HTTPOnly & SameSite flags
By default, the affinity cookie is created without those flags.
One however can change that through configuration.
`SameSite` can be `none`, `lax`, `strict` or empty.
##### Domain
#### Domain
The Domain attribute of a cookie specifies the domain for which the cookie is valid.
@ -190,7 +347,7 @@ By setting the Domain attribute, the cookie can be shared across subdomains (for
??? example "Adding Stickiness -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
my-service:
@ -200,7 +357,7 @@ By setting the Domain attribute, the cookie can be shared across subdomains (for
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.my-service]
[http.services.my-service.loadBalancer.sticky.cookie]
@ -209,7 +366,7 @@ By setting the Domain attribute, the cookie can be shared across subdomains (for
??? example "Adding Stickiness with custom Options -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
my-service:
@ -223,7 +380,7 @@ By setting the Domain attribute, the cookie can be shared across subdomains (for
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.my-service]
[http.services.my-service.loadBalancer.sticky.cookie]
@ -237,7 +394,7 @@ By setting the Domain attribute, the cookie can be shared across subdomains (for
??? example "Setting Stickiness on all the required levels -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
wrr1:
@ -271,7 +428,7 @@ By setting the Domain attribute, the cookie can be shared across subdomains (for
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.wrr1]
[http.services.wrr1.weighted.sticky.cookie]
@ -308,7 +465,7 @@ To keep a session open with the same server, the client would then need to speci
curl -b "lvl1=whoami1; lvl2=http://127.0.0.1:8081" http://localhost:8000
```
#### Passive Health Check
### Passive Health Check
The `passiveHealthcheck` option configures passive health check to remove unhealthy servers from the load balancing rotation.
@ -326,18 +483,27 @@ Below are the available options for the passive health check mechanism:
| <a id="opt-failureWindow" href="#opt-failureWindow" title="#opt-failureWindow">`failureWindow`</a> | Defines the time window during which the failed attempts must occur for the server to be marked as unhealthy. It also defines for how long the server will be considered unhealthy. | 10s | No |
| <a id="opt-maxFailedAttempts" href="#opt-maxFailedAttempts" title="#opt-maxFailedAttempts">`maxFailedAttempts`</a> | Defines the number of consecutive failed attempts allowed within the failure window before marking the server as unhealthy. | 1 | No |
## Weighted Round Robin (WRR)
## Advanced Service Types
The WRR is able to load balance the requests between multiple services based on weights.
Advanced service types allow you to compose multiple services together for weighted distribution, consistent hashing, mirroring, or failover scenarios.
These are distinct from load balancing strategies - they operate at the **service level** rather than the **server level**.
This strategy is only available to load balance between services and not between servers.
!!! info "Key Difference"
- **Load Balancing Strategies** (wrr, p2c, hrw, leasttime): Distribute traffic among **servers** within a single `loadBalancer` service
- **Advanced Service Types** (weighted, highestRandomWeight, mirroring, failover): Distribute or manage traffic among multiple **services**
### Weighted Round robin
The `weighted` service type load balances requests between multiple services based on weights.
This is different from the `wrr` strategy - it operates on services, not servers.
!!! 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-crd.md) providers. To load balance between servers based on weights, the Load Balancer service should be used instead.
This service type can be defined currently with the [File](../../../install-configuration/providers/others/file.md) provider or [IngressRoute](../../../routing-configuration/kubernetes/crd/http/ingressroute.md).
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
app:
@ -360,7 +526,7 @@ http:
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.app]
[[http.services.app.weighted.services]]
@ -381,7 +547,7 @@ http:
url = "http://private-ip-server-2/"
```
### Health Check
#### Health Check
HealthCheck enables automatic self-healthcheck for this service, i.e. whenever one of its children is reported as down, this service becomes aware of it, and takes it into account (i.e. it ignores the down child) when running the load-balancing algorithm. In addition, if the parent of this service also has HealthCheck enabled, this service reports to its parent any status change.
@ -392,7 +558,7 @@ HealthCheck enables automatic self-healthcheck for this service, i.e. whenever o
HealthCheck on Weighted services can be defined currently only with the [File provider](../../../install-configuration/providers/others/file.md).
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
app:
@ -424,7 +590,7 @@ http:
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.app]
[http.services.app.weighted.healthCheck]
@ -454,83 +620,138 @@ http:
url = "http://private-ip-server-2/"
```
## P2C
### Highest Random Weight
Power of two choices algorithm is a load balancing strategy that selects two servers at random and chooses the one with the least number of active requests.
The `highestRandomWeight` service type uses consistent hashing (Rendezvous Hashing) to load balance requests between multiple services.
This ensures that requests from the same client IP are consistently routed to the same service.
??? example "P2C Load Balancing -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
This is different from the `hrw` strategy on a loadBalancer - it operates on **services**, not servers.
```yaml tab="Structured (YAML)"
## Dynamic configuration
http:
services:
my-service:
loadBalancer:
strategy: "p2c"
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
```
!!! info "Supported Providers"
```toml tab="Structured (TOML) "
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "p2c"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
```
This service type can be defined currently only with the [File](../../../install-configuration/providers/others/file.md) provider.
## Least-Time
```yaml tab="Structured (YAML)"
## Routing configuration
http:
services:
app:
highestRandomWeight:
services:
- name: appv1
weight: 1
- name: appv2
weight: 1
The Least-Time load balancing algorithm selects the server with the lowest average response time (Time To First Byte - TTFB),
combined with the fewest active connections, weighted by server capacity.
This strategy is ideal for heterogeneous backend environments where servers have varying performance characteristics,
different hardware capabilities, or varying network latency.
appv1:
loadBalancer:
servers:
- url: "http://private-ip-server-1/"
The algorithm continuously measures each backend's response time and tracks active connection counts.
When routing a request,
it calculates a score for each healthy server using the formula: `(avg_response_time × (1 + active_connections)) / weight`.
The server with the lowest score receives the request.
When multiple servers have identical scores,
Weighted Round Robin (WRR) with Earliest Deadline First (EDF) scheduling is used as a tie-breaker to ensure fair distribution.
appv2:
loadBalancer:
servers:
- url: "http://private-ip-server-2/"
```
??? example "Basic Least-Time Load Balancing -- Using the [File Provider](../../../install-configuration/providers/others/file.md)"
```toml tab="Structured (TOML)"
## Routing configuration
[http.services]
[http.services.app]
[[http.services.app.highestRandomWeight.services]]
name = "appv1"
weight = 1
[[http.services.app.highestRandomWeight.services]]
name = "appv2"
weight = 1
```yaml tab="Structured (YAML)"
## Dynamic configuration
http:
services:
my-service:
loadBalancer:
strategy: "leasttime"
servers:
- url: "http://private-ip-server-1/"
- url: "http://private-ip-server-2/"
- url: "http://private-ip-server-3/"
```
[http.services.appv1]
[http.services.appv1.loadBalancer]
[[http.services.appv1.loadBalancer.servers]]
url = "http://private-ip-server-1/"
```toml tab="Structured (TOML)"
## Dynamic configuration
[http.services]
[http.services.my-service.loadBalancer]
strategy = "leasttime"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-2/"
[[http.services.my-service.loadBalancer.servers]]
url = "http://private-ip-server-3/"
```
[http.services.appv2]
[http.services.appv2.loadBalancer]
[[http.services.appv2.loadBalancer.servers]]
url = "http://private-ip-server-2/"
```
## Mirroring
#### Health Check
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.
HealthCheck enables automatic self-healthcheck for this service, similar to the Weighted Round Robin service type.
!!! note "Behavior"
If HealthCheck is enabled for a given service and any of its descendants does not have it enabled, the creation of the service will fail.
HealthCheck on Highest Random Weight services can be defined currently only with the [File provider](../../../install-configuration/providers/others/file.md).
```yaml tab="Structured (YAML)"
## Routing configuration
http:
services:
app:
highestRandomWeight:
healthCheck: {}
services:
- name: appv1
weight: 1
- name: appv2
weight: 1
appv1:
loadBalancer:
healthCheck:
path: /status
interval: 10s
timeout: 3s
servers:
- url: "http://private-ip-server-1/"
appv2:
loadBalancer:
healthCheck:
path: /status
interval: 10s
timeout: 3s
servers:
- url: "http://private-ip-server-2/"
```
```toml tab="Structured (TOML)"
## Routing configuration
[http.services]
[http.services.app]
[http.services.app.highestRandomWeight.healthCheck]
[[http.services.app.highestRandomWeight.services]]
name = "appv1"
weight = 1
[[http.services.app.highestRandomWeight.services]]
name = "appv2"
weight = 1
[http.services.appv1]
[http.services.appv1.loadBalancer]
[http.services.appv1.loadBalancer.healthCheck]
path = "/health"
interval = "10s"
timeout = "3s"
[[http.services.appv1.loadBalancer.servers]]
url = "http://private-ip-server-1/"
[http.services.appv2]
[http.services.appv2.loadBalancer]
[http.services.appv2.loadBalancer.healthCheck]
path = "/health"
interval = "10s"
timeout = "3s"
[[http.services.appv2.loadBalancer.servers]]
url = "http://private-ip-server-2/"
```
### Mirroring
The `mirroring` service type mirrors 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`"
@ -538,10 +759,10 @@ The mirroring is able to mirror requests sent to a service to other services. Pl
!!! 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-crd.md) providers.
This service type can be defined currently with the [File](../../../install-configuration/providers/others/file.md) provider or [IngressRoute](../../../routing-configuration/kubernetes/crd/http/ingressroute.md).
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
mirrored-api:
@ -572,7 +793,7 @@ http:
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.mirrored-api]
[http.services.mirrored-api.mirroring]
@ -599,7 +820,7 @@ http:
url = "http://private-ip-server-2/"
```
### Health Check
#### Health Check
HealthCheck enables automatic self-healthcheck for this service, i.e. if the main handler of the service becomes unreachable, the information is propagated upwards to its parent.
@ -610,7 +831,7 @@ HealthCheck enables automatic self-healthcheck for this service, i.e. if the mai
HealthCheck on Mirroring services can be defined currently only with the [File provider](../../../install-configuration/providers/others/file.md).
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
mirrored-api:
@ -637,7 +858,7 @@ http:
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.mirrored-api]
[http.services.mirrored-api.mirroring]
@ -658,7 +879,7 @@ http:
[http.services.appv2]
[http.services.appv2.loadBalancer]
[http.services.appv1.loadBalancer.healthCheck]
[http.services.appv2.loadBalancer.healthCheck]
path = "/health"
interval = "10s"
timeout = "3s"
@ -666,17 +887,17 @@ http:
url = "http://private-ip-server-2/"
```
## Failover
### Failover
A failover service job is to forward all requests to a fallback service when the main service becomes unreachable.
The `failover` service type forwards all requests to a fallback service when the main service becomes unreachable.
!!! info "Relation to HealthCheck"
The failover service relies on the HealthCheck system to get notified when its main service becomes unreachable, which means HealthCheck needs to be enabled and functional on the main service. However, HealthCheck does not need to be enabled on the failover service itself for it to be functional. It is only required in order to propagate upwards the information when the failover itself becomes down (i.e. both its main and its fallback are down too).
!!! info "Supported Provider"
This strategy can currently only be defined with the [File](../../../install-configuration/providers/others/file.md) provider.
This service type can currently only be defined with the [File](../../../install-configuration/providers/others/file.md) provider.
### HealthCheck
#### HealthCheck
HealthCheck enables automatic self-healthcheck for this service, i.e. if the main and the fallback services become unreachable, the information is propagated upwards to its parent.
@ -687,7 +908,7 @@ HealthCheck enables automatic self-healthcheck for this service, i.e. if the mai
HealthCheck on a Failover service can be defined currently only with the [File provider](../../../install-configuration/providers/others/file.md).
```yaml tab="Structured (YAML)"
## Dynamic configuration
## Routing configuration
http:
services:
app:
@ -716,7 +937,7 @@ http:
```
```toml tab="Structured (TOML)"
## Dynamic configuration
## Routing configuration
[http.services]
[http.services.app]
[http.services.app.failover.healthCheck]

View file

@ -8,7 +8,7 @@ The `grpcWeb` middleware converts gRPC Web requests to HTTP/2 gRPC requests befo
!!! tip
Please note, that Traefik needs to communicate using gRPC with the backends (h2c or HTTP/2 over TLS).
Check out the [gRPC](../../../../user-guides/grpc.md) user guide for more details.
Check out [Exposing gRPC Services](../../../../expose/overview.md#exposing-grpc-services) for more details.
## Configuration Examples

View file

@ -254,27 +254,30 @@ The following annotations are organized by category for easier navigation.
### Authentication
| Annotation | Limitations / Notes |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioauth-type" href="#opt-nginx-ingress-kubernetes-ioauth-type" title="#opt-nginx-ingress-kubernetes-ioauth-type">`nginx.ingress.kubernetes.io/auth-type`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-secret" href="#opt-nginx-ingress-kubernetes-ioauth-secret" title="#opt-nginx-ingress-kubernetes-ioauth-secret">`nginx.ingress.kubernetes.io/auth-secret`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-secret-type" href="#opt-nginx-ingress-kubernetes-ioauth-secret-type" title="#opt-nginx-ingress-kubernetes-ioauth-secret-type">`nginx.ingress.kubernetes.io/auth-secret-type`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-realm" href="#opt-nginx-ingress-kubernetes-ioauth-realm" title="#opt-nginx-ingress-kubernetes-ioauth-realm">`nginx.ingress.kubernetes.io/auth-realm`</a> | |
| Annotation | Limitations / Notes |
|-------------------------------------------------------|-------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioauth-type" href="#opt-nginx-ingress-kubernetes-ioauth-type" title="#opt-nginx-ingress-kubernetes-ioauth-type">`nginx.ingress.kubernetes.io/auth-type`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-secret" href="#opt-nginx-ingress-kubernetes-ioauth-secret" title="#opt-nginx-ingress-kubernetes-ioauth-secret">`nginx.ingress.kubernetes.io/auth-secret`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-secret-type" href="#opt-nginx-ingress-kubernetes-ioauth-secret-type" title="#opt-nginx-ingress-kubernetes-ioauth-secret-type">`nginx.ingress.kubernetes.io/auth-secret-type`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-realm" href="#opt-nginx-ingress-kubernetes-ioauth-realm" title="#opt-nginx-ingress-kubernetes-ioauth-realm">`nginx.ingress.kubernetes.io/auth-realm`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-url" href="#opt-nginx-ingress-kubernetes-ioauth-url" title="#opt-nginx-ingress-kubernetes-ioauth-url">`nginx.ingress.kubernetes.io/auth-url`</a> | Only URL and response headers copy supported. Forward auth behaves differently than NGINX. |
| <a id="opt-nginx-ingress-kubernetes-ioauth-method" href="#opt-nginx-ingress-kubernetes-ioauth-method" title="#opt-nginx-ingress-kubernetes-ioauth-method">`nginx.ingress.kubernetes.io/auth-method`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-response-headers" href="#opt-nginx-ingress-kubernetes-ioauth-response-headers" title="#opt-nginx-ingress-kubernetes-ioauth-response-headers">`nginx.ingress.kubernetes.io/auth-response-headers`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-signin" href="#opt-nginx-ingress-kubernetes-ioauth-signin" title="#opt-nginx-ingress-kubernetes-ioauth-signin">`nginx.ingress.kubernetes.io/auth-signin`</a> | Redirects to signin URL on 401 response. |
| <a id="opt-nginx-ingress-kubernetes-ioauth-method" href="#opt-nginx-ingress-kubernetes-ioauth-method" title="#opt-nginx-ingress-kubernetes-ioauth-method">`nginx.ingress.kubernetes.io/auth-method`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-response-headers" href="#opt-nginx-ingress-kubernetes-ioauth-response-headers" title="#opt-nginx-ingress-kubernetes-ioauth-response-headers">`nginx.ingress.kubernetes.io/auth-response-headers`</a> | |
### SSL/TLS
| Annotation | Limitations / Notes |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-iossl-redirect" href="#opt-nginx-ingress-kubernetes-iossl-redirect" title="#opt-nginx-ingress-kubernetes-iossl-redirect">`nginx.ingress.kubernetes.io/ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
| <a id="opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" href="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" title="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect">`nginx.ingress.kubernetes.io/force-ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
| <a id="opt-nginx-ingress-kubernetes-iossl-passthrough" href="#opt-nginx-ingress-kubernetes-iossl-passthrough" title="#opt-nginx-ingress-kubernetes-iossl-passthrough">`nginx.ingress.kubernetes.io/ssl-passthrough`</a> | Some differences in SNI/default backend handling. |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-server-name" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-server-name" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-server-name">`nginx.ingress.kubernetes.io/proxy-ssl-server-name`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-name" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name">`nginx.ingress.kubernetes.io/proxy-ssl-name`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify">`nginx.ingress.kubernetes.io/proxy-ssl-verify`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret">`nginx.ingress.kubernetes.io/proxy-ssl-secret`</a> | |
| Annotation | Limitations / Notes |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-iossl-redirect" href="#opt-nginx-ingress-kubernetes-iossl-redirect" title="#opt-nginx-ingress-kubernetes-iossl-redirect">`nginx.ingress.kubernetes.io/ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
| <a id="opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" href="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect" title="#opt-nginx-ingress-kubernetes-ioforce-ssl-redirect">`nginx.ingress.kubernetes.io/force-ssl-redirect`</a> | Cannot opt-out per route if enabled globally. |
| <a id="opt-nginx-ingress-kubernetes-iossl-passthrough" href="#opt-nginx-ingress-kubernetes-iossl-passthrough" title="#opt-nginx-ingress-kubernetes-iossl-passthrough">`nginx.ingress.kubernetes.io/ssl-passthrough`</a> | Some differences in SNI/default backend handling. |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-server-name" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-server-name" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-server-name">`nginx.ingress.kubernetes.io/proxy-ssl-server-name`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-name" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-name">`nginx.ingress.kubernetes.io/proxy-ssl-name`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-verify">`nginx.ingress.kubernetes.io/proxy-ssl-verify`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" href="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret" title="#opt-nginx-ingress-kubernetes-ioproxy-ssl-secret">`nginx.ingress.kubernetes.io/proxy-ssl-secret`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-secret" href="#opt-nginx-ingress-kubernetes-ioauth-tls-secret" title="#opt-nginx-ingress-kubernetes-ioauth-tls-secret">`nginx.ingress.kubernetes.io/auth-tls-secret`</a> | When validation fails, the rejection happens during the TLS handshake rather than returning a 400 Bad Request. |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client">`nginx.ingress.kubernetes.io/auth-tls-verify-client`</a> | When validation fails, the rejection happens during the TLS handshake rather than returning a 400 Bad Request. |
### Session Affinity
@ -316,6 +319,8 @@ The following annotations are organized by category for easier navigation.
| Annotation | Limitations / Notes |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioapp-root" href="#opt-nginx-ingress-kubernetes-ioapp-root" title="#opt-nginx-ingress-kubernetes-ioapp-root">`nginx.ingress.kubernetes.io/app-root`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iofrom-to-www-redirect" href="#opt-nginx-ingress-kubernetes-iofrom-to-www-redirect" title="#opt-nginx-ingress-kubernetes-iofrom-to-www-redirect">`nginx.ingress.kubernetes.io/from-to-www-redirect`</a> | Doesn't support wildcard hosts. |
| <a id="opt-nginx-ingress-kubernetes-iouse-regex" href="#opt-nginx-ingress-kubernetes-iouse-regex" title="#opt-nginx-ingress-kubernetes-iouse-regex">`nginx.ingress.kubernetes.io/use-regex`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iorewrite-target" href="#opt-nginx-ingress-kubernetes-iorewrite-target" title="#opt-nginx-ingress-kubernetes-iorewrite-target">`nginx.ingress.kubernetes.io/rewrite-target`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iopermanent-redirect" href="#opt-nginx-ingress-kubernetes-iopermanent-redirect" title="#opt-nginx-ingress-kubernetes-iopermanent-redirect">`nginx.ingress.kubernetes.io/permanent-redirect`</a> | Defaults to a 301 Moved Permanently status code. |
@ -329,6 +334,11 @@ The following annotations are organized by category for easier navigation.
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-iowhitelist-source-range" href="#opt-nginx-ingress-kubernetes-iowhitelist-source-range" title="#opt-nginx-ingress-kubernetes-iowhitelist-source-range">`nginx.ingress.kubernetes.io/whitelist-source-range`</a> | |
### Timeout
| Annotation | Limitations / Notes |
|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioproxy-connect-timeout" href="#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout" title="#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout">`nginx.ingress.kubernetes.io/proxy-connect-timeout`</a> | Timeout can be defined globally at the provider level using the [`proxyConnectTimeout` option](../../../install-configuration/providers/kubernetes/kubernetes-ingress-nginx/#opt-providers-kubernetesIngressNGINX-proxyConnectTimeout). |
## Limitations
@ -356,12 +366,8 @@ The following annotations are organized by category for easier navigation.
| Annotation | Notes |
|-----------------------------------------------------------------------------|------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioapp-root" href="#opt-nginx-ingress-kubernetes-ioapp-root" title="#opt-nginx-ingress-kubernetes-ioapp-root">`nginx.ingress.kubernetes.io/app-root`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" href="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" title="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior">`nginx.ingress.kubernetes.io/affinity-canary-behavior`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-signin" href="#opt-nginx-ingress-kubernetes-ioauth-signin" title="#opt-nginx-ingress-kubernetes-ioauth-signin">`nginx.ingress.kubernetes.io/auth-signin`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-secret" href="#opt-nginx-ingress-kubernetes-ioauth-tls-secret" title="#opt-nginx-ingress-kubernetes-ioauth-tls-secret">`nginx.ingress.kubernetes.io/auth-tls-secret`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth">`nginx.ingress.kubernetes.io/auth-tls-verify-depth`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-client">`nginx.ingress.kubernetes.io/auth-tls-verify-client`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" href="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior" title="#opt-nginx-ingress-kubernetes-ioaffinity-canary-behavior">`nginx.ingress.kubernetes.io/affinity-canary-behavior`</a> | | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" href="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth" title="#opt-nginx-ingress-kubernetes-ioauth-tls-verify-depth">`nginx.ingress.kubernetes.io/auth-tls-verify-depth`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-error-page" href="#opt-nginx-ingress-kubernetes-ioauth-tls-error-page" title="#opt-nginx-ingress-kubernetes-ioauth-tls-error-page">`nginx.ingress.kubernetes.io/auth-tls-error-page`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream" href="#opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream" title="#opt-nginx-ingress-kubernetes-ioauth-tls-pass-certificate-to-upstream">`nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioauth-tls-match-cn" href="#opt-nginx-ingress-kubernetes-ioauth-tls-match-cn" title="#opt-nginx-ingress-kubernetes-ioauth-tls-match-cn">`nginx.ingress.kubernetes.io/auth-tls-match-cn`</a> | |
@ -399,8 +405,7 @@ The following annotations are organized by category for easier navigation.
| <a id="opt-nginx-ingress-kubernetes-ioglobal-rate-limit-ignored-cidrs" href="#opt-nginx-ingress-kubernetes-ioglobal-rate-limit-ignored-cidrs" title="#opt-nginx-ingress-kubernetes-ioglobal-rate-limit-ignored-cidrs">`nginx.ingress.kubernetes.io/global-rate-limit-ignored-cidrs`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iopreserve-trailing-slash" href="#opt-nginx-ingress-kubernetes-iopreserve-trailing-slash" title="#opt-nginx-ingress-kubernetes-iopreserve-trailing-slash">`nginx.ingress.kubernetes.io/preserve-trailing-slash`</a> | Traefik preserves trailing slash by default. |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-cookie-domain" href="#opt-nginx-ingress-kubernetes-ioproxy-cookie-domain" title="#opt-nginx-ingress-kubernetes-ioproxy-cookie-domain">`nginx.ingress.kubernetes.io/proxy-cookie-domain`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-cookie-path" href="#opt-nginx-ingress-kubernetes-ioproxy-cookie-path" title="#opt-nginx-ingress-kubernetes-ioproxy-cookie-path">`nginx.ingress.kubernetes.io/proxy-cookie-path`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-connect-timeout" href="#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout" title="#opt-nginx-ingress-kubernetes-ioproxy-connect-timeout">`nginx.ingress.kubernetes.io/proxy-connect-timeout`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-cookie-path" href="#opt-nginx-ingress-kubernetes-ioproxy-cookie-path" title="#opt-nginx-ingress-kubernetes-ioproxy-cookie-path">`nginx.ingress.kubernetes.io/proxy-cookie-path`</a> | | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-send-timeout" href="#opt-nginx-ingress-kubernetes-ioproxy-send-timeout" title="#opt-nginx-ingress-kubernetes-ioproxy-send-timeout">`nginx.ingress.kubernetes.io/proxy-send-timeout`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-read-timeout" href="#opt-nginx-ingress-kubernetes-ioproxy-read-timeout" title="#opt-nginx-ingress-kubernetes-ioproxy-read-timeout">`nginx.ingress.kubernetes.io/proxy-read-timeout`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-next-upstream" href="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream" title="#opt-nginx-ingress-kubernetes-ioproxy-next-upstream">`nginx.ingress.kubernetes.io/proxy-next-upstream`</a> | |

View file

@ -13,7 +13,90 @@ With Consul Catalog, Traefik can leverage tags attached to a service to generate
We recommend to *not* use tags to store sensitive data (certificates, credentials, etc).
Instead, we recommend to store sensitive data in a safer storage (secrets, file, etc).
## Routing Configuration
## Configuration Examples
??? example "Configuring Consul Catalog & Deploying / Exposing one Service"
Enabling the consul catalog provider
```yaml tab="Structured (YAML)"
providers:
consulCatalog: {}
```
```toml tab="Structured (TOML)"
[providers.consulCatalog]
```
```bash tab="CLI"
--providers.consulcatalog=true
```
Attaching tags to services (when registering a service in Consul)
```bash
consul services register -name=my-service -tag="traefik.http.routers.my-service.rule=Host(`example.com`)"
```
Or using a service definition file:
```json
{
"service": {
"name": "my-service",
"tags": [
"traefik.http.routers.my-service.rule=Host(`example.com`)"
]
}
}
```
??? example "Specify a Custom Port for the Container"
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```json
{
"service": {
"name": "my-service",
"tags": [
"traefik.http.routers.my-service.rule=Host(`example.com`)",
"traefik.http.routers.my-service.service=my-service",
"traefik.http.services.my-service.loadbalancer.server.port=12345"
]
}
}
```
!!! important "Traefik Connecting to the Wrong Port: `HTTP/502 Gateway Error`"
By default, Traefik uses the first exposed port of a container.
Setting the tag `traefik.http.services.xxx.loadbalancer.server.port`
overrides that behavior.
??? example "Specifying more than one router and service per container"
Forwarding requests to more than one port on a container requires referencing the service loadbalancer port definition using the service parameter on the router.
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`:
```json
{
"service": {
"name": "my-service",
"tags": [
"traefik.http.routers.www-router.rule=Host(`example-a.com`)",
"traefik.http.routers.www-router.service=www-service",
"traefik.http.services.www-service.loadbalancer.server.port=8000",
"traefik.http.routers.admin-router.rule=Host(`example-b.com`)",
"traefik.http.routers.admin-router.service=admin-service",
"traefik.http.services.admin-service.loadbalancer.server.port=9000"
]
}
}
```
## Configuration Options
!!! info "tags"
@ -35,120 +118,24 @@ To update the configuration of the Router automatically attached to the service,
For example, to change the rule, you could add the tag ```traefik.http.routers.my-service.rule=Host(`example.com`)```.
??? info "`traefik.http.routers.<router_name>.rule`"
See [rule](../http/routing/rules-and-priority.md) for more information.
```yaml
traefik.http.routers.myrouter.rule=Host(`example.com`)
```
#### Configuration Options
??? info "`traefik.http.routers.<router_name>.ruleSyntax`"
!!! warning
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.
See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.
```yaml
traefik.http.routers.myrouter.ruleSyntax=v3
```
??? info "`traefik.http.routers.<router_name>.priority`"
See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.priority=42"
```
??? info "`traefik.http.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.http.routers.myrouter.entrypoints=web,websecure
```
??? info "`traefik.http.routers.<router_name>.middlewares`"
See [middlewares overview](../http/middlewares/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.middlewares=auth,prefix,cb
```
??? info "`traefik.http.routers.<router_name>.service`"
See [service](../http/load-balancing/service.md) for more information.
```yaml
traefik.http.routers.myrouter.service=myservice
```
??? info "`traefik.http.routers.<router_name>.tls`"
See [tls](../http/tls/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.tls=true
```
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.tls.certresolver=myresolver
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
traefik.http.routers.myrouter.tls.domains[0].main=example.org
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org
```
??? info "`traefik.http.routers.<router_name>.tls.options`"
```yaml
traefik.http.routers.myrouter.tls.options=foobar
```
??? info "`traefik.http.routers.<router_name>.observability.accesslogs`"
The accessLogs option controls whether the router will produce access-logs.
```yaml
"traefik.http.routers.myrouter.observability.accesslogs=true"
```
??? info "`traefik.http.routers.<router_name>.observability.metrics`"
The metrics option controls whether the router will produce metrics.
```yaml
"traefik.http.routers.myrouter.observability.metrics=true"
```
??? info "`traefik.http.routers.<router_name>.observability.tracing`"
The tracing option controls whether the router will produce traces.
```yaml
"traefik.http.routers.myrouter.observability.tracing=true"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-routers-router-name-rule" href="#opt-traefik-http-routers-router-name-rule" title="#opt-traefik-http-routers-router-name-rule">`traefik.http.routers.<router_name>.rule`</a> | See [rule](../http/routing/rules-and-priority.md#rules) for more information. | ```Host(`example.com`)``` |
| <a id="opt-traefik-http-routers-router-name-ruleSyntax" href="#opt-traefik-http-routers-router-name-ruleSyntax" title="#opt-traefik-http-routers-router-name-ruleSyntax">`traefik.http.routers.<router_name>.ruleSyntax`</a> | See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-http-routers-router-name-priority" href="#opt-traefik-http-routers-router-name-priority" title="#opt-traefik-http-routers-router-name-priority">`traefik.http.routers.<router_name>.priority`</a> | See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
| <a id="opt-traefik-http-routers-router-name-entrypoints" href="#opt-traefik-http-routers-router-name-entrypoints" title="#opt-traefik-http-routers-router-name-entrypoints">`traefik.http.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `web,websecure` |
| <a id="opt-traefik-http-routers-router-name-middlewares" href="#opt-traefik-http-routers-router-name-middlewares" title="#opt-traefik-http-routers-router-name-middlewares">`traefik.http.routers.<router_name>.middlewares`</a> | See [middlewares overview](../http/middlewares/overview.md) for more information. | `auth,prefix,cb` |
| <a id="opt-traefik-http-routers-router-name-service" href="#opt-traefik-http-routers-router-name-service" title="#opt-traefik-http-routers-router-name-service">`traefik.http.routers.<router_name>.service`</a> | See [service](../http/load-balancing/service.md) for more information. | `myservice` |
| <a id="opt-traefik-http-routers-router-name-tls" href="#opt-traefik-http-routers-router-name-tls" title="#opt-traefik-http-routers-router-name-tls">`traefik.http.routers.<router_name>.tls`</a> | See [tls](../http/tls/overview.md) for more information. | `true` |
| <a id="opt-traefik-http-routers-router-name-tls-certresolver" href="#opt-traefik-http-routers-router-name-tls-certresolver" title="#opt-traefik-http-routers-router-name-tls-certresolver">`traefik.http.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information. | `myresolver` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-main" href="#opt-traefik-http-routers-router-name-tls-domainsn-main" title="#opt-traefik-http-routers-router-name-tls-domainsn-main">`traefik.http.routers.<router_name>.tls.domains[n].main`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-sans" href="#opt-traefik-http-routers-router-name-tls-domainsn-sans" title="#opt-traefik-http-routers-router-name-tls-domainsn-sans">`traefik.http.routers.<router_name>.tls.domains[n].sans`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-options" href="#opt-traefik-http-routers-router-name-tls-options" title="#opt-traefik-http-routers-router-name-tls-options">`traefik.http.routers.<router_name>.tls.options`</a> | | `foobar` |
| <a id="opt-traefik-http-routers-router-name-observability-accesslogs" href="#opt-traefik-http-routers-router-name-observability-accesslogs" title="#opt-traefik-http-routers-router-name-observability-accesslogs">`traefik.http.routers.<router_name>.observability.accesslogs`</a> | The accessLogs option controls whether the router will produce access-logs. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-metrics" href="#opt-traefik-http-routers-router-name-observability-metrics" title="#opt-traefik-http-routers-router-name-observability-metrics">`traefik.http.routers.<router_name>.observability.metrics`</a> | The metrics option controls whether the router will produce metrics. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-tracing" href="#opt-traefik-http-routers-router-name-observability-tracing" title="#opt-traefik-http-routers-router-name-observability-tracing">`traefik.http.routers.<router_name>.observability.tracing`</a> | The tracing option controls whether the router will produce traces. | `true` |
### Services
@ -158,181 +145,34 @@ add tags starting with `traefik.http.services.{name-of-your-choice}.`, followed
For example, to change the `passHostHeader` behavior,
you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`.
??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`"
Registers a port.
Useful when the service exposes multiples ports.
```yaml
traefik.http.services.myservice.loadbalancer.server.port=8080
```
#### Configuration Options
??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`"
Overrides the default scheme.
```yaml
traefik.http.services.myservice.loadbalancer.server.scheme=http
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.weight`"
Overrides the default weight.
```yaml
traefik.http.services.myservice.loadbalancer.server.weight=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../http/load-balancing/serverstransport.md) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.serverstransport=foobar@file
```
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
```yaml
traefik.http.services.myservice.loadbalancer.passhostheader=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.method=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.status=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.port=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.maxage=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
```yaml
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-port" href="#opt-traefik-http-services-service-name-loadbalancer-server-port" title="#opt-traefik-http-services-service-name-loadbalancer-server-port">`traefik.http.services.<service_name>.loadbalancer.server.port`</a> | Registers a port.<br/>Useful when the service exposes multiples ports. | `8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-server-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-server-scheme">`traefik.http.services.<service_name>.loadbalancer.server.scheme`</a> | Overrides the default scheme. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-weight" href="#opt-traefik-http-services-service-name-loadbalancer-server-weight" title="#opt-traefik-http-services-service-name-loadbalancer-server-weight">`traefik.http.services.<service_name>.loadbalancer.server.weight`</a> | Overrides the default weight. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-http-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-http-services-service-name-loadbalancer-serverstransport">`traefik.http.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../http/load-balancing/serverstransport.md) for more information. | `foobar@file` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-passhostheader" href="#opt-traefik-http-services-service-name-loadbalancer-passhostheader" title="#opt-traefik-http-services-service-name-loadbalancer-passhostheader">`traefik.http.services.<service_name>.loadbalancer.passhostheader`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name">`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname">`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `example.org` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path">`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `/foo` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method">`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status">`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port">`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme">`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout">`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects">`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`</a> | | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`</a> | | `/foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`</a> | | `none` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`</a> | | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" href="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" title="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval">`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`</a> | | `10` |
### Middleware
@ -375,124 +215,32 @@ You can declare TCP Routers, Middlewares and/or Services using tags.
#### TCP Routers
??? info "`traefik.tcp.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2
```
##### Configuration Options
??? info "`traefik.tcp.routers.<router_name>.rule`"
See [rule](../tcp/routing/rules-and-priority.md#rules) for more information.
```yaml
traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)
```
??? info "`traefik.tcp.routers.<router_name>.ruleSyntax`"
!!! warning
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.
configure the rule syntax to be used for parsing the rule on a per-router basis.
```yaml
traefik.tcp.routers.mytcprouter.ruleSyntax=v3
```
??? info "`traefik.tcp.routers.<router_name>.priority`"
See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.priority=42"
```
??? info "`traefik.tcp.routers.<router_name>.service`"
See [service](../tcp/service.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.service=myservice
```
??? info "`traefik.tcp.routers.<router_name>.tls`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls=true
```
??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`"
See [certResolver](../tcp/tls.md#configuration-options) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org
```
??? info "`traefik.tcp.routers.<router_name>.tls.options`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.options=mysoptions
```
??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`"
See [Passthrough](../tcp/tls.md#opt-passthrough) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.passthrough=true
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-routers-router-name-entrypoints" href="#opt-traefik-tcp-routers-router-name-entrypoints" title="#opt-traefik-tcp-routers-router-name-entrypoints">`traefik.tcp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-tcp-routers-router-name-rule" href="#opt-traefik-tcp-routers-router-name-rule" title="#opt-traefik-tcp-routers-router-name-rule">`traefik.tcp.routers.<router_name>.rule`</a> | See [rule](../tcp/routing/rules-and-priority.md#rules) for more information. | ```HostSNI(`example.com`)``` |
| <a id="opt-traefik-tcp-routers-router-name-ruleSyntax" href="#opt-traefik-tcp-routers-router-name-ruleSyntax" title="#opt-traefik-tcp-routers-router-name-ruleSyntax">`traefik.tcp.routers.<router_name>.ruleSyntax`</a> | configure the rule syntax to be used for parsing the rule on a per-router basis.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-tcp-routers-router-name-priority" href="#opt-traefik-tcp-routers-router-name-priority" title="#opt-traefik-tcp-routers-router-name-priority">`traefik.tcp.routers.<router_name>.priority`</a> | See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
| <a id="opt-traefik-tcp-routers-router-name-service" href="#opt-traefik-tcp-routers-router-name-service" title="#opt-traefik-tcp-routers-router-name-service">`traefik.tcp.routers.<router_name>.service`</a> | See [service](../tcp/service.md) for more information. | `myservice` |
| <a id="opt-traefik-tcp-routers-router-name-tls" href="#opt-traefik-tcp-routers-router-name-tls" title="#opt-traefik-tcp-routers-router-name-tls">`traefik.tcp.routers.<router_name>.tls`</a> | See [TLS](../tcp/tls.md) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-tls-certresolver" href="#opt-traefik-tcp-routers-router-name-tls-certresolver" title="#opt-traefik-tcp-routers-router-name-tls-certresolver">`traefik.tcp.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../tcp/tls.md#configuration-options) for more information. | `myresolver` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-main" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-main" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-main">`traefik.tcp.routers.<router_name>.tls.domains[n].main`</a> | See [TLS](../tcp/tls.md) for more information. | `example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-sans" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans">`traefik.tcp.routers.<router_name>.tls.domains[n].sans`</a> | See [TLS](../tcp/tls.md) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-options" href="#opt-traefik-tcp-routers-router-name-tls-options" title="#opt-traefik-tcp-routers-router-name-tls-options">`traefik.tcp.routers.<router_name>.tls.options`</a> | See [TLS](../tcp/tls.md) for more information. | `mysoptions` |
| <a id="opt-traefik-tcp-routers-router-name-tls-passthrough" href="#opt-traefik-tcp-routers-router-name-tls-passthrough" title="#opt-traefik-tcp-routers-router-name-tls-passthrough">`traefik.tcp.routers.<router_name>.tls.passthrough`</a> | See [Passthrough](../tcp/tls.md#opt-passthrough) for more information. | `true` |
#### TCP Services
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`"
Registers a port of the application.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.server.port=423
```
##### Configuration Options
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`"
Determines whether to use TLS when dialing with the backend.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../tcp/serverstransport.md) for more information.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.serverstransport=foobar@file
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-port" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-port" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-port">`traefik.tcp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-tls" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls">`traefik.tcp.services.<service_name>.loadbalancer.server.tls`</a> | Determines whether to use TLS when dialing with the backend. | `true` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport">`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../tcp/serverstransport.md) for more information. | `foobar@file` |
#### TCP Middleware
@ -534,67 +282,28 @@ You can declare UDP Routers and/or Services using tags.
#### UDP Routers
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.udp.routers.myudprouter.entrypoints=ep1,ep2
```
##### Configuration Options
??? info "`traefik.udp.routers.<router_name>.service`"
See [service](../udp/service.md) for more information.
```yaml
traefik.udp.routers.myudprouter.service=myservice
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-routers-router-name-entrypoints" href="#opt-traefik-udp-routers-router-name-entrypoints" title="#opt-traefik-udp-routers-router-name-entrypoints">`traefik.udp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-udp-routers-router-name-service" href="#opt-traefik-udp-routers-router-name-service" title="#opt-traefik-udp-routers-router-name-service">`traefik.udp.routers.<router_name>.service`</a> | See [service](../udp/service.md) for more information. | `myservice` |
#### UDP Services
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
Registers a port of the application.
```yaml
traefik.udp.services.myudpservice.loadbalancer.server.port=423
```
##### Configuration Options
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-services-service-name-loadbalancer-server-port" href="#opt-traefik-udp-services-service-name-loadbalancer-server-port" title="#opt-traefik-udp-services-service-name-loadbalancer-server-port">`traefik.udp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
### Specific Provider Options
#### `traefik.enable`
```yaml
traefik.enable=true
```
You can tell Traefik to consider (or not) the service by setting `traefik.enable` to true or false.
This option overrides the value of `exposedByDefault`.
#### `traefik.consulcatalog.connect`
```yaml
traefik.consulcatalog.connect=true
```
You can tell Traefik to consider (or not) the service as a Connect capable one by setting `traefik.consulcatalog.connect` to true or false.
This option overrides the value of `connectByDefault`.
#### `traefik.consulcatalog.canary`
```yaml
traefik.consulcatalog.canary=true
```
When ConsulCatalog, in the context of a Nomad orchestrator,
is a provider (of service registration) for Traefik,
one might have the need to distinguish within Traefik between a [Canary](https://learn.hashicorp.com/tutorials/nomad/job-blue-green-and-canary-deployments#deploy-with-canaries) instance of a service, or a production one.
For example if one does not want them to be part of the same load-balancer.
Therefore, this option, which is meant to be provided as one of the values of the `canary_tags` field in the Nomad [service stanza](https://www.nomadproject.io/docs/job-specification/service#canary_tags),
allows Traefik to identify that the associated instance is a canary one.
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-enable" href="#opt-traefik-enable" title="#opt-traefik-enable">`traefik.enable`</a> | You can tell Traefik to consider (or not) the service by setting `traefik.enable` to true or false.<br/>This option overrides the value of `exposedByDefault`. | `true` |
| <a id="opt-traefik-consulcatalog-connect" href="#opt-traefik-consulcatalog-connect" title="#opt-traefik-consulcatalog-connect">`traefik.consulcatalog.connect`</a> | You can tell Traefik to consider (or not) the service as a Connect capable one by setting `traefik.consulcatalog.connect` to true or false.<br/>This option overrides the value of `connectByDefault`. | `true` |
| <a id="opt-traefik-consulcatalog-canary" href="#opt-traefik-consulcatalog-canary" title="#opt-traefik-consulcatalog-canary">`traefik.consulcatalog.canary`</a> | When ConsulCatalog, in the context of a Nomad orchestrator, is a provider (of service registration) for Traefik, one might have the need to distinguish within Traefik between a [Canary](https://learn.hashicorp.com/tutorials/nomad/job-blue-green-and-canary-deployments#deploy-with-canaries) instance of a service, or a production one.<br/>For example if one does not want them to be part of the same load-balancer.<br/><br/>Therefore, this option, which is meant to be provided as one of the values of the `canary_tags` field in the Nomad [service stanza](https://www.nomadproject.io/docs/job-specification/service#canary_tags), allows Traefik to identify that the associated instance is a canary one. | `true` |
#### Port Lookup

View file

@ -19,12 +19,12 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
Enabling the docker provider
```yaml tab="File (YAML)"
```yaml tab="Structured (YAML)"
providers:
docker: {}
```
```toml tab="File (TOML)"
```toml tab="Structured (TOML)"
[providers.docker]
```
@ -81,7 +81,7 @@ With Docker, Traefik can leverage labels attached to a container to generate rou
- traefik.http.services.admin-service.loadbalancer.server.port=9000
```
## Routing Configuration
## Configuration Options
!!! info "Labels"
@ -145,118 +145,24 @@ For example, to change the rule, you could add the label ```traefik.http.routers
!!! warning "The character `@` is not authorized in the router name `<router_name>`."
??? info "`traefik.http.routers.<router_name>.rule`"
#### Configuration Options
See [rule](../http/routing/rules-and-priority.md) for more information.
```yaml
"traefik.http.routers.myrouter.rule=Host(`example.com`)"
```
??? info "`traefik.http.routers.<router_name>.ruleSyntax`"
!!! warning
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.
See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.
```yaml
traefik.http.routers.myrouter.ruleSyntax=v3
```
??? info "`traefik.http.routers.<router_name>.entrypoints`"
```yaml
"traefik.http.routers.myrouter.entrypoints=ep1,ep2"
```
??? info "`traefik.http.routers.<router_name>.middlewares`"
See [middlewares overview](../http/middlewares/overview.md) for more information.
```yaml
"traefik.http.routers.myrouter.middlewares=auth,prefix,cb"
```
??? info "`traefik.http.routers.<router_name>.service`"
See [service](../http/load-balancing/service.md) for more information.
```yaml
"traefik.http.routers.myrouter.service=myservice"
```
??? info "`traefik.http.routers.<router_name>.tls`"
See [tls](../http/tls/overview.md) for more information.
```yaml
"traefik.http.routers.myrouter.tls=true"
```
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information.
```yaml
"traefik.http.routers.myrouter.tls.certresolver=myresolver"
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
"traefik.http.routers.myrouter.tls.domains[0].main=example.org"
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
"traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org"
```
??? info "`traefik.http.routers.<router_name>.tls.options`"
```yaml
"traefik.http.routers.myrouter.tls.options=foobar"
```
??? info "`traefik.http.routers.<router_name>.observability.accesslogs`"
The accessLogs option controls whether the router will produce access-logs.
```yaml
"traefik.http.routers.myrouter.observability.accesslogs=true"
```
??? info "`traefik.http.routers.<router_name>.observability.metrics`"
The metrics option controls whether the router will produce metrics.
```yaml
"traefik.http.routers.myrouter.observability.metrics=true"
```
??? info "`traefik.http.routers.<router_name>.observability.tracing`"
The tracing option controls whether the router will produce traces.
```yaml
"traefik.http.routers.myrouter.observability.tracing=true"
```
??? info "`traefik.http.routers.<router_name>.priority`"
See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
"traefik.http.routers.myrouter.priority=42"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-routers-router-name-rule" href="#opt-traefik-http-routers-router-name-rule" title="#opt-traefik-http-routers-router-name-rule">`traefik.http.routers.<router_name>.rule`</a> | See [rule](../http/routing/rules-and-priority.md#rules) for more information. | ```Host(`example.com`)``` |
| <a id="opt-traefik-http-routers-router-name-ruleSyntax" href="#opt-traefik-http-routers-router-name-ruleSyntax" title="#opt-traefik-http-routers-router-name-ruleSyntax">`traefik.http.routers.<router_name>.ruleSyntax`</a> | See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-http-routers-router-name-entrypoints" href="#opt-traefik-http-routers-router-name-entrypoints" title="#opt-traefik-http-routers-router-name-entrypoints">`traefik.http.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-http-routers-router-name-middlewares" href="#opt-traefik-http-routers-router-name-middlewares" title="#opt-traefik-http-routers-router-name-middlewares">`traefik.http.routers.<router_name>.middlewares`</a> | See [middlewares overview](../http/middlewares/overview.md) for more information. | `auth,prefix,cb` |
| <a id="opt-traefik-http-routers-router-name-service" href="#opt-traefik-http-routers-router-name-service" title="#opt-traefik-http-routers-router-name-service">`traefik.http.routers.<router_name>.service`</a> | See [service](../http/load-balancing/service.md) for more information. | `myservice` |
| <a id="opt-traefik-http-routers-router-name-tls" href="#opt-traefik-http-routers-router-name-tls" title="#opt-traefik-http-routers-router-name-tls">`traefik.http.routers.<router_name>.tls`</a> | See [tls](../http/tls/overview.md) for more information. | `true` |
| <a id="opt-traefik-http-routers-router-name-tls-certresolver" href="#opt-traefik-http-routers-router-name-tls-certresolver" title="#opt-traefik-http-routers-router-name-tls-certresolver">`traefik.http.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information. | `myresolver` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-main" href="#opt-traefik-http-routers-router-name-tls-domainsn-main" title="#opt-traefik-http-routers-router-name-tls-domainsn-main">`traefik.http.routers.<router_name>.tls.domains[n].main`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-sans" href="#opt-traefik-http-routers-router-name-tls-domainsn-sans" title="#opt-traefik-http-routers-router-name-tls-domainsn-sans">`traefik.http.routers.<router_name>.tls.domains[n].sans`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-options" href="#opt-traefik-http-routers-router-name-tls-options" title="#opt-traefik-http-routers-router-name-tls-options">`traefik.http.routers.<router_name>.tls.options`</a> | | `foobar` |
| <a id="opt-traefik-http-routers-router-name-observability-accesslogs" href="#opt-traefik-http-routers-router-name-observability-accesslogs" title="#opt-traefik-http-routers-router-name-observability-accesslogs">`traefik.http.routers.<router_name>.observability.accesslogs`</a> | The accessLogs option controls whether the router will produce access-logs. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-metrics" href="#opt-traefik-http-routers-router-name-observability-metrics" title="#opt-traefik-http-routers-router-name-observability-metrics">`traefik.http.routers.<router_name>.observability.metrics`</a> | The metrics option controls whether the router will produce metrics. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-tracing" href="#opt-traefik-http-routers-router-name-observability-tracing" title="#opt-traefik-http-routers-router-name-observability-tracing">`traefik.http.routers.<router_name>.observability.tracing`</a> | The tracing option controls whether the router will produce traces. | `true` |
| <a id="opt-traefik-http-routers-router-name-priority" href="#opt-traefik-http-routers-router-name-priority" title="#opt-traefik-http-routers-router-name-priority">`traefik.http.routers.<router_name>.priority`</a> | See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
### Services
@ -268,182 +174,34 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
!!! warning "The character `@` is not authorized in the service name `<service_name>`."
??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`"
#### Configuration Options
Registers a port.
Useful when the container exposes multiples ports.
```yaml
"traefik.http.services.myservice.loadbalancer.server.port=8080"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`"
Overrides the default scheme.
```yaml
"traefik.http.services.myservice.loadbalancer.server.scheme=http"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.url`"
Defines the service URL.
This option cannot be used in combination with `port` or `scheme` definition.
```yaml
traefik.http.services.<service_name>.loadbalancer.server.url=http://foobar:8080
```
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../http/load-balancing/serverstransport.md) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.serverstransport=foobar@file"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
```yaml
"traefik.http.services.myservice.loadbalancer.passhostheader=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10s"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.method=foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.status=42"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.port=42"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10s"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
"traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.maxage=42"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
```yaml
"traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-port" href="#opt-traefik-http-services-service-name-loadbalancer-server-port" title="#opt-traefik-http-services-service-name-loadbalancer-server-port">`traefik.http.services.<service_name>.loadbalancer.server.port`</a> | Registers a port.<br/>Useful when the container exposes multiples ports. | `8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-server-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-server-scheme">`traefik.http.services.<service_name>.loadbalancer.server.scheme`</a> | Overrides the default scheme. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-url" href="#opt-traefik-http-services-service-name-loadbalancer-server-url" title="#opt-traefik-http-services-service-name-loadbalancer-server-url">`traefik.http.services.<service_name>.loadbalancer.server.url`</a> | Defines the service URL.<br/>This option cannot be used in combination with `port` or `scheme` definition. | `http://foobar:8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-http-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-http-services-service-name-loadbalancer-serverstransport">`traefik.http.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../http/load-balancing/serverstransport.md) for more information. | `foobar@file` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-passhostheader" href="#opt-traefik-http-services-service-name-loadbalancer-passhostheader" title="#opt-traefik-http-services-service-name-loadbalancer-passhostheader">`traefik.http.services.<service_name>.loadbalancer.passhostheader`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name">`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname">`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `example.org` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10s` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10s` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path">`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `/foo` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method">`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status">`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port">`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme">`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout">`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10s` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects">`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`</a> | | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`</a> | | `/foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`</a> | | `none` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`</a> | | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" href="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" title="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval">`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`</a> | | `10` |
### Middleware
@ -497,123 +255,31 @@ You can declare TCP Routers and/or Services using labels.
#### TCP Routers
??? info "`traefik.tcp.routers.<router_name>.entrypoints`"
##### Configuration Options
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2"
```
??? info "`traefik.tcp.routers.<router_name>.rule`"
See [rule](../tcp/routing/rules-and-priority.md#rules) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)"
```
??? info "`traefik.tcp.routers.<router_name>.ruleSyntax`"
!!! warning
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.
configure the rule syntax to be used for parsing the rule on a per-router basis.
```yaml
traefik.tcp.routers.mytcprouter.ruleSyntax=v3
```
??? info "`traefik.tcp.routers.<router_name>.service`"
See [service](../tcp/service.md) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.service=myservice"
```
??? info "`traefik.tcp.routers.<router_name>.tls`"
See [TLS](../tcp/tls.md) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.tls=true"
```
??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`"
See [certResolver](../tcp/tls.md#configuration-options) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver"
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`"
See [TLS](../tcp/tls.md) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org"
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`"
See [TLS](../tcp/tls.md) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org"
```
??? info "`traefik.tcp.routers.<router_name>.tls.options`"
```yaml
"traefik.tcp.routers.mytcprouter.tls.options=mysoptions"
```
??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`"
See [TLS](../tcp/tls.md#opt-passthrough) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.tls.passthrough=true"
```
??? info "`traefik.tcp.routers.<router_name>.priority`"
See [priority](../tcp/routing/rules-and-priority.md) for more information.
```yaml
"traefik.tcp.routers.mytcprouter.priority=42"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-routers-router-name-entrypoints" href="#opt-traefik-tcp-routers-router-name-entrypoints" title="#opt-traefik-tcp-routers-router-name-entrypoints">`traefik.tcp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-tcp-routers-router-name-rule" href="#opt-traefik-tcp-routers-router-name-rule" title="#opt-traefik-tcp-routers-router-name-rule">`traefik.tcp.routers.<router_name>.rule`</a> | See [rule](../tcp/routing/rules-and-priority.md#rules) for more information. | ```HostSNI(`example.com`)``` |
| <a id="opt-traefik-tcp-routers-router-name-ruleSyntax" href="#opt-traefik-tcp-routers-router-name-ruleSyntax" title="#opt-traefik-tcp-routers-router-name-ruleSyntax">`traefik.tcp.routers.<router_name>.ruleSyntax`</a> | configure the rule syntax to be used for parsing the rule on a per-router basis.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-tcp-routers-router-name-service" href="#opt-traefik-tcp-routers-router-name-service" title="#opt-traefik-tcp-routers-router-name-service">`traefik.tcp.routers.<router_name>.service`</a> | See [service](../tcp/service.md) for more information. | `myservice` |
| <a id="opt-traefik-tcp-routers-router-name-tls" href="#opt-traefik-tcp-routers-router-name-tls" title="#opt-traefik-tcp-routers-router-name-tls">`traefik.tcp.routers.<router_name>.tls`</a> | See [TLS](../tcp/tls.md) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-tls-certresolver" href="#opt-traefik-tcp-routers-router-name-tls-certresolver" title="#opt-traefik-tcp-routers-router-name-tls-certresolver">`traefik.tcp.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../tcp/tls.md#configuration-options) for more information. | `myresolver` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-main" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-main" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-main">`traefik.tcp.routers.<router_name>.tls.domains[n].main`</a> | See [TLS](../tcp/tls.md) for more information. | `example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-sans" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans">`traefik.tcp.routers.<router_name>.tls.domains[n].sans`</a> | See [TLS](../tcp/tls.md) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-options" href="#opt-traefik-tcp-routers-router-name-tls-options" title="#opt-traefik-tcp-routers-router-name-tls-options">`traefik.tcp.routers.<router_name>.tls.options`</a> | | `mysoptions` |
| <a id="opt-traefik-tcp-routers-router-name-tls-passthrough" href="#opt-traefik-tcp-routers-router-name-tls-passthrough" title="#opt-traefik-tcp-routers-router-name-tls-passthrough">`traefik.tcp.routers.<router_name>.tls.passthrough`</a> | See [Passthrough](../tcp/tls.md#opt-passthrough) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-priority" href="#opt-traefik-tcp-routers-router-name-priority" title="#opt-traefik-tcp-routers-router-name-priority">`traefik.tcp.routers.<router_name>.priority`</a> | See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
#### TCP Services
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`"
##### Configuration Options
Registers a port of the application.
```yaml
"traefik.tcp.services.mytcpservice.loadbalancer.server.port=423"
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`"
Determines whether to use TLS when dialing with the backend.
```yaml
"traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true"
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../tcp/serverstransport.md) for more information.
```yaml
"traefik.tcp.services.mytcpservice.loadbalancer.serverstransport=foobar@file"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-port" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-port" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-port">`traefik.tcp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-tls" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls">`traefik.tcp.services.<service_name>.loadbalancer.server.tls`</a> | Determines whether to use TLS when dialing with the backend. | `true` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport">`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../tcp/serverstransport.md) for more information. | `foobar@file` |
#### TCP Middleware
@ -659,76 +325,25 @@ You can declare UDP Routers and/or Services using labels.
#### UDP Routers
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
##### Configuration Options
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
"traefik.udp.routers.myudprouter.entrypoints=ep1,ep2"
```
??? info "`traefik.udp.routers.<router_name>.service`"
See [service](../udp/service.md) for more information.
```yaml
"traefik.udp.routers.myudprouter.service=myservice"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-routers-router-name-entrypoints" href="#opt-traefik-udp-routers-router-name-entrypoints" title="#opt-traefik-udp-routers-router-name-entrypoints">`traefik.udp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-udp-routers-router-name-service" href="#opt-traefik-udp-routers-router-name-service" title="#opt-traefik-udp-routers-router-name-service">`traefik.udp.routers.<router_name>.service`</a> | See [service](../udp/service.md) for more information. | `myservice` |
#### UDP Services
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
##### Configuration Options
Registers a port of the application.
```yaml
"traefik.udp.services.myudpservice.loadbalancer.server.port=423"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-services-service-name-loadbalancer-server-port" href="#opt-traefik-udp-services-service-name-loadbalancer-server-port" title="#opt-traefik-udp-services-service-name-loadbalancer-server-port">`traefik.udp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
### Specific Provider Options
#### `traefik.enable`
```yaml
- "traefik.enable=true"
```
You can tell Traefik to consider (or not) the container by setting `traefik.enable` to true or false.
This option overrides the value of `exposedByDefault`.
#### `traefik.docker.allownonrunning`
```yaml
- "traefik.docker.allownonrunning=true"
```
By default, Traefik only considers containers in "running" state.
This option controls whether containers that are not in "running" state (e.g., stopped, paused, exited) should still be visible to Traefik for service discovery.
When this label is set to true, Traefik will:
- Keep the router and service configuration even when the container is not running
- Create services with empty backend server lists
- Return 503 Service Unavailable for requests to stopped containers (instead of 404 Not Found)
- Execute the full middleware chain, allowing middlewares to intercept requests
!!! warning "Configuration Collision"
As the `traefik.docker.allownonrunning` enables the discovery of all containers exposing this option disregarding their state,
if multiple stopped containers expose the same router but their configurations diverge, then the routers will be dropped.
#### `traefik.docker.network`
```yaml
- "traefik.docker.network=mynetwork"
```
Overrides the default docker network to use for connections to the container.
If a container is linked to several networks, be sure to set the proper network name (you can check this with `docker inspect <container_id>`),
otherwise it will randomly pick one (depending on how docker is returning them).
!!! warning
When deploying a stack from a compose file `stack`, the networks defined are prefixed with `stack`.
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-enable" href="#opt-traefik-enable" title="#opt-traefik-enable">`traefik.enable`</a> | You can tell Traefik to consider (or not) the container by setting `traefik.enable` to true or false.<br/>This option overrides the value of `exposedByDefault`. | `true` |
| <a id="opt-traefik-docker-allownonrunning" href="#opt-traefik-docker-allownonrunning" title="#opt-traefik-docker-allownonrunning">`traefik.docker.allownonrunning`</a> | By default, Traefik only considers containers in "running" state.<br/>This option controls whether containers that are not in "running" state (e.g., stopped, paused, exited) should still be visible to Traefik for service discovery.<br/><br/>When this label is set to true, Traefik will:<br/>- Keep the router and service configuration even when the container is not running<br/>- Create services with empty backend server lists<br/>- Return 503 Service Unavailable for requests to stopped containers (instead of 404 Not Found)<br/>- Execute the full middleware chain, allowing middlewares to intercept requests<br/><br/>As the `traefik.docker.allownonrunning` enables the discovery of all containers exposing this option disregarding their state, if multiple stopped containers expose the same router but their configurations diverge, then the routers will be dropped. | `true` |
| <a id="opt-traefik-docker-network" href="#opt-traefik-docker-network" title="#opt-traefik-docker-network">`traefik.docker.network`</a> | Overrides the default docker network to use for connections to the container.<br/>If a container is linked to several networks, be sure to set the proper network name (you can check this with `docker inspect <container_id>`), otherwise it will randomly pick one (depending on how docker is returning them).<br/><br/>When deploying a stack from a compose file `stack`, the networks defined are prefixed with `stack`. | `mynetwork` |

View file

@ -13,7 +13,96 @@ With ECS, Traefik can leverage labels attached to a container to generate routin
We recommend to *not* use labels to store sensitive data (certificates, credentials, etc).
Instead, we recommend to store sensitive data in a safer storage (secrets, file, etc).
## Routing Configurationred
## Configuration Examples
??? example "Configuring ECS & Deploying / Exposing one Service"
Enabling the ECS provider
```yaml tab="Structured (YAML)"
providers:
ecs: {}
```
```toml tab="Structured (TOML)"
[providers.ecs]
```
```bash tab="CLI"
--providers.ecs=true
```
Attaching labels to containers (in your ECS task definition)
```json
{
"family": "my-service",
"containerDefinitions": [
{
"name": "my-container",
"image": "my-image:latest",
"labels": {
"traefik.http.routers.my-container.rule": "Host(`example.com`)"
}
}
]
}
```
??? example "Specify a Custom Port for the Container"
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```json
{
"family": "my-service",
"containerDefinitions": [
{
"name": "my-container",
"image": "my-image:latest",
"labels": {
"traefik.http.routers.my-container.rule": "Host(`example.com`)",
"traefik.http.routers.my-container.service": "my-service",
"traefik.http.services.my-service.loadbalancer.server.port": "12345"
}
}
]
}
```
!!! important "Traefik Connecting to the Wrong Port: `HTTP/502 Gateway Error`"
By default, Traefik uses the first exposed port of a container.
Setting the label `traefik.http.services.xxx.loadbalancer.server.port`
overrides that behavior.
??? example "Specifying more than one router and service per container"
Forwarding requests to more than one port on a container requires referencing the service loadbalancer port definition using the service parameter on the router.
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`:
```json
{
"family": "my-service",
"containerDefinitions": [
{
"name": "my-container",
"image": "my-image:latest",
"labels": {
"traefik.http.routers.www-router.rule": "Host(`example-a.com`)",
"traefik.http.routers.www-router.service": "www-service",
"traefik.http.services.www-service.loadbalancer.server.port": "8000",
"traefik.http.routers.admin-router.rule": "Host(`example-b.com`)",
"traefik.http.routers.admin-router.service": "admin-service",
"traefik.http.services.admin-service.loadbalancer.server.port": "9000"
}
}
]
}
```
## Configuration Options
!!! info "labels"
@ -37,120 +126,24 @@ For example, to change the rule, you could add the label ```traefik.http.routers
!!! warning "The character `@` is not authorized in the router name `<router_name>`."
??? info "`traefik.http.routers.<router_name>.rule`"
See [rule](../http/routing/rules-and-priority.md#rules) for more information.
```yaml
traefik.http.routers.myrouter.rule=Host(`example.com`)
```
#### Configuration Options
??? info "`traefik.http.routers.<router_name>.ruleSyntax`"
!!! warning
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.
See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.
```yaml
traefik.http.routers.myrouter.ruleSyntax=v3
```
??? info "`traefik.http.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.http.routers.myrouter.entrypoints=web,websecure
```
??? info "`traefik.http.routers.<router_name>.middlewares`"
See [middlewares overview](../http/middlewares/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.middlewares=auth,prefix,cb
```
??? info "`traefik.http.routers.<router_name>.service`"
See [service](../http/load-balancing/service.md) for more information.
```yaml
traefik.http.routers.myrouter.service=myservice
```
??? info "`traefik.http.routers.<router_name>.tls`"
See [tls](../http/tls/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.tls=true
```
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.tls.certresolver=myresolver
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
traefik.http.routers.myrouter.tls.domains[0].main=example.org
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org
```
??? info "`traefik.http.routers.<router_name>.tls.options`"
```yaml
traefik.http.routers.myrouter.tls.options=foobar
```
??? info "`traefik.http.routers.<router_name>.observability.accesslogs`"
The accessLogs option controls whether the router will produce access-logs.
```yaml
"traefik.http.routers.myrouter.observability.accesslogs=true"
```
??? info "`traefik.http.routers.<router_name>.observability.metrics`"
The metrics option controls whether the router will produce metrics.
```yaml
"traefik.http.routers.myrouter.observability.metrics=true"
```
??? info "`traefik.http.routers.<router_name>.observability.tracing`"
The tracing option controls whether the router will produce traces.
```yaml
"traefik.http.routers.myrouter.observability.tracing=true"
```
??? info "`traefik.http.routers.<router_name>.priority`"
See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
traefik.http.routers.myrouter.priority=42
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-routers-router-name-rule" href="#opt-traefik-http-routers-router-name-rule" title="#opt-traefik-http-routers-router-name-rule">`traefik.http.routers.<router_name>.rule`</a> | See [rule](../http/routing/rules-and-priority.md#rules) for more information. | ```Host(`example.com`)``` |
| <a id="opt-traefik-http-routers-router-name-ruleSyntax" href="#opt-traefik-http-routers-router-name-ruleSyntax" title="#opt-traefik-http-routers-router-name-ruleSyntax">`traefik.http.routers.<router_name>.ruleSyntax`</a> | See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-http-routers-router-name-entrypoints" href="#opt-traefik-http-routers-router-name-entrypoints" title="#opt-traefik-http-routers-router-name-entrypoints">`traefik.http.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `web,websecure` |
| <a id="opt-traefik-http-routers-router-name-middlewares" href="#opt-traefik-http-routers-router-name-middlewares" title="#opt-traefik-http-routers-router-name-middlewares">`traefik.http.routers.<router_name>.middlewares`</a> | See [middlewares overview](../http/middlewares/overview.md) for more information. | `auth,prefix,cb` |
| <a id="opt-traefik-http-routers-router-name-service" href="#opt-traefik-http-routers-router-name-service" title="#opt-traefik-http-routers-router-name-service">`traefik.http.routers.<router_name>.service`</a> | See [service](../http/load-balancing/service.md) for more information. | `myservice` |
| <a id="opt-traefik-http-routers-router-name-tls" href="#opt-traefik-http-routers-router-name-tls" title="#opt-traefik-http-routers-router-name-tls">`traefik.http.routers.<router_name>.tls`</a> | See [tls](../http/tls/overview.md) for more information. | `true` |
| <a id="opt-traefik-http-routers-router-name-tls-certresolver" href="#opt-traefik-http-routers-router-name-tls-certresolver" title="#opt-traefik-http-routers-router-name-tls-certresolver">`traefik.http.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information. | `myresolver` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-main" href="#opt-traefik-http-routers-router-name-tls-domainsn-main" title="#opt-traefik-http-routers-router-name-tls-domainsn-main">`traefik.http.routers.<router_name>.tls.domains[n].main`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-sans" href="#opt-traefik-http-routers-router-name-tls-domainsn-sans" title="#opt-traefik-http-routers-router-name-tls-domainsn-sans">`traefik.http.routers.<router_name>.tls.domains[n].sans`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-options" href="#opt-traefik-http-routers-router-name-tls-options" title="#opt-traefik-http-routers-router-name-tls-options">`traefik.http.routers.<router_name>.tls.options`</a> | | `foobar` |
| <a id="opt-traefik-http-routers-router-name-observability-accesslogs" href="#opt-traefik-http-routers-router-name-observability-accesslogs" title="#opt-traefik-http-routers-router-name-observability-accesslogs">`traefik.http.routers.<router_name>.observability.accesslogs`</a> | The accessLogs option controls whether the router will produce access-logs. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-metrics" href="#opt-traefik-http-routers-router-name-observability-metrics" title="#opt-traefik-http-routers-router-name-observability-metrics">`traefik.http.routers.<router_name>.observability.metrics`</a> | The metrics option controls whether the router will produce metrics. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-tracing" href="#opt-traefik-http-routers-router-name-observability-tracing" title="#opt-traefik-http-routers-router-name-observability-tracing">`traefik.http.routers.<router_name>.observability.tracing`</a> | The tracing option controls whether the router will produce traces. | `true` |
| <a id="opt-traefik-http-routers-router-name-priority" href="#opt-traefik-http-routers-router-name-priority" title="#opt-traefik-http-routers-router-name-priority">`traefik.http.routers.<router_name>.priority`</a> | See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
### Services
@ -162,175 +155,33 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
!!! warning "The character `@` is not authorized in the service name `<service_name>`."
??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`"
Registers a port.
Useful when the service exposes multiples ports.
```yaml
traefik.http.services.myservice.loadbalancer.server.port=8080
```
#### Configuration Options
??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`"
Overrides the default scheme.
```yaml
traefik.http.services.myservice.loadbalancer.server.scheme=http
```
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../http/load-balancing/serverstransport.md) for more information.
```yaml
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file
```
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
```yaml
traefik.http.services.myservice.loadbalancer.passhostheader=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.method=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.status=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.port=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
```yaml
"traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.maxage=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
`FlushInterval` specifies the flush interval to flush to the client while copying the response body.
```yaml
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-port" href="#opt-traefik-http-services-service-name-loadbalancer-server-port" title="#opt-traefik-http-services-service-name-loadbalancer-server-port">`traefik.http.services.<service_name>.loadbalancer.server.port`</a> | Registers a port.<br/>Useful when the service exposes multiples ports. | `8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-server-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-server-scheme">`traefik.http.services.<service_name>.loadbalancer.server.scheme`</a> | Overrides the default scheme. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-http-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-http-services-service-name-loadbalancer-serverstransport">`traefik.http.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../http/load-balancing/serverstransport.md) for more information. | `foobar@file` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-passhostheader" href="#opt-traefik-http-services-service-name-loadbalancer-passhostheader" title="#opt-traefik-http-services-service-name-loadbalancer-passhostheader">`traefik.http.services.<service_name>.loadbalancer.passhostheader`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name">`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname">`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `example.org` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path">`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `/foo` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method">`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status">`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port">`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme">`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout">`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects">`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`</a> | | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`</a> | | `/foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`</a> | | `none` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`</a> | | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" href="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" title="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval">`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`</a> | `FlushInterval` specifies the flush interval to flush to the client while copying the response body. | `10` |
### Middleware
@ -375,133 +226,32 @@ You can declare TCP Routers and/or Services using labels.
#### TCP Routers
??? info "`traefik.tcp.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2
```
##### Configuration Options
??? info "`traefik.tcp.routers.<router_name>.rule`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)
```
??? info "`traefik.tcp.routers.<router_name>.ruleSyntax`"
!!! warning
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.
configure the rule syntax to be used for parsing the rule on a per-router basis.
```yaml
traefik.tcp.routers.mytcprouter.ruleSyntax=v3
```
??? info "`traefik.tcp.routers.<router_name>.service`"
See [service](../tcp/service.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.service=myservice
```
??? info "`traefik.tcp.routers.<router_name>.tls`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls=true
```
??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`"
See [certResolver](../tcp/tls.md#configuration-options) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org
```
??? info "`traefik.tcp.routers.<router_name>.tls.options`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.options=mysoptions
```
??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`"
See [Passthrough](../tcp/tls.md#opt-passthrough) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.passthrough=true
```
??? info "`traefik.tcp.routers.<router_name>.priority`"
See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
traefik.tcp.routers.mytcprouter.priority=42
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-routers-router-name-entrypoints" href="#opt-traefik-tcp-routers-router-name-entrypoints" title="#opt-traefik-tcp-routers-router-name-entrypoints">`traefik.tcp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-tcp-routers-router-name-rule" href="#opt-traefik-tcp-routers-router-name-rule" title="#opt-traefik-tcp-routers-router-name-rule">`traefik.tcp.routers.<router_name>.rule`</a> | See [rule](../tcp/routing/rules-and-priority.md#rules) for more information. | ```HostSNI(`example.com`)``` |
| <a id="opt-traefik-tcp-routers-router-name-ruleSyntax" href="#opt-traefik-tcp-routers-router-name-ruleSyntax" title="#opt-traefik-tcp-routers-router-name-ruleSyntax">`traefik.tcp.routers.<router_name>.ruleSyntax`</a> | configure the rule syntax to be used for parsing the rule on a per-router basis.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-tcp-routers-router-name-service" href="#opt-traefik-tcp-routers-router-name-service" title="#opt-traefik-tcp-routers-router-name-service">`traefik.tcp.routers.<router_name>.service`</a> | See [service](../tcp/service.md) for more information. | `myservice` |
| <a id="opt-traefik-tcp-routers-router-name-tls" href="#opt-traefik-tcp-routers-router-name-tls" title="#opt-traefik-tcp-routers-router-name-tls">`traefik.tcp.routers.<router_name>.tls`</a> | See [TLS](../tcp/tls.md) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-tls-certresolver" href="#opt-traefik-tcp-routers-router-name-tls-certresolver" title="#opt-traefik-tcp-routers-router-name-tls-certresolver">`traefik.tcp.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../tcp/tls.md#configuration-options) for more information. | `myresolver` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-main" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-main" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-main">`traefik.tcp.routers.<router_name>.tls.domains[n].main`</a> | See [TLS](../tcp/tls.md) for more information. | `example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-sans" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans">`traefik.tcp.routers.<router_name>.tls.domains[n].sans`</a> | See [TLS](../tcp/tls.md) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-options" href="#opt-traefik-tcp-routers-router-name-tls-options" title="#opt-traefik-tcp-routers-router-name-tls-options">`traefik.tcp.routers.<router_name>.tls.options`</a> | See [TLS](../tcp/tls.md) for more information. | `mysoptions` |
| <a id="opt-traefik-tcp-routers-router-name-tls-passthrough" href="#opt-traefik-tcp-routers-router-name-tls-passthrough" title="#opt-traefik-tcp-routers-router-name-tls-passthrough">`traefik.tcp.routers.<router_name>.tls.passthrough`</a> | See [Passthrough](../tcp/tls.md#opt-passthrough) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-priority" href="#opt-traefik-tcp-routers-router-name-priority" title="#opt-traefik-tcp-routers-router-name-priority">`traefik.tcp.routers.<router_name>.priority`</a> | See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
#### TCP Services
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`"
Registers a port of the application.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.server.port=423
```
##### Configuration Options
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`"
Determines whether to use TLS when dialing with the backend.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.weight`"
Overrides the default weight.
```yaml
traefik.http.services.myservice.loadbalancer.server.weight=42
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../tcp/serverstransport.md) for more information.
```yaml
traefik.tcp.services.<service_name>.loadbalancer.serverstransport=foobar@file
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-port" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-port" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-port">`traefik.tcp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-tls" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls">`traefik.tcp.services.<service_name>.loadbalancer.server.tls`</a> | Determines whether to use TLS when dialing with the backend. | `true` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-weight" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-weight" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-weight">`traefik.tcp.services.<service_name>.loadbalancer.server.weight`</a> | Overrides the default weight. | `42` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport">`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../tcp/serverstransport.md) for more information. | `foobar@file` |
### UDP
@ -543,40 +293,25 @@ More information about available middlewares in the dedicated [middlewares secti
#### UDP Routers
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.udp.routers.myudprouter.entrypoints=ep1,ep2
```
##### Configuration Options
??? info "`traefik.udp.routers.<router_name>.service`"
See [service](../udp/service.md) for more information.
```yaml
traefik.udp.routers.myudprouter.service=myservice
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-routers-router-name-entrypoints" href="#opt-traefik-udp-routers-router-name-entrypoints" title="#opt-traefik-udp-routers-router-name-entrypoints">`traefik.udp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-udp-routers-router-name-service" href="#opt-traefik-udp-routers-router-name-service" title="#opt-traefik-udp-routers-router-name-service">`traefik.udp.routers.<router_name>.service`</a> | See [service](../udp/service.md) for more information. | `myservice` |
#### UDP Services
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
Registers a port of the application.
```yaml
traefik.udp.services.myudpservice.loadbalancer.server.port=423
```
##### Configuration Options
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-services-service-name-loadbalancer-server-port" href="#opt-traefik-udp-services-service-name-loadbalancer-server-port" title="#opt-traefik-udp-services-service-name-loadbalancer-server-port">`traefik.udp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
### Specific Provider Options
#### `traefik.enable`
#### Configuration Options
```yaml
traefik.enable=true
```
You can tell Traefik to consider (or not) the ECS service by setting `traefik.enable` to true or false.
This option overrides the value of `exposedByDefault`.
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-enable" href="#opt-traefik-enable" title="#opt-traefik-enable">`traefik.enable`</a> | You can tell Traefik to consider (or not) the ECS service by setting `traefik.enable` to true or false.<br/>This option overrides the value of `exposedByDefault`. | `true` |

View file

@ -112,31 +112,33 @@
[http.services.Service03.loadBalancer.responseForwarding]
flushInterval = "42s"
[http.services.Service04]
[http.services.Service04.mirroring]
middlewares = ["foobar", "foobar"]
[http.services.Service05]
[http.services.Service05.mirroring]
service = "foobar"
mirrorBody = true
maxBodySize = 42
[[http.services.Service04.mirroring.mirrors]]
[[http.services.Service05.mirroring.mirrors]]
name = "foobar"
percent = 42
[[http.services.Service04.mirroring.mirrors]]
[[http.services.Service05.mirroring.mirrors]]
name = "foobar"
percent = 42
[http.services.Service04.mirroring.healthCheck]
[http.services.Service05]
[http.services.Service05.weighted]
[http.services.Service05.mirroring.healthCheck]
[http.services.Service06]
[http.services.Service06.weighted]
[[http.services.Service05.weighted.services]]
[[http.services.Service06.weighted.services]]
name = "foobar"
weight = 42
[[http.services.Service05.weighted.services]]
[[http.services.Service06.weighted.services]]
name = "foobar"
weight = 42
[http.services.Service05.weighted.sticky]
[http.services.Service05.weighted.sticky.cookie]
[http.services.Service06.weighted.sticky]
[http.services.Service06.weighted.sticky.cookie]
name = "foobar"
secure = true
httpOnly = true
@ -144,7 +146,7 @@
maxAge = 42
path = "foobar"
domain = "foobar"
[http.services.Service05.weighted.healthCheck]
[http.services.Service06.weighted.healthCheck]
[http.middlewares]
[http.middlewares.Middleware01]
[http.middlewares.Middleware01.addPrefix]

View file

@ -120,6 +120,10 @@ http:
flushInterval: 42s
serversTransport: foobar
Service04:
middlewares:
- foobar
- foobar
Service05:
mirroring:
service: foobar
mirrorBody: true
@ -130,7 +134,7 @@ http:
- name: foobar
percent: 42
healthCheck: {}
Service05:
Service06:
weighted:
services:
- name: foobar

View file

@ -5,6 +5,62 @@ description: "Read the technical documentation to learn the Traefik Routing Conf
# Traefik & KV Stores
## Configuration Examples
??? example "Configuring KV Store & Deploying / Exposing one Service"
Enabling a KV store provider (example: Consul)
```yaml tab="Structured (YAML)"
providers:
consul:
endpoints:
- "127.0.0.1:8500"
```
```toml tab="Structured (TOML)"
[providers.consul]
endpoints = ["127.0.0.1:8500"]
```
```bash tab="CLI"
--providers.consul.endpoints=127.0.0.1:8500
```
Setting keys in the KV store (example: Consul)
```bash
consul kv put traefik/http/routers/my-router/rule "Host(`example.com`)"
consul kv put traefik/http/routers/my-router/service "my-service"
consul kv put traefik/http/services/my-service/loadbalancer/servers/0/url "http://127.0.0.1:8080"
```
??? example "Specify a Custom Port for the Service"
Forward requests for `http://example.com` to `http://127.0.0.1:12345`:
```bash
consul kv put traefik/http/routers/my-router/rule "Host(`example.com`)"
consul kv put traefik/http/routers/my-router/service "my-service"
consul kv put traefik/http/services/my-service/loadbalancer/servers/0/url "http://127.0.0.1:12345"
```
??? example "Specifying more than one router and service"
Forwarding requests to more than one service requires defining multiple routers and services.
In this example, requests are forwarded for `http://example-a.com` to `http://127.0.0.1:8000` in addition to `http://example-b.com` forwarding to `http://127.0.0.1:9000`:
```bash
consul kv put traefik/http/routers/www-router/rule "Host(`example-a.com`)"
consul kv put traefik/http/routers/www-router/service "www-service"
consul kv put traefik/http/services/www-service/loadbalancer/servers/0/url "http://127.0.0.1:8000"
consul kv put traefik/http/routers/admin-router/rule "Host(`example-b.com`)"
consul kv put traefik/http/routers/admin-router/service "admin-service"
consul kv put traefik/http/services/admin-service/loadbalancer/servers/0/url "http://127.0.0.1:9000"
```
## Configuration Options
!!! info "Keys"
@ -93,15 +149,6 @@ description: "Read the technical documentation to learn the Traefik Routing Conf
If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared.
##### Configuration Example
```bash
# Declaring a middleware
traefik/http/middlewares/myAddPrefix/addPrefix/prefix=/foobar
# Referencing a middleware
traefik/http/routers/<router_name>/middlewares/0=myAddPrefix
```
#### ServerTransport
##### Configuration Options
@ -110,17 +157,6 @@ traefik/http/routers/<router_name>/middlewares/0=myAddPrefix
|-----------------------------------------------------------------|-----------------------------------------------------------------|-----------------------------------------|
| <a id="opt-traefikhttpserversTransportsserversTransportNamest-option" href="#opt-traefikhttpserversTransportsserversTransportNamest-option" title="#opt-traefikhttpserversTransportsserversTransportNamest-option">`traefik/http/serversTransports/<serversTransportName>/st_option`</a> | With `st_option` the ServerTransport option to set (ex `maxIdleConnsPerHost`).<br/> More information about available options in the dedicated [ServerTransport section](../http/load-balancing/serverstransport.md). | ServerTransport Options |
##### Configuration Example
```bash
# Declaring a ServerTransport
traefik/http/serversTransports/myServerTransport/maxIdleConnsPerHost=-1
traefik/http/serversTransports/myServerTransport/certificates/0/certFile=mypath/cert.pem
traefik/http/serversTransports/myServerTransport/certificates/0/keyFile=mypath/key.pem
# Referencing a middleware
traefik/http/services/myService/serversTransports/0=myServerTransport
```
### TCP
You can declare TCP Routers and/or Services using KV.
@ -170,15 +206,6 @@ More information about available middlewares in the dedicated [middlewares secti
If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared.
##### Configuration Example
```bash
# Declaring a middleware
traefik/tcp/middlewares/test-inflightconn/amount=10
# Referencing a middleware
traefik/tcp/routers/<router_name>/middlewares/0=test-inflightconn
```
#### ServerTransport
##### Configuration Options
@ -187,15 +214,6 @@ traefik/tcp/routers/<router_name>/middlewares/0=test-inflightconn
|-----------------------------------------------------------------|-----------------------------------------------------------------|-----------------------------------------|
| <a id="opt-traefiktcpserversTransportsserversTransportNamest-option" href="#opt-traefiktcpserversTransportsserversTransportNamest-option" title="#opt-traefiktcpserversTransportsserversTransportNamest-option">`traefik/tcp/serversTransports/<serversTransportName>/st_option`</a> | With `st_option` the ServerTransport option to set (ex `maxIdleConnsPerHost`).<br/> More information about available options in the dedicated [ServerTransport section](../tcp/serverstransport.md). | ServerTransport Options |
##### Configuration Example
```bash
# Declaring a ServerTransport
traefik/tcp/serversTransports/myServerTransport/maxIdleConnsPerHost=-1
# Referencing a middleware
traefik/tcp/services/myService/serversTransports/0=myServerTransport
```
### UDP
You can declare UDP Routers and/or Services using KV.

View file

@ -13,7 +13,108 @@ With Nomad, Traefik can leverage tags attached to a service to generate routing
We recommend to *not* use tags to store sensitive data (certificates, credentials, etc).
Instead, we recommend to store sensitive data in a safer storage (secrets, file, etc).
## Routing Configuration
## Configuration Examples
??? example "Configuring Nomad & Deploying / Exposing one Service"
Enabling the nomad provider
```yaml tab="Structured (YAML)"
providers:
nomad: {}
```
```toml tab="Structured (TOML)"
[providers.nomad]
```
```bash tab="CLI"
--providers.nomad=true
```
Attaching tags to services (in your Nomad job file)
```hcl
job "my-service" {
datacenters = ["dc1"]
group "web" {
task "app" {
driver = "docker"
service {
name = "my-service"
tags = [
"traefik.http.routers.my-service.rule=Host(`example.com`)",
]
}
}
}
}
```
??? example "Specify a Custom Port for the Container"
Forward requests for `http://example.com` to `http://<private IP of container>:12345`:
```hcl
job "my-service" {
datacenters = ["dc1"]
group "web" {
task "app" {
driver = "docker"
service {
name = "my-service"
tags = [
"traefik.http.routers.my-service.rule=Host(`example.com`)",
"traefik.http.routers.my-service.service=my-service",
"traefik.http.services.my-service.loadbalancer.server.port=12345",
]
}
}
}
}
```
!!! important "Traefik Connecting to the Wrong Port: `HTTP/502 Gateway Error`"
By default, Traefik uses the first exposed port of a container.
Setting the tag `traefik.http.services.xxx.loadbalancer.server.port`
overrides that behavior.
??? example "Specifying more than one router and service per container"
Forwarding requests to more than one port on a container requires referencing the service loadbalancer port definition using the service parameter on the router.
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`:
```hcl
job "my-service" {
datacenters = ["dc1"]
group "web" {
task "app" {
driver = "docker"
service {
name = "my-service"
tags = [
"traefik.http.routers.www-router.rule=Host(`example-a.com`)",
"traefik.http.routers.www-router.service=www-service",
"traefik.http.services.www-service.loadbalancer.server.port=8000",
"traefik.http.routers.admin-router.rule=Host(`example-b.com`)",
"traefik.http.routers.admin-router.service=admin-service",
"traefik.http.services.admin-service.loadbalancer.server.port=9000",
]
}
}
}
}
```
## Configuration Options
!!! info "Tags"
@ -35,120 +136,24 @@ To update the configuration of the Router automatically attached to the service,
For example, to change the rule, you could add the tag ```traefik.http.routers.my-service.rule=Host(`example.com`)```.
??? info "`traefik.http.routers.<router_name>.rule`"
#### Configuration Options
See [rule](../http/routing/rules-and-priority.md) for more information.
```yaml
traefik.http.routers.myrouter.rule=Host(`example.com`)
```
??? info "`traefik.http.routers.<router_name>.ruleSyntax`"
!!! warning
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.
See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.
```yaml
traefik.http.routers.myrouter.ruleSyntax=v3
```
??? info "`traefik.http.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.http.routers.myrouter.entrypoints=web,websecure
```
??? info "`traefik.http.routers.<router_name>.middlewares`"
See [middlewares overview](../http/middlewares/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.middlewares=auth,prefix,cb
```
??? info "`traefik.http.routers.<router_name>.service`"
See [service](../http/load-balancing/service.md) for more information.
```yaml
traefik.http.routers.myrouter.service=myservice
```
??? info "`traefik.http.routers.<router_name>.tls`"
See [tls](../http/tls/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.tls=true
```
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information.
```yaml
traefik.http.routers.myrouter.tls.certresolver=myresolver
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
traefik.http.routers.myrouter.tls.domains[0].main=example.org
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org
```
??? info "`traefik.http.routers.<router_name>.tls.options`"
```yaml
traefik.http.routers.myrouter.tls.options=foobar
```
??? info "`traefik.http.routers.<router_name>.priority`"
See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
traefik.http.routers.myrouter.priority=42
```
??? info "`traefik.http.routers.<router_name>.observability.accesslogs`"
The accessLogs option controls whether the router will produce access-logs.
```yaml
"traefik.http.routers.myrouter.observability.accesslogs=true"
```
??? info "`traefik.http.routers.<router_name>.observability.metrics`"
The metrics option controls whether the router will produce metrics.
```yaml
"traefik.http.routers.myrouter.observability.metrics=true"
```
??? info "`traefik.http.routers.<router_name>.observability.tracing`"
The tracing option controls whether the router will produce traces.
```yaml
"traefik.http.routers.myrouter.observability.tracing=true"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-routers-router-name-rule" href="#opt-traefik-http-routers-router-name-rule" title="#opt-traefik-http-routers-router-name-rule">`traefik.http.routers.<router_name>.rule`</a> | See [rule](../http/routing/rules-and-priority.md#rules) for more information. | ```Host(`example.com`)``` |
| <a id="opt-traefik-http-routers-router-name-ruleSyntax" href="#opt-traefik-http-routers-router-name-ruleSyntax" title="#opt-traefik-http-routers-router-name-ruleSyntax">`traefik.http.routers.<router_name>.ruleSyntax`</a> | See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-http-routers-router-name-entrypoints" href="#opt-traefik-http-routers-router-name-entrypoints" title="#opt-traefik-http-routers-router-name-entrypoints">`traefik.http.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `web,websecure` |
| <a id="opt-traefik-http-routers-router-name-middlewares" href="#opt-traefik-http-routers-router-name-middlewares" title="#opt-traefik-http-routers-router-name-middlewares">`traefik.http.routers.<router_name>.middlewares`</a> | See [middlewares overview](../http/middlewares/overview.md) for more information. | `auth,prefix,cb` |
| <a id="opt-traefik-http-routers-router-name-service" href="#opt-traefik-http-routers-router-name-service" title="#opt-traefik-http-routers-router-name-service">`traefik.http.routers.<router_name>.service`</a> | See [service](../http/load-balancing/service.md) for more information. | `myservice` |
| <a id="opt-traefik-http-routers-router-name-tls" href="#opt-traefik-http-routers-router-name-tls" title="#opt-traefik-http-routers-router-name-tls">`traefik.http.routers.<router_name>.tls`</a> | See [tls](../http/tls/overview.md) for more information. | `true` |
| <a id="opt-traefik-http-routers-router-name-tls-certresolver" href="#opt-traefik-http-routers-router-name-tls-certresolver" title="#opt-traefik-http-routers-router-name-tls-certresolver">`traefik.http.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information. | `myresolver` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-main" href="#opt-traefik-http-routers-router-name-tls-domainsn-main" title="#opt-traefik-http-routers-router-name-tls-domainsn-main">`traefik.http.routers.<router_name>.tls.domains[n].main`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-sans" href="#opt-traefik-http-routers-router-name-tls-domainsn-sans" title="#opt-traefik-http-routers-router-name-tls-domainsn-sans">`traefik.http.routers.<router_name>.tls.domains[n].sans`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-options" href="#opt-traefik-http-routers-router-name-tls-options" title="#opt-traefik-http-routers-router-name-tls-options">`traefik.http.routers.<router_name>.tls.options`</a> | | `foobar` |
| <a id="opt-traefik-http-routers-router-name-priority" href="#opt-traefik-http-routers-router-name-priority" title="#opt-traefik-http-routers-router-name-priority">`traefik.http.routers.<router_name>.priority`</a> | See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
| <a id="opt-traefik-http-routers-router-name-observability-accesslogs" href="#opt-traefik-http-routers-router-name-observability-accesslogs" title="#opt-traefik-http-routers-router-name-observability-accesslogs">`traefik.http.routers.<router_name>.observability.accesslogs`</a> | The accessLogs option controls whether the router will produce access-logs. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-metrics" href="#opt-traefik-http-routers-router-name-observability-metrics" title="#opt-traefik-http-routers-router-name-observability-metrics">`traefik.http.routers.<router_name>.observability.metrics`</a> | The metrics option controls whether the router will produce metrics. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-tracing" href="#opt-traefik-http-routers-router-name-observability-tracing" title="#opt-traefik-http-routers-router-name-observability-tracing">`traefik.http.routers.<router_name>.observability.tracing`</a> | The tracing option controls whether the router will produce traces. | `true` |
### Services
@ -158,173 +163,33 @@ add tags starting with `traefik.http.services.{name-of-your-choice}.`, followed
For example, to change the `passHostHeader` behavior,
you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`.
??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`"
#### Configuration Options
Registers a port.
Useful when the service exposes multiples ports.
```yaml
traefik.http.services.myservice.loadbalancer.server.port=8080
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`"
Overrides the default scheme.
```yaml
traefik.http.services.myservice.loadbalancer.server.scheme=http
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.weight`"
Overrides the default weight.
```yaml
traefik.http.services.myservice.loadbalancer.server.weight=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../http/load-balancing/serverstransport.md) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.serverstransport=foobar@file
```
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
```yaml
traefik.http.services.myservice.loadbalancer.passhostheader=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.status=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.port=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`"
```yaml
traefik.http.services.myservice.loadbalancer.sticky.cookie.maxage=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
```yaml
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-port" href="#opt-traefik-http-services-service-name-loadbalancer-server-port" title="#opt-traefik-http-services-service-name-loadbalancer-server-port">`traefik.http.services.<service_name>.loadbalancer.server.port`</a> | Registers a port.<br/>Useful when the service exposes multiples ports. | `8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-server-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-server-scheme">`traefik.http.services.<service_name>.loadbalancer.server.scheme`</a> | Overrides the default scheme. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-weight" href="#opt-traefik-http-services-service-name-loadbalancer-server-weight" title="#opt-traefik-http-services-service-name-loadbalancer-server-weight">`traefik.http.services.<service_name>.loadbalancer.server.weight`</a> | Overrides the default weight. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-http-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-http-services-service-name-loadbalancer-serverstransport">`traefik.http.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../http/load-balancing/serverstransport.md) for more information. | `foobar@file` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-passhostheader" href="#opt-traefik-http-services-service-name-loadbalancer-passhostheader" title="#opt-traefik-http-services-service-name-loadbalancer-passhostheader">`traefik.http.services.<service_name>.loadbalancer.passhostheader`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name">`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname">`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `example.org` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path">`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `/foo` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status">`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port">`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme">`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout">`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects">`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`</a> | | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`</a> | | `/foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`</a> | | `none` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-maxage">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.maxage`</a> | | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" href="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" title="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval">`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`</a> | | `10` |
### Middleware
@ -367,125 +232,31 @@ You can declare TCP Routers and/or Services using tags.
#### TCP Routers
??? info "`traefik.tcp.routers.<router_name>.entrypoints`"
##### Configuration Options
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2
```
??? info "`traefik.tcp.routers.<router_name>.rule`"
See [rule](../tcp/routing/rules-and-priority.md#rules) for more information.
```yaml
traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)
```
??? info "`traefik.tcp.routers.<router_name>.ruleSyntax`"
!!! warning
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.
configure the rule syntax to be used for parsing the rule on a per-router basis.
```yaml
traefik.tcp.routers.mytcprouter.ruleSyntax=v3
```
??? info "`traefik.tcp.routers.<router_name>.priority`"
See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
traefik.tcp.routers.myrouter.priority=42
```
??? info "`traefik.tcp.routers.<router_name>.service`"
See [service](../tcp/service.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.service=myservice
```
??? info "`traefik.tcp.routers.<router_name>.tls`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls=true
```
??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`"
See [certResolver](../tcp/tls.md#configuration-options) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`"
See [TLS](../tcp/tls.md) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org
```
??? info "`traefik.tcp.routers.<router_name>.tls.options`"
See [TLS](../tcp/tls.md#configuration-options) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.options=myoptions
```
??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`"
See [Passthrough](../tcp/tls.md#opt-passthrough) for more information.
```yaml
traefik.tcp.routers.mytcprouter.tls.passthrough=true
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-routers-router-name-entrypoints" href="#opt-traefik-tcp-routers-router-name-entrypoints" title="#opt-traefik-tcp-routers-router-name-entrypoints">`traefik.tcp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-tcp-routers-router-name-rule" href="#opt-traefik-tcp-routers-router-name-rule" title="#opt-traefik-tcp-routers-router-name-rule">`traefik.tcp.routers.<router_name>.rule`</a> | See [rule](../tcp/routing/rules-and-priority.md#rules) for more information. | ```HostSNI(`example.com`)``` |
| <a id="opt-traefik-tcp-routers-router-name-ruleSyntax" href="#opt-traefik-tcp-routers-router-name-ruleSyntax" title="#opt-traefik-tcp-routers-router-name-ruleSyntax">`traefik.tcp.routers.<router_name>.ruleSyntax`</a> | configure the rule syntax to be used for parsing the rule on a per-router basis.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-tcp-routers-router-name-priority" href="#opt-traefik-tcp-routers-router-name-priority" title="#opt-traefik-tcp-routers-router-name-priority">`traefik.tcp.routers.<router_name>.priority`</a> | See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
| <a id="opt-traefik-tcp-routers-router-name-service" href="#opt-traefik-tcp-routers-router-name-service" title="#opt-traefik-tcp-routers-router-name-service">`traefik.tcp.routers.<router_name>.service`</a> | See [service](../tcp/service.md) for more information. | `myservice` |
| <a id="opt-traefik-tcp-routers-router-name-tls" href="#opt-traefik-tcp-routers-router-name-tls" title="#opt-traefik-tcp-routers-router-name-tls">`traefik.tcp.routers.<router_name>.tls`</a> | See [TLS](../tcp/tls.md) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-tls-certresolver" href="#opt-traefik-tcp-routers-router-name-tls-certresolver" title="#opt-traefik-tcp-routers-router-name-tls-certresolver">`traefik.tcp.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../tcp/tls.md#configuration-options) for more information. | `myresolver` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-main" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-main" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-main">`traefik.tcp.routers.<router_name>.tls.domains[n].main`</a> | See [TLS](../tcp/tls.md) for more information. | `example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-sans" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans">`traefik.tcp.routers.<router_name>.tls.domains[n].sans`</a> | See [TLS](../tcp/tls.md) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-options" href="#opt-traefik-tcp-routers-router-name-tls-options" title="#opt-traefik-tcp-routers-router-name-tls-options">`traefik.tcp.routers.<router_name>.tls.options`</a> | See [TLS](../tcp/tls.md#configuration-options) for more information. | `myoptions` |
| <a id="opt-traefik-tcp-routers-router-name-tls-passthrough" href="#opt-traefik-tcp-routers-router-name-tls-passthrough" title="#opt-traefik-tcp-routers-router-name-tls-passthrough">`traefik.tcp.routers.<router_name>.tls.passthrough`</a> | See [Passthrough](../tcp/tls.md#opt-passthrough) for more information. | `true` |
#### TCP Services
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`"
##### Configuration Options
Registers a port of the application.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.server.port=423
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`"
Determines whether to use TLS when dialing with the backend.
```yaml
traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../tcp/serverstransport.md) for more information.
```yaml
traefik.tcp.services.myservice.loadbalancer.serverstransport=foobar@file
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-port" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-port" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-port">`traefik.tcp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-tls" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls">`traefik.tcp.services.<service_name>.loadbalancer.server.tls`</a> | Determines whether to use TLS when dialing with the backend. | `true` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport">`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../tcp/serverstransport.md) for more information. | `foobar@file` |
#### TCP Middleware
@ -527,56 +298,27 @@ You can declare UDP Routers and/or Services using tags.
#### UDP Routers
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
##### Configuration Options
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
traefik.udp.routers.myudprouter.entrypoints=ep1,ep2
```
??? info "`traefik.udp.routers.<router_name>.service`"
See [service](../udp/service.md) for more information.
```yaml
traefik.udp.routers.myudprouter.service=myservice
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-routers-router-name-entrypoints" href="#opt-traefik-udp-routers-router-name-entrypoints" title="#opt-traefik-udp-routers-router-name-entrypoints">`traefik.udp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-udp-routers-router-name-service" href="#opt-traefik-udp-routers-router-name-service" title="#opt-traefik-udp-routers-router-name-service">`traefik.udp.routers.<router_name>.service`</a> | See [service](../udp/service.md) for more information. | `myservice` |
#### UDP Services
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
##### Configuration Options
Registers a port of the application.
```yaml
traefik.udp.services.myudpservice.loadbalancer.server.port=423
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-services-service-name-loadbalancer-server-port" href="#opt-traefik-udp-services-service-name-loadbalancer-server-port" title="#opt-traefik-udp-services-service-name-loadbalancer-server-port">`traefik.udp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
### Specific Provider Options
#### `traefik.enable`
```yaml
traefik.enable=true
```
You can tell Traefik to consider (or not) the service by setting `traefik.enable` to true or false.
This option overrides the value of `exposedByDefault`.
#### `traefik.nomad.canary`
```yaml
traefik.nomad.canary=true
```
When Nomad orchestrator is a provider (of service registration) for Traefik,
one might have the need to distinguish within Traefik between a [Canary](https://learn.hashicorp.com/tutorials/nomad/job-blue-green-and-canary-deployments#deploy-with-canaries) instance of a service, or a production one.
For example if one does not want them to be part of the same load-balancer.
Therefore, this option, which is meant to be provided as one of the values of the `canary_tags` field in the Nomad [service stanza](https://www.nomadproject.io/docs/job-specification/service#canary_tags),
allows Traefik to identify that the associated instance is a canary one.
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-enable" href="#opt-traefik-enable" title="#opt-traefik-enable">`traefik.enable`</a> | You can tell Traefik to consider (or not) the service by setting `traefik.enable` to true or false.<br/>This option overrides the value of `exposedByDefault`. | `true` |
| <a id="opt-traefik-nomad-canary" href="#opt-traefik-nomad-canary" title="#opt-traefik-nomad-canary">`traefik.nomad.canary`</a> | When Nomad orchestrator is a provider (of service registration) for Traefik, one might have the need to distinguish within Traefik between a [Canary](https://learn.hashicorp.com/tutorials/nomad/job-blue-green-and-canary-deployments#deploy-with-canaries) instance of a service, or a production one.<br/>For example if one does not want them to be part of the same load-balancer.<br/><br/>Therefore, this option, which is meant to be provided as one of the values of the `canary_tags` field in the Nomad [service stanza](https://www.nomadproject.io/docs/job-specification/service#canary_tags), allows Traefik to identify that the associated instance is a canary one. | `true` |
#### Port Lookup

View file

@ -19,7 +19,7 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
Enabling the docker provider (Swarm Mode)
```yaml tab="File (YAML)"
```yaml tab="Structured (YAML)"
providers:
swarm:
# swarm classic (1.12-)
@ -28,7 +28,7 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
endpoint: "tcp://127.0.0.1:2377"
```
```toml tab="File (TOML)"
```toml tab="Structured (TOML)"
[providers.swarm]
# swarm classic (1.12-)
# endpoint = "tcp://127.0.0.1:2375"
@ -104,7 +104,7 @@ With Docker Swarm, Traefik can leverage labels attached to a service to generate
- traefik.http.services.admin-service.loadbalancer.server.port=9000
```
## Routing Configuration
## Configuration Options
!!! info "Labels"
@ -156,120 +156,24 @@ For example, to change the rule, you could add the label ```traefik.http.routers
!!! warning "The character `@` is not authorized in the router name `<router_name>`."
??? info "`traefik.http.routers.<router_name>.rule`"
#### Configuration Options
See [rule](../http/routing/rules-and-priority.md) for more information.
```yaml
- "traefik.http.routers.myrouter.rule=Host(`example.com`)"
```
??? info "`traefik.http.routers.<router_name>.ruleSyntax`"
!!! warning
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.
See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.
```yaml
traefik.http.routers.myrouter.ruleSyntax=v3
```
??? info "`traefik.http.routers.<router_name>.entrypoints`"
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
- "traefik.http.routers.myrouter.entrypoints=ep1,ep2"
```
??? info "`traefik.http.routers.<router_name>.middlewares`"
See [middlewares overview](../http/middlewares/overview.md) for more information.
```yaml
- "traefik.http.routers.myrouter.middlewares=auth,prefix,cb"
```
??? info "`traefik.http.routers.<router_name>.service`"
See [service](../http/load-balancing/service.md) for more information.
```yaml
- "traefik.http.routers.myrouter.service=myservice"
```
??? info "`traefik.http.routers.<router_name>.tls`"
See [tls](../http/tls/overview.md) for more information.
```yaml
- "traefik.http.routers.myrouter.tls=true"
```
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information.
```yaml
- "traefik.http.routers.myrouter.tls.certresolver=myresolver"
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
- "traefik.http.routers.myrouter.tls.domains[0].main=example.org"
```
??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`"
See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information.
```yaml
- "traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org"
```
??? info "`traefik.http.routers.<router_name>.tls.options`"
```yaml
- "traefik.http.routers.myrouter.tls.options=foobar"
```
??? info "`traefik.http.routers.<router_name>.observability.accesslogs`"
The accessLogs option controls whether the router will produce access-logs.
```yaml
"traefik.http.routers.myrouter.observability.accesslogs=true"
```
??? info "`traefik.http.routers.<router_name>.observability.metrics`"
The metrics option controls whether the router will produce metrics.
```yaml
"traefik.http.routers.myrouter.observability.metrics=true"
```
??? info "`traefik.http.routers.<router_name>.observability.tracing`"
The tracing option controls whether the router will produce traces.
```yaml
"traefik.http.routers.myrouter.observability.tracing=true"
```
??? info "`traefik.http.routers.<router_name>.priority`"
See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information.
```yaml
- "traefik.http.routers.myrouter.priority=42"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-routers-router-name-rule" href="#opt-traefik-http-routers-router-name-rule" title="#opt-traefik-http-routers-router-name-rule">`traefik.http.routers.<router_name>.rule`</a> | See [rule](../http/routing/rules-and-priority.md#rules) for more information. | ```Host(`example.com`)``` |
| <a id="opt-traefik-http-routers-router-name-ruleSyntax" href="#opt-traefik-http-routers-router-name-ruleSyntax" title="#opt-traefik-http-routers-router-name-ruleSyntax">`traefik.http.routers.<router_name>.ruleSyntax`</a> | See [ruleSyntax](../http/routing/rules-and-priority.md#rulesyntax) for more information.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-http-routers-router-name-entrypoints" href="#opt-traefik-http-routers-router-name-entrypoints" title="#opt-traefik-http-routers-router-name-entrypoints">`traefik.http.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-http-routers-router-name-middlewares" href="#opt-traefik-http-routers-router-name-middlewares" title="#opt-traefik-http-routers-router-name-middlewares">`traefik.http.routers.<router_name>.middlewares`</a> | See [middlewares overview](../http/middlewares/overview.md) for more information. | `auth,prefix,cb` |
| <a id="opt-traefik-http-routers-router-name-service" href="#opt-traefik-http-routers-router-name-service" title="#opt-traefik-http-routers-router-name-service">`traefik.http.routers.<router_name>.service`</a> | See [service](../http/load-balancing/service.md) for more information. | `myservice` |
| <a id="opt-traefik-http-routers-router-name-tls" href="#opt-traefik-http-routers-router-name-tls" title="#opt-traefik-http-routers-router-name-tls">`traefik.http.routers.<router_name>.tls`</a> | See [tls](../http/tls/overview.md) for more information. | `true` |
| <a id="opt-traefik-http-routers-router-name-tls-certresolver" href="#opt-traefik-http-routers-router-name-tls-certresolver" title="#opt-traefik-http-routers-router-name-tls-certresolver">`traefik.http.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../../install-configuration/tls/certificate-resolvers/overview.md) for more information. | `myresolver` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-main" href="#opt-traefik-http-routers-router-name-tls-domainsn-main" title="#opt-traefik-http-routers-router-name-tls-domainsn-main">`traefik.http.routers.<router_name>.tls.domains[n].main`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-domainsn-sans" href="#opt-traefik-http-routers-router-name-tls-domainsn-sans" title="#opt-traefik-http-routers-router-name-tls-domainsn-sans">`traefik.http.routers.<router_name>.tls.domains[n].sans`</a> | See [domains](../../install-configuration/tls/certificate-resolvers/acme.md#domain-definition) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-http-routers-router-name-tls-options" href="#opt-traefik-http-routers-router-name-tls-options" title="#opt-traefik-http-routers-router-name-tls-options">`traefik.http.routers.<router_name>.tls.options`</a> | | `foobar` |
| <a id="opt-traefik-http-routers-router-name-observability-accesslogs" href="#opt-traefik-http-routers-router-name-observability-accesslogs" title="#opt-traefik-http-routers-router-name-observability-accesslogs">`traefik.http.routers.<router_name>.observability.accesslogs`</a> | The accessLogs option controls whether the router will produce access-logs. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-metrics" href="#opt-traefik-http-routers-router-name-observability-metrics" title="#opt-traefik-http-routers-router-name-observability-metrics">`traefik.http.routers.<router_name>.observability.metrics`</a> | The metrics option controls whether the router will produce metrics. | `true` |
| <a id="opt-traefik-http-routers-router-name-observability-tracing" href="#opt-traefik-http-routers-router-name-observability-tracing" title="#opt-traefik-http-routers-router-name-observability-tracing">`traefik.http.routers.<router_name>.observability.tracing`</a> | The tracing option controls whether the router will produce traces. | `true` |
| <a id="opt-traefik-http-routers-router-name-priority" href="#opt-traefik-http-routers-router-name-priority" title="#opt-traefik-http-routers-router-name-priority">`traefik.http.routers.<router_name>.priority`</a> | See [priority](../http/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
### Services
@ -281,189 +185,34 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
!!! warning "The character `@` is not authorized in the service name `<service_name>`."
??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`"
#### Configuration Options
Registers a port.
Useful when the container exposes multiples ports.
Mandatory for Docker Swarm (see the section ["Port Detection with Docker Swarm"](../../install-configuration/providers/swarm.md#port-detection)).
{: #port }
```yaml
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`"
Overrides the default scheme.
```yaml
- "traefik.http.services.myservice.loadbalancer.server.scheme=http"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.url`"
Defines the service URL.
This option cannot be used in combination with `port` or `scheme` definition.
```yaml
traefik.http.services.<service_name>.loadbalancer.server.url=http://foobar:8080
```
??? info "`traefik.http.services.<service_name>.loadbalancer.server.weight`"
Overrides the default weight.
```yaml
traefik.http.services.myservice.loadbalancer.server.weight=42
```
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../http/load-balancing/serverstransport.md) for more information.
```yaml
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
```yaml
- "traefik.http.services.myservice.loadbalancer.passhostheader=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.unhealthyinterval=10s"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.method=foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.status=42"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.port=42"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10s"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`"
See [health check](../http/load-balancing/service.md#health-check) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.path=/foobar"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`"
```yaml
- "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none"
```
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
See [response forwarding](../http/load-balancing/service.md#configuration-options) for more information.
```yaml
- "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-port" href="#opt-traefik-http-services-service-name-loadbalancer-server-port" title="#opt-traefik-http-services-service-name-loadbalancer-server-port">`traefik.http.services.<service_name>.loadbalancer.server.port`</a> | Registers a port.<br/>Useful when the container exposes multiples ports.<br/>Mandatory for Docker Swarm (see the section ["Port Detection with Docker Swarm"](../../install-configuration/providers/swarm.md#port-detection)). | `8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-server-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-server-scheme">`traefik.http.services.<service_name>.loadbalancer.server.scheme`</a> | Overrides the default scheme. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-url" href="#opt-traefik-http-services-service-name-loadbalancer-server-url" title="#opt-traefik-http-services-service-name-loadbalancer-server-url">`traefik.http.services.<service_name>.loadbalancer.server.url`</a> | Defines the service URL.<br/>This option cannot be used in combination with `port` or `scheme` definition. | `http://foobar:8080` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-server-weight" href="#opt-traefik-http-services-service-name-loadbalancer-server-weight" title="#opt-traefik-http-services-service-name-loadbalancer-server-weight">`traefik.http.services.<service_name>.loadbalancer.server.weight`</a> | Overrides the default weight. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-http-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-http-services-service-name-loadbalancer-serverstransport">`traefik.http.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../http/load-balancing/serverstransport.md) for more information. | `foobar@file` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-passhostheader" href="#opt-traefik-http-services-service-name-loadbalancer-passhostheader" title="#opt-traefik-http-services-service-name-loadbalancer-passhostheader">`traefik.http.services.<service_name>.loadbalancer.passhostheader`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-headers-header-name">`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-hostname">`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `example.org` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-interval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10s` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-unhealthyinterval">`traefik.http.services.<service_name>.loadbalancer.healthcheck.unhealthyinterval`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10s` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-path">`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `/foo` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-method">`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-status">`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-port">`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `42` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-scheme">`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `http` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-timeout">`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `10s` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" href="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects" title="#opt-traefik-http-services-service-name-loadbalancer-healthcheck-followredirects">`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`</a> | See [health check](../http/load-balancing/service.md#health-check) for more information. | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-httponly">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-name">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`</a> | | `foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-path">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.path`</a> | | `/foobar` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-secure">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`</a> | | `true` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" href="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite" title="#opt-traefik-http-services-service-name-loadbalancer-sticky-cookie-samesite">`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`</a> | | `none` |
| <a id="opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" href="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval" title="#opt-traefik-http-services-service-name-loadbalancer-responseforwarding-flushinterval">`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`</a> | See [response forwarding](../http/load-balancing/service.md#configuration-options) for more information. | `10` |
### Middleware
@ -519,125 +268,31 @@ You can declare TCP Routers and/or Services using labels.
#### TCP Routers
??? info "`traefik.tcp.routers.<router_name>.entrypoints`"
##### Configuration Options
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2"
```
??? info "`traefik.tcp.routers.<router_name>.rule`"
See [rule](../tcp/routing/rules-and-priority.md#rules) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)"
```
??? info "`traefik.tcp.routers.<router_name>.ruleSyntax`"
!!! warning
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.
configure the rule syntax to be used for parsing the rule on a per-router basis.
```yaml
traefik.tcp.routers.mytcprouter.ruleSyntax=v3
```
??? info "`traefik.tcp.routers.<router_name>.service`"
See [service](../tcp/service.md) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.service=myservice"
```
??? info "`traefik.tcp.routers.<router_name>.tls`"
See [TLS](../tcp/tls.md) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.tls=true"
```
??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`"
See [certResolver](../tcp/tls.md#configuration-options) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver"
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`"
See [TLS](../tcp/tls.md) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org"
```
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`"
See [TLS](../tcp/tls.md) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org"
```
??? info "`traefik.tcp.routers.<router_name>.tls.options`"
See [TLS](../tcp/tls.md) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.tls.options=mysoptions"
```
??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`"
See [Passthrough](../tcp/tls.md#opt-passthrough) for more information.
```yaml
- "traefik.tcp.routers.mytcprouter.tls.passthrough=true"
```
??? info "`traefik.tcp.routers.<router_name>.priority`"
See [priority](../tcp/routing/rules-and-priority.md) for more information.
```yaml
- "traefik.tcp.routers.myrouter.priority=42"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-routers-router-name-entrypoints" href="#opt-traefik-tcp-routers-router-name-entrypoints" title="#opt-traefik-tcp-routers-router-name-entrypoints">`traefik.tcp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-tcp-routers-router-name-rule" href="#opt-traefik-tcp-routers-router-name-rule" title="#opt-traefik-tcp-routers-router-name-rule">`traefik.tcp.routers.<router_name>.rule`</a> | See [rule](../tcp/routing/rules-and-priority.md#rules) for more information. | ```HostSNI(`example.com`)``` |
| <a id="opt-traefik-tcp-routers-router-name-ruleSyntax" href="#opt-traefik-tcp-routers-router-name-ruleSyntax" title="#opt-traefik-tcp-routers-router-name-ruleSyntax">`traefik.tcp.routers.<router_name>.ruleSyntax`</a> | configure the rule syntax to be used for parsing the rule on a per-router basis.<br/>RuleSyntax option is deprecated and will be removed in the next major version.<br/>Please do not use this field and rewrite the router rules to use the v3 syntax. | `v3` |
| <a id="opt-traefik-tcp-routers-router-name-service" href="#opt-traefik-tcp-routers-router-name-service" title="#opt-traefik-tcp-routers-router-name-service">`traefik.tcp.routers.<router_name>.service`</a> | See [service](../tcp/service.md) for more information. | `myservice` |
| <a id="opt-traefik-tcp-routers-router-name-tls" href="#opt-traefik-tcp-routers-router-name-tls" title="#opt-traefik-tcp-routers-router-name-tls">`traefik.tcp.routers.<router_name>.tls`</a> | See [TLS](../tcp/tls.md) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-tls-certresolver" href="#opt-traefik-tcp-routers-router-name-tls-certresolver" title="#opt-traefik-tcp-routers-router-name-tls-certresolver">`traefik.tcp.routers.<router_name>.tls.certresolver`</a> | See [certResolver](../tcp/tls.md#configuration-options) for more information. | `myresolver` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-main" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-main" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-main">`traefik.tcp.routers.<router_name>.tls.domains[n].main`</a> | See [TLS](../tcp/tls.md) for more information. | `example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-domainsn-sans" href="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans" title="#opt-traefik-tcp-routers-router-name-tls-domainsn-sans">`traefik.tcp.routers.<router_name>.tls.domains[n].sans`</a> | See [TLS](../tcp/tls.md) for more information. | `test.example.org,dev.example.org` |
| <a id="opt-traefik-tcp-routers-router-name-tls-options" href="#opt-traefik-tcp-routers-router-name-tls-options" title="#opt-traefik-tcp-routers-router-name-tls-options">`traefik.tcp.routers.<router_name>.tls.options`</a> | See [TLS](../tcp/tls.md) for more information. | `mysoptions` |
| <a id="opt-traefik-tcp-routers-router-name-tls-passthrough" href="#opt-traefik-tcp-routers-router-name-tls-passthrough" title="#opt-traefik-tcp-routers-router-name-tls-passthrough">`traefik.tcp.routers.<router_name>.tls.passthrough`</a> | See [Passthrough](../tcp/tls.md#opt-passthrough) for more information. | `true` |
| <a id="opt-traefik-tcp-routers-router-name-priority" href="#opt-traefik-tcp-routers-router-name-priority" title="#opt-traefik-tcp-routers-router-name-priority">`traefik.tcp.routers.<router_name>.priority`</a> | See [priority](../tcp/routing/rules-and-priority.md#priority-calculation) for more information. | `42` |
#### TCP Services
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`"
##### Configuration Options
Registers a port of the application.
```yaml
- "traefik.tcp.services.mytcpservice.loadbalancer.server.port=423"
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`"
Determines whether to use TLS when dialing with the backend.
```yaml
- "traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true"
```
??? info "`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`"
Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.
See [serverstransport](../tcp/serverstransport.md) for more information.
```yaml
- "traefik.tcp.services.<service_name>.loadbalancer.serverstransport=foobar@file"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-port" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-port" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-port">`traefik.tcp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-server-tls" href="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls" title="#opt-traefik-tcp-services-service-name-loadbalancer-server-tls">`traefik.tcp.services.<service_name>.loadbalancer.server.tls`</a> | Determines whether to use TLS when dialing with the backend. | `true` |
| <a id="opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" href="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport" title="#opt-traefik-tcp-services-service-name-loadbalancer-serverstransport">`traefik.tcp.services.<service_name>.loadbalancer.serverstransport`</a> | Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one.<br/>See [serverstransport](../tcp/serverstransport.md) for more information. | `foobar@file` |
#### TCP Middleware
@ -684,65 +339,25 @@ You can declare UDP Routers and/or Services using labels.
#### UDP Routers
??? info "`traefik.udp.routers.<router_name>.entrypoints`"
##### Configuration Options
See [entry points](../../install-configuration/entrypoints.md) for more information.
```yaml
- "traefik.udp.routers.myudprouter.entrypoints=ep1,ep2"
```
??? info "`traefik.udp.routers.<router_name>.service`"
See [service](../udp/service.md) for more information.
```yaml
- "traefik.udp.routers.myudprouter.service=myservice"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-routers-router-name-entrypoints" href="#opt-traefik-udp-routers-router-name-entrypoints" title="#opt-traefik-udp-routers-router-name-entrypoints">`traefik.udp.routers.<router_name>.entrypoints`</a> | See [entry points](../../install-configuration/entrypoints.md) for more information. | `ep1,ep2` |
| <a id="opt-traefik-udp-routers-router-name-service" href="#opt-traefik-udp-routers-router-name-service" title="#opt-traefik-udp-routers-router-name-service">`traefik.udp.routers.<router_name>.service`</a> | See [service](../udp/service.md) for more information. | `myservice` |
#### UDP Services
??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`"
##### Configuration Options
Registers a port of the application.
```yaml
- "traefik.udp.services.myudpservice.loadbalancer.server.port=423"
```
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-udp-services-service-name-loadbalancer-server-port" href="#opt-traefik-udp-services-service-name-loadbalancer-server-port" title="#opt-traefik-udp-services-service-name-loadbalancer-server-port">`traefik.udp.services.<service_name>.loadbalancer.server.port`</a> | Registers a port of the application. | `423` |
### Specific Provider Options
#### `traefik.enable`
```yaml
- "traefik.enable=true"
```
You can tell Traefik to consider (or not) the container by setting `traefik.enable` to true or false.
This option overrides the value of `exposedByDefault`.
#### `traefik.swarm.network`
```yaml
- "traefik.swarm.network=mynetwork"
```
Overrides the default docker network to use for connections to the container.
If a container is linked to several networks, be sure to set the proper network name (you can check this with `docker inspect <container_id>`),
otherwise it will randomly pick one (depending on how docker is returning them).
!!! warning
When deploying a stack from a compose file `stack`, the networks defined are prefixed with `stack`.
#### `traefik.swarm.lbswarm`
```yaml
- "traefik.swarm.lbswarm=true"
```
Enables Swarm's inbuilt load balancer (only relevant in Swarm Mode).
If you enable this option, Traefik will use the virtual IP provided by docker swarm instead of the containers IPs.
Which means that Traefik will not perform any kind of load balancing and will delegate this task to swarm.
| Label | Description | Value |
|------|-------------|-------|
| <a id="opt-traefik-enable" href="#opt-traefik-enable" title="#opt-traefik-enable">`traefik.enable`</a> | You can tell Traefik to consider (or not) the container by setting `traefik.enable` to true or false.<br/>This option overrides the value of `exposedByDefault`. | `true` |
| <a id="opt-traefik-swarm-network" href="#opt-traefik-swarm-network" title="#opt-traefik-swarm-network">`traefik.swarm.network`</a> | Overrides the default docker network to use for connections to the container.<br/>If a container is linked to several networks, be sure to set the proper network name (you can check this with `docker inspect <container_id>`), otherwise it will randomly pick one (depending on how docker is returning them).<br/><br/>When deploying a stack from a compose file `stack`, the networks defined are prefixed with `stack`. | `mynetwork` |
| <a id="opt-traefik-swarm-lbswarm" href="#opt-traefik-swarm-lbswarm" title="#opt-traefik-swarm-lbswarm">`traefik.swarm.lbswarm`</a> | Enables Swarm's inbuilt load balancer (only relevant in Swarm Mode).<br/>If you enable this option, Traefik will use the virtual IP provided by docker swarm instead of the containers IPs.<br/>Which means that Traefik will not perform any kind of load balancing and will delegate this task to swarm. | `true` |

View file

@ -2045,6 +2045,6 @@ If the ServersTransportTCP CRD is defined in another provider the cross-provider
## Further
Also see the [full example](../../user-guides/crd-acme/index.md) with Let's Encrypt.
For additional information on exposing services with Kubernetes, see the [Kubernetes guide](../../expose/kubernetes/basic.md).
{% include-markdown "includes/traefik-for-business-applications.md" %}

View file

@ -101,11 +101,12 @@ ports:
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
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
# Defines the HTTPS entry point named 'websecure'
websecure:

View file

@ -1,183 +0,0 @@
---
title: "Integration with cert-manager"
description: "Learn how to use cert-manager certificates with Traefik Proxy for your routers. Read the technical documentation."
---
# cert-manager
Provision TLS Certificate for Traefik Proxy with cert-manager on Kubernetes
{: .subtitle }
## Pre-requisites
To obtain certificates from cert-manager that can be used in Traefik Proxy, you will need to:
1. Have cert-manager properly configured
2. Have Traefik Proxy configured
The certificates can then be used in an Ingress / IngressRoute / HTTPRoute.
## Example with ACME and HTTP challenge
!!! example "ACME issuer for HTTP challenge"
```yaml tab="Issuer"
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: acme
spec:
acme:
# Production server is on https://acme-v02.api.letsencrypt.org/directory
# Use staging by default.
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: acme
solvers:
- http01:
ingress:
ingressClassName: traefik
```
```yaml tab="Certificate"
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: whoami
namespace: traefik
spec:
secretName: domain-tls # <=== Name of secret where the generated certificate will be stored.
dnsNames:
- "domain.example.com"
issuerRef:
name: acme
kind: Issuer
```
Let's see now how to use it with the various Kubernetes providers of Traefik Proxy.
The enabled providers can be seen on the [dashboard](../reference/install-configuration/api-dashboard.md) of Traefik Proxy and also in the INFO logs when Traefik Proxy starts.
### With an Ingress
To use this certificate with an Ingress, the [Kubernetes Ingress](../providers/kubernetes-ingress.md) provider has to be enabled.
!!! info Traefik Helm Chart
This provider is enabled by default in the Traefik Helm Chart.
!!! example "Route with this Certificate"
```yaml tab="Ingress"
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: domain
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
rules:
- host: domain.example.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: domain-service
port:
number: 80
tls:
- secretName: domain-tls # <=== Use the name defined in Certificate resource.
```
### With an IngressRoute
To use this certificate with an IngressRoute, the [Kubernetes CRD](../providers/kubernetes-crd.md) provider has to be enabled.
!!! info Traefik Helm Chart
This provider is enabled by default in the Traefik Helm Chart.
!!! example "Route with this Certificate"
```yaml tab="IngressRoute"
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: domain
spec:
entryPoints:
- websecure
routes:
- match: Host(`domain.example.com`)
kind: Rule
services:
- name: domain-service
port: 80
tls:
secretName: domain-tls # <=== Use the name defined in Certificate resource.
```
### With an HTTPRoute
To use this certificate with an HTTPRoute, the [Kubernetes Gateway](../routing/providers/kubernetes-gateway.md) provider has to be enabled.
!!! info Traefik Helm Chart
This provider is disabled by default in the Traefik Helm Chart.
!!! example "Route with this Certificate"
```yaml tab="HTTPRoute"
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: domain-gateway
spec:
gatewayClassName: traefik
listeners:
- name: websecure
port: 8443
protocol: HTTPS
hostname: domain.example.com
tls:
certificateRefs:
- name: domain-tls # <==== Use the name defined in Certificate resource.
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: domain
spec:
parentRefs:
- name: domain-gateway
hostnames:
- domain.example.com
rules:
- matches:
- path:
type: Exact
value: /
backendRefs:
- name: domain-service
port: 80
weight: 1
```
## Troubleshooting
There are multiple event sources available to investigate when using cert-manager:
1. Kubernetes events in `Certificate` and `CertificateRequest` resources
2. cert-manager logs
3. Dashboard and/or (debug) logs from Traefik Proxy
cert-manager documentation provides a [detailed guide](https://cert-manager.io/docs/troubleshooting/) on how to troubleshoot a certificate request.
{% include-markdown "includes/traefik-for-business-applications.md" %}

View file

@ -1,32 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
ports:
- protocol: TCP
name: web
port: 8000
- protocol: TCP
name: admin
port: 8080
- protocol: TCP
name: websecure
port: 4443
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami

View file

@ -1,74 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v3.6
args:
- --api.insecure
- --accesslog
- --entryPoints.web.Address=:8000
- --entryPoints.websecure.Address=:4443
- --providers.kubernetescrd
- --certificatesresolvers.myresolver.acme.tlschallenge
- --certificatesresolvers.myresolver.acme.email=foo@you.com
- --certificatesresolvers.myresolver.acme.storage=acme.json
# Please note that this is the staging Let's Encrypt server.
# Once you get things working, you should remove that whole line altogether.
- --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
ports:
- name: web
containerPort: 8000
- name: websecure
containerPort: 4443
- name: admin
containerPort: 8080
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: whoami
labels:
app: whoami
spec:
replicas: 2
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- name: web
containerPort: 80

View file

@ -1,32 +0,0 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: simpleingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`your.example.com`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`your.example.com`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: myresolver

View file

@ -1,17 +0,0 @@
---
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default
namespace: default
spec:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 # TLS 1.2
- TLS_AES_256_GCM_SHA384 # TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256 # TLS 1.3
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true

View file

@ -1,134 +0,0 @@
---
title: "Traefik CRD TLS Documentation"
description: "Learn how to use Traefik Proxy w/ an IngressRoute Custom Resource Definition (CRD) for Kubernetes, and TLS with Let's Encrypt. Read the technical documentation."
---
# Traefik & CRD & Let's Encrypt
Traefik with an IngressRoute Custom Resource Definition for Kubernetes, and TLS Through Let's Encrypt.
{: .subtitle }
This document is intended to be a fully working example demonstrating how to set up Traefik in [Kubernetes](https://kubernetes.io),
with the dynamic configuration coming from the [IngressRoute Custom Resource](../../providers/kubernetes-crd.md),
and TLS setup with [Let's Encrypt](https://letsencrypt.org).
However, for the sake of simplicity, we're using [k3s](https://github.com/rancher/k3s) docker image for the Kubernetes cluster setup.
Please note that for this setup, given that we're going to use ACME's TLS-ALPN-01 challenge, the host you'll be running it on must be able to receive connections from the outside on port 443.
And of course its internet facing IP address must match the domain name you intend to use.
In the following, the Kubernetes resources defined in YAML configuration files can be applied to the setup in two different ways:
- the first, and usual way, is simply with the `kubectl apply` command.
- the second, which can be used for this tutorial, is to directly place the files in the directory used by the k3s docker image for such inputs (`/var/lib/rancher/k3s/server/manifests`).
!!! important "Kubectl Version"
With the `rancher/k3s` version used in this guide (`0.8.0`), the kubectl version needs to be >= `1.11`.
## k3s Docker-compose Configuration
Our starting point is the docker-compose configuration file, to start the k3s cluster.
You can start it with:
```bash
docker compose -f k3s.yml up
```
```yaml
--8<-- "content/user-guides/crd-acme/k3s.yml"
```
## Cluster Resources
Let's now have a look (in the order they should be applied, if using `kubectl apply`) at all the required resources for the full setup.
### IngressRoute Definition
First, you will need to install Traefik CRDs containing the definition of the `IngressRoute` and the `Middleware` kinds,
and the RBAC authorization resources which will be referenced through the `serviceAccountName` of the deployment.
```bash
# Install Traefik Resource Definitions:
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
# Install RBAC for Traefik:
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml
```
### Services
Then, the services. One for Traefik itself, and one for the app it routes for, i.e. in this case our demo HTTP server: [whoami](https://github.com/traefik/whoami).
```bash
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/user-guides/crd-acme/02-services.yml
```
```yaml
--8<-- "content/user-guides/crd-acme/02-services.yml"
```
### Deployments
Next, the deployments, i.e. the actual pods behind the services.
Again, one pod for Traefik, and one for the whoami app.
```bash
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/user-guides/crd-acme/03-deployments.yml
```
```yaml
--8<-- "content/user-guides/crd-acme/03-deployments.yml"
```
### Port Forwarding
Now, as an exception to what we said above, please note that you should not let the ingressRoute resources below be applied automatically to your cluster.
The reason is, as soon as the ACME provider of Traefik detects we have TLS routers, it will try to generate the certificates for the corresponding domains.
And this will not work, because as it is, our Traefik pod is not reachable from the outside, which will make the ACME TLS challenge fail.
Therefore, for the whole thing to work, we must delay applying the ingressRoute resources until we have port-forwarding set up properly, which is the next step.
```bash
kubectl port-forward --address 0.0.0.0 service/traefik 8000:8000 8080:8080 443:4443 -n default
```
Also, and this is out of the scope of this guide, please note that because of the privileged ports limitation on Linux, the above command might fail to listen on port 443.
In which case you can use tricks such as elevating caps of `kubectl` with `setcaps`, or using `authbind`, or setting up a NAT between your host and the WAN.
Look it up.
### Traefik Routers
We can now finally apply the actual ingressRoutes, with:
```bash
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/user-guides/crd-acme/04-ingressroutes.yml
```
```yaml
--8<-- "content/user-guides/crd-acme/04-ingressroutes.yml"
```
Give it a few seconds for the ACME TLS challenge to complete, and you should then be able to access your whoami pod (routed through Traefik), from the outside.
Both with or (just for fun, do not do that in production) without TLS:
```bash
curl [-k] https://your.example.com/tls
```
```bash
curl http://your.example.com:8000/notls
```
Note that you'll have to use `-k` as long as you're using the staging server of Let's Encrypt, since it is not an authorized certificate authority on systems where it hasn't been manually added.
### Force TLS v1.2+
Nowadays, TLS v1.0 and v1.1 are deprecated.
In order to force TLS v1.2 or later on all your IngressRoute, you can define the `default` TLSOption:
```bash
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.6/docs/content/user-guides/crd-acme/05-tlsoption.yml
```
```yaml
--8<-- "content/user-guides/crd-acme/05-tlsoption.yml"
```

View file

@ -1,30 +0,0 @@
server:
image: rancher/k3s:v1.34.2-k3s1
command: server --disable-agent --no-deploy traefik
environment:
- K3S_CLUSTER_SECRET=somethingtotallyrandom
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
volumes:
# k3s will generate a kubeconfig.yaml in this directory. This volume is mounted
# on your host, so you can then 'export KUBECONFIG=/somewhere/on/your/host/out/kubeconfig.yaml',
# in order for your kubectl commands to work.
- /somewhere/on/your/host/out:/output
# This directory is where you put all the (yaml) configuration files of
# the Kubernetes resources.
- /somewhere/on/your/host/in:/var/lib/rancher/k3s/server/manifests
ports:
- 6443:6443
node:
image: rancher/k3s:v1.34.2-k3s1
privileged: true
links:
- server
environment:
- K3S_URL=https://server:6443
- K3S_CLUSTER_SECRET=somethingtotallyrandom
volumes:
# this is where you would place a alternative traefik image (saved as a .tar file with
# 'docker save'), if you want to use it, instead of the traefik:v3.6 image.
- /somewhere/on/your/host/custom-image:/var/lib/rancher/k3s/agent/images

View file

@ -1,283 +0,0 @@
---
title: "Traefik Proxy gRPC Examples"
description: "This section of the Traefik Proxy documentation explains how to use Traefik as reverse proxy for gRPC applications."
---
# gRPC Examples
## With HTTP (h2c)
This section explains how to use Traefik as reverse proxy for gRPC application.
### Traefik Configuration
Static configuration:
```yaml tab="File (YAML)"
entryPoints:
web:
address: :80
providers:
file:
directory: /path/to/dynamic/config
api: {}
```
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.web]
address = ":80"
[api]
[providers.file]
directory = "/path/to/dynamic/config"
```
```yaml tab="CLI"
--entryPoints.web.address=:80
--providers.file.directory=/path/to/dynamic/config
--api.insecure=true
```
`/path/to/dynamic/config/dynamic_conf.{yml,toml}`:
```yaml tab="YAML"
## dynamic configuration ##
http:
routers:
routerTest:
service: srv-grpc
rule: Host(`frontend.local`)
services:
srv-grpc:
loadBalancer:
servers:
- url: h2c://backend.local:8080
```
```toml tab="TOML"
## dynamic configuration ##
[http]
[http.routers]
[http.routers.routerTest]
service = "srv-grpc"
rule = "Host(`frontend.local`)"
[http.services]
[http.services.srv-grpc]
[http.services.srv-grpc.loadBalancer]
[[http.services.srv-grpc.loadBalancer.servers]]
url = "h2c://backend.local:8080"
```
!!! warning
For providers with labels, you will have to specify the `traefik.http.services.<my-service-name>.loadbalancer.server.scheme=h2c`
### Conclusion
We don't need specific configuration to use gRPC in Traefik, we just need to use `h2c` protocol, or use HTTPS communications to have HTTP2 with the backend.
## With HTTPS
This section explains how to use Traefik as reverse proxy for gRPC application with self-signed certificates.
![gRPC architecture](../assets/img/user-guides/grpc.svg)
### gRPC Server Certificate
In order to secure the gRPC server, we generate a self-signed certificate for service url:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./backend.key -out ./backend.cert
```
That will prompt for information, the important answer is:
```txt
Common Name (e.g. server FQDN or YOUR name) []: backend.local
```
### gRPC Client Certificate
Generate your self-signed certificate for router url:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./frontend.key -out ./frontend.cert
```
with
```txt
Common Name (e.g. server FQDN or YOUR name) []: frontend.local
```
### Traefik Configuration
At last, we configure our Traefik instance to use both self-signed certificates.
Static configuration:
```yaml tab="File (YAML)"
entryPoints:
websecure:
address: :4443
serversTransport:
# For secure connection on backend.local
rootCAs:
- ./backend.cert
providers:
file:
directory: /path/to/dynamic/config
api: {}
```
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.websecure]
address = ":4443"
[serversTransport]
# For secure connection on backend.local
rootCAs = [ "./backend.cert" ]
[api]
[provider.file]
directory = "/path/to/dynamic/config"
```
```yaml tab="CLI"
--entryPoints.websecure.address=:4443
# For secure connection on backend.local
--serversTransport.rootCAs=./backend.cert
--providers.file.directory=/path/to/dynamic/config
--api.insecure=true
```
`/path/to/dynamic/config/dynamic_conf.{yml,toml}`:
```yaml tab="YAML"
## dynamic configuration ##
http:
routers:
routerTest:
service: srv-grpc
rule: Host(`frontend.local`)
services:
srv-grpc:
loadBalancer:
servers:
# Access on backend with HTTPS
- url: https://backend.local:8080
tls:
# For secure connection on frontend.local
certificates:
- certfile: ./frontend.cert
keyfile: ./frontend.key
```
```toml tab="TOML"
## dynamic configuration ##
[http]
[http.routers]
[http.routers.routerTest]
service = "srv-grpc"
rule = "Host(`frontend.local`)"
[http.services]
[http.services.srv-grpc]
[http.services.srv-grpc.loadBalancer]
[[http.services.srv-grpc.loadBalancer.servers]]
# Access on backend with HTTPS
url = "https://backend.local:8080"
[tls]
# For secure connection on frontend.local
[[tls.certificates]]
certFile = "./frontend.cert"
keyFile = "./frontend.key"
```
!!! warning
With some services, the server URLs use the IP, so you may need to configure `insecureSkipVerify` instead of the `rootCAs` to activate HTTPS without hostname verification.
### A gRPC example in go (modify for https)
We use the gRPC greeter example in [grpc-go](https://github.com/grpc/grpc-go/tree/master/examples/helloworld)
!!! warning
In order to use this gRPC example, we need to modify it to use HTTPS
So we modify the "gRPC server example" to use our own self-signed certificate:
```go
// ...
// Read cert and key file
backendCert, _ := os.ReadFile("./backend.cert")
backendKey, _ := os.ReadFile("./backend.key")
// Generate Certificate struct
cert, err := tls.X509KeyPair(backendCert, backendKey)
if err != nil {
log.Fatalf("failed to parse certificate: %v", err)
}
// Create credentials
creds := credentials.NewServerTLSFromCert(&cert)
// Use Credentials in gRPC server options
serverOption := grpc.Creds(creds)
var s *grpc.Server = grpc.NewServer(serverOption)
defer s.Stop()
pb.RegisterGreeterServer(s, &server{})
err := s.Serve(lis)
// ...
```
Next we will modify gRPC Client to use our Traefik self-signed certificate:
```go
// ...
// Read cert file
frontendCert, _ := os.ReadFile("./frontend.cert")
// Create CertPool
roots := x509.NewCertPool()
roots.AppendCertsFromPEM(frontendCert)
// Create credentials
credsClient := credentials.NewClientTLSFromCert(roots, "")
// Dial with specific Transport (with credentials)
conn, err := grpc.Dial("frontend.local:4443", grpc.WithTransportCredentials(credsClient))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := pb.NewGreeterClient(conn)
name := "World"
r, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: name})
// ...
```

View file

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

View file

@ -136,12 +136,15 @@ plugins:
'middlewares/tcp/ipwhitelist.md': 'reference/routing-configuration/tcp/middlewares/ipallowlist.md'
'middlewares/tcp/ipallowlist.md': 'reference/routing-configuration/tcp/middlewares/ipallowlist.md'
## User Guides
'user-guides/crd-acme/index.md': 'expose/kubernetes.md'
'user-guides/cert-manager.md': 'expose/kubernetes.md'
'user-guides/docker-compose/basic-example/index.md': 'expose/docker.md'
'user-guides/docker-compose/acme-tls/index.md': 'expose/docker.md'
'user-guides/docker-compose/acme-http/index.md': 'expose/docker.md'
'user-guides/docker-compose/acme-dns/index.md': 'expose/docker.md'
'user-guides/crd-acme/index.md': 'expose/kubernetes/basic.md'
'user-guides/cert-manager.md': 'expose/kubernetes/advanced.md'
'user-guides/docker-compose/basic-example/index.md': 'expose/docker/basic.md'
'user-guides/docker-compose/acme-tls/index.md': 'expose/docker/basic.md'
'user-guides/docker-compose/acme-http/index.md': 'expose/docker/basic.md'
'user-guides/docker-compose/acme-dns/index.md': 'expose/docker/basic.md'
'user-guides/fastproxy.md': 'reference/install-configuration/experimental/fastproxy.md'
'user-guides/grpc.md': 'expose/overview.md#exposing-grpc-services'
'user-guides/websocket.md': 'expose/overview.md#exposing-websocket-services'
# References
# Static Configuration
'reference/static-configuration/overview.md': 'reference/install-configuration/configuration-options.md'
@ -201,9 +204,15 @@ nav:
- 'Swarm': 'setup/swarm.md'
- 'Expose':
- 'Overview': 'expose/overview.md'
- 'Kubernetes': 'expose/kubernetes.md'
- 'Docker': 'expose/docker.md'
- 'Swarm': 'expose/swarm.md'
- 'Kubernetes':
- 'Basic': 'expose/kubernetes/basic.md'
- 'Advanced': 'expose/kubernetes/advanced.md'
- 'Docker':
- 'Basic': 'expose/docker/basic.md'
- 'Advanced': 'expose/docker/advanced.md'
- 'Swarm':
- 'Basic': 'expose/swarm/basic.md'
- 'Advanced': 'expose/swarm/advanced.md'
- 'Secure':
- '<span class="nav-link-with-icon">Secure Access with JWT <img src="https://doc.traefik.io/traefik-hub/img/ps-traefik-hub-logo-light.svg" class="menu-icon" alt="Traefik Hub API Gateway"></span>': 'secure/secure-api-access-with-jwt.md'
- '<span class="nav-link-with-icon">Secure Access with OIDC <img src="https://doc.traefik.io/traefik-hub/img/ps-traefik-hub-logo-light.svg" class="menu-icon" alt="Traefik Hub API Gateway"></span>': 'secure/secure-api-access-with-oidc.md'
@ -263,6 +272,9 @@ nav:
- 'Tracing': 'reference/install-configuration/observability/tracing.md'
- 'Logs & AccessLogs': 'reference/install-configuration/observability/logs-and-accesslogs.md'
- 'Health Check (CLI & Ping)': 'reference/install-configuration/observability/healthcheck.md'
- 'Experimental':
- 'FastProxy': 'reference/install-configuration/experimental/fastproxy.md'
- 'Plugins': 'reference/install-configuration/experimental/plugins.md'
- 'Options List': 'reference/install-configuration/configuration-options.md'
- 'Routing Configuration':
- 'Common Configuration' :
@ -369,12 +381,6 @@ nav:
- 'Deprecation Notices':
- 'Releases': 'deprecation/releases.md'
- 'Features': 'deprecation/features.md'
- 'User Guides':
- 'FastProxy': 'user-guides/fastproxy.md'
- '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'
- 'Contributing':
- 'Thank You!': 'contributing/thank-you.md'
- 'Submitting Issues': 'contributing/submitting-issues.md'

View file

@ -8,7 +8,7 @@ click==8.1.7
colorama==0.4.6
ghp-import==2.1.0
importlib_metadata==7.1.0
Jinja2==3.1.3
Jinja2==3.1.6
Markdown==3.3.6
MarkupSafe==2.1.5
mergedeep==1.3.4
@ -21,4 +21,4 @@ PyYAML==6.0.1
pyyaml_env_tag==0.1
six==1.16.0
watchdog==4.0.0
zipp==3.18.1
zipp==3.19.1

8
go.mod
View file

@ -37,6 +37,7 @@ require (
github.com/hashicorp/go-version v1.8.0
github.com/hashicorp/nomad/api v0.0.0-20231213195942-64e3dca9274b // No tag on the repo.
github.com/http-wasm/http-wasm-host-go v0.7.0
github.com/huandu/xstrings v1.5.0
github.com/influxdata/influxdb-client-go/v2 v2.7.0
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab // No tag on the repo.
github.com/klauspost/compress v1.18.0
@ -71,6 +72,7 @@ require (
github.com/tidwall/gjson v1.17.0
github.com/traefik/grpc-web v0.16.0
github.com/traefik/paerser v0.2.2
github.com/traefik/traefik/dynamic/ext v0.0.0-00010101000000-000000000000
github.com/traefik/yaegi v0.16.1
github.com/unrolled/render v1.0.2
github.com/unrolled/secure v1.0.9
@ -180,7 +182,7 @@ require (
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/containerd/containerd v1.7.23 // indirect
github.com/containerd/containerd v1.7.29 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
@ -253,7 +255,6 @@ require (
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.182 // indirect
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
github.com/imdario/mergo v0.3.16 // indirect
@ -411,6 +412,9 @@ require (
sigs.k8s.io/randfill v1.0.0 // indirect
)
// Dynamic config extension.
replace github.com/traefik/traefik/dynamic/ext => ./pkg/config/dynamic/ext
// Containous forks
replace (
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e

4
go.sum
View file

@ -297,8 +297,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=

View file

@ -223,6 +223,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of
the referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -1233,6 +1252,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references to
Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -2975,6 +3013,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -3212,6 +3269,24 @@ spec:
Default value is -1, which means unlimited size.
format: int64
type: integer
middlewares:
description: Middlewares defines the list of references to Middleware
resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware resource.
properties:
name:
description: Name defines the name of the referenced Middleware
resource.
type: string
namespace:
description: Namespace defines the namespace of the referenced
Middleware resource.
type: string
required:
- name
type: object
type: array
mirrorBody:
description: |-
MirrorBody defines whether the body of the request should be mirrored.
@ -3299,6 +3374,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.
@ -3687,6 +3781,25 @@ spec:
- Service
- TraefikService
type: string
middlewares:
description: Middlewares defines the list of references
to Middleware resources to apply to the service.
items:
description: MiddlewareRef is a reference to a Middleware
resource.
properties:
name:
description: Name defines the name of the referenced
Middleware resource.
type: string
namespace:
description: Namespace defines the namespace of the
referenced Middleware resource.
type: string
required:
- name
type: object
type: array
name:
description: |-
Name defines the name of the referenced Kubernetes Service or TraefikService.

View file

@ -0,0 +1,35 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[api]
insecure = true
[log]
level = "DEBUG"
noColor = true
[entryPoints]
[entryPoints.web]
address = ":8000"
[providers.file]
filename = "{{ .SelfFilename }}"
## dynamic configuration ##
[http.routers]
[http.routers.router1]
service = "service1"
rule = "Path(`/whoami`)"
[http.middlewares]
[http.middlewares.add-header.headers.customRequestHeaders]
X-Custom-Header = "service-middleware-test"
[http.services]
[http.services.service1]
middlewares = ["add-header"]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "{{ .Server }}"

View file

@ -8,7 +8,7 @@ implementation:
organization: traefik
project: traefik
url: https://traefik.io/
version: v3.6
version: v3.7
kind: ConformanceReport
mode: default
profiles:
@ -30,12 +30,13 @@ profiles:
result: success
statistics:
Failed: 0
Passed: 13
Passed: 15
Skipped: 0
supportedFeatures:
- GatewayPort8080
- HTTPRouteBackendProtocolH2C
- HTTPRouteBackendProtocolWebSocket
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteDestinationPortMatching
- HTTPRouteHostRewrite
- HTTPRouteMethodMatching
@ -50,7 +51,6 @@ profiles:
- GatewayHTTPListenerIsolation
- GatewayInfrastructurePropagation
- GatewayStaticAddresses
- HTTPRouteBackendRequestHeaderModification
- HTTPRouteBackendTimeout
- HTTPRouteCORS
- HTTPRouteNamedRouteRule

View file

@ -2364,3 +2364,37 @@ func (s *SimpleSuite) TestEncodedCharactersDifferentEntryPoints() {
require.NoError(s.T(), err)
}
}
func (s *SimpleSuite) TestServiceMiddleware() {
s.createComposeProject("base")
s.composeUp()
defer s.composeDown()
whoamiIP := s.getComposeServiceIP("whoami1")
file := s.adaptFile("fixtures/service_middleware.toml", struct {
Server string
}{Server: "http://" + whoamiIP})
s.traefikCmd(withConfigFile(file))
// Wait for Traefik to be ready
err := try.GetRequest("http://127.0.0.1:8080/api/http/services", 2*time.Second, try.BodyContains("service1"))
require.NoError(s.T(), err)
// Make a request and verify the middleware added the custom header
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/whoami", nil)
require.NoError(s.T(), err)
response, err := http.DefaultClient.Do(req)
require.NoError(s.T(), err)
assert.Equal(s.T(), http.StatusOK, response.StatusCode)
// Read the response body to check if the whoami service received the custom header
body, err := io.ReadAll(response.Body)
require.NoError(s.T(), err)
// The whoami service should have received the X-Custom-Header that was added by the service middleware
assert.Contains(s.T(), string(body), "X-Custom-Header: service-middleware-test")
}

View file

@ -0,0 +1,7 @@
package ext
// HTTP is a dynamic.HTTP extension.
type HTTP struct{}
// Router is a dynamic.Router extension.
type Router struct{}

View file

@ -0,0 +1,3 @@
module github.com/traefik/traefik/dynamic/ext
go 1.24.0

View file

@ -5,6 +5,7 @@ import (
"time"
ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/dynamic/ext"
otypes "github.com/traefik/traefik/v3/pkg/observability/types"
traefiktls "github.com/traefik/traefik/v3/pkg/tls"
"github.com/traefik/traefik/v3/pkg/types"
@ -33,6 +34,8 @@ const (
// HTTPConfiguration contains all the HTTP configuration parameters.
type HTTPConfiguration struct {
ext.HTTP `yaml:",inline"`
Routers map[string]*Router `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty" export:"true"`
Services map[string]*Service `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty" export:"true"`
Middlewares map[string]*Middleware `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
@ -55,6 +58,7 @@ type Model struct {
// Service holds a service configuration (can only be of one type at the same time).
type Service struct {
Middlewares []string `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
LoadBalancer *ServersLoadBalancer `json:"loadBalancer,omitempty" toml:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty" export:"true"`
HighestRandomWeight *HighestRandomWeight `json:"highestRandomWeight,omitempty" toml:"highestRandomWeight,omitempty" yaml:"highestRandomWeight,omitempty" label:"-" export:"true"`
Weighted *WeightedRoundRobin `json:"weighted,omitempty" toml:"weighted,omitempty" yaml:"weighted,omitempty" label:"-" export:"true"`
@ -62,10 +66,22 @@ type Service struct {
Failover *Failover `json:"failover,omitempty" toml:"failover,omitempty" yaml:"failover,omitempty" label:"-" export:"true"`
}
// Merge merges another Service into this one.
// Returns true if the merge succeeds, false if configurations conflict.
func (s *Service) Merge(other *Service) bool {
if s.LoadBalancer == nil || other.LoadBalancer == nil {
return reflect.DeepEqual(s, other)
}
return s.LoadBalancer.Merge(other.LoadBalancer)
}
// +k8s:deepcopy-gen=true
// Router holds the router configuration.
type Router struct {
ext.Router `yaml:",inline"`
EntryPoints []string `json:"entryPoints,omitempty" toml:"entryPoints,omitempty" yaml:"entryPoints,omitempty" export:"true"`
Middlewares []string `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
Service string `json:"service,omitempty" toml:"service,omitempty" yaml:"service,omitempty" export:"true"`
@ -342,8 +358,39 @@ type ServersLoadBalancer struct {
ServersTransport string `json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty" export:"true"`
}
// Mergeable tells if the given service is mergeable.
func (l *ServersLoadBalancer) Mergeable(loadBalancer *ServersLoadBalancer) bool {
// Merge merges the other load balancer into this one.
// Returns true if merge succeeded, false if configurations conflict.
func (l *ServersLoadBalancer) Merge(other *ServersLoadBalancer) bool {
if !l.mergeable(other) {
return false
}
// Deduplicate and append servers.
uniq := make(map[string]struct{}, len(l.Servers))
for _, server := range l.Servers {
uniq[server.URL] = struct{}{}
}
for _, server := range other.Servers {
if _, ok := uniq[server.URL]; !ok {
l.Servers = append(l.Servers, server)
}
}
return true
}
// SetDefaults Default values for a ServersLoadBalancer.
func (l *ServersLoadBalancer) SetDefaults() {
defaultPassHostHeader := DefaultPassHostHeader
l.PassHostHeader = &defaultPassHostHeader
l.Strategy = BalancerStrategyWRR
l.ResponseForwarding = &ResponseForwarding{}
l.ResponseForwarding.SetDefaults()
}
// mergeable tells if the given service is mergeable.
func (l *ServersLoadBalancer) mergeable(loadBalancer *ServersLoadBalancer) bool {
savedServers := l.Servers
defer func() {
l.Servers = savedServers
@ -359,16 +406,6 @@ func (l *ServersLoadBalancer) Mergeable(loadBalancer *ServersLoadBalancer) bool
return reflect.DeepEqual(l, loadBalancer)
}
// SetDefaults Default values for a ServersLoadBalancer.
func (l *ServersLoadBalancer) SetDefaults() {
defaultPassHostHeader := DefaultPassHostHeader
l.PassHostHeader = &defaultPassHostHeader
l.Strategy = BalancerStrategyWRR
l.ResponseForwarding = &ResponseForwarding{}
l.ResponseForwarding.SetDefaults()
}
// +k8s:deepcopy-gen=true
// ResponseForwarding holds the response forwarding configuration.

View file

@ -35,6 +35,16 @@ type TCPService struct {
Weighted *TCPWeightedRoundRobin `json:"weighted,omitempty" toml:"weighted,omitempty" yaml:"weighted,omitempty" label:"-" export:"true"`
}
// Merge merges another TCPService into this one.
// Returns true if the merge succeeds, false if configurations conflict.
func (s *TCPService) Merge(other *TCPService) bool {
if s.LoadBalancer == nil || other.LoadBalancer == nil {
return reflect.DeepEqual(s, other)
}
return s.LoadBalancer.Merge(other.LoadBalancer)
}
// +k8s:deepcopy-gen=true
// TCPWeightedRoundRobin is a weighted round robin tcp load-balancer of services.
@ -102,8 +112,29 @@ type TCPServersLoadBalancer struct {
HealthCheck *TCPServerHealthCheck `json:"healthCheck,omitempty" toml:"healthCheck,omitempty" yaml:"healthCheck,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"`
}
// Mergeable tells if the given service is mergeable.
func (l *TCPServersLoadBalancer) Mergeable(loadBalancer *TCPServersLoadBalancer) bool {
// Merge merges the other load balancer into this one.
// Returns true if the merge succeeds, false if configurations conflict.
func (l *TCPServersLoadBalancer) Merge(other *TCPServersLoadBalancer) bool {
if !l.mergeable(other) {
return false
}
// Deduplicate and append servers.
uniq := make(map[string]struct{}, len(l.Servers))
for _, server := range l.Servers {
uniq[server.Address] = struct{}{}
}
for _, server := range other.Servers {
if _, ok := uniq[server.Address]; !ok {
l.Servers = append(l.Servers, server)
}
}
return true
}
// mergeable tells if the given service is mergeable.
func (l *TCPServersLoadBalancer) mergeable(loadBalancer *TCPServersLoadBalancer) bool {
savedServers := l.Servers
defer func() {
l.Servers = savedServers

View file

@ -20,6 +20,16 @@ type UDPService struct {
Weighted *UDPWeightedRoundRobin `json:"weighted,omitempty" toml:"weighted,omitempty" yaml:"weighted,omitempty" label:"-" export:"true"`
}
// Merge merges another UDPService into this one.
// Returns true if the merge succeeds, false if configurations conflict.
func (s *UDPService) Merge(other *UDPService) bool {
if s.LoadBalancer == nil || other.LoadBalancer == nil {
return reflect.DeepEqual(s, other)
}
return s.LoadBalancer.Merge(other.LoadBalancer)
}
// +k8s:deepcopy-gen=true
// UDPWeightedRoundRobin is a weighted round robin UDP load-balancer of services.
@ -56,8 +66,29 @@ type UDPServersLoadBalancer struct {
Servers []UDPServer `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server" export:"true"`
}
// Mergeable reports whether the given load-balancer can be merged with the receiver.
func (l *UDPServersLoadBalancer) Mergeable(loadBalancer *UDPServersLoadBalancer) bool {
// Merge merges the other load balancer into this one.
// Returns true if merge succeeded, false if configurations conflict.
func (l *UDPServersLoadBalancer) Merge(other *UDPServersLoadBalancer) bool {
if !l.mergeable(other) {
return false
}
// Deduplicate and append servers.
uniq := make(map[string]struct{}, len(l.Servers))
for _, server := range l.Servers {
uniq[server.Address] = struct{}{}
}
for _, server := range other.Servers {
if _, ok := uniq[server.Address]; !ok {
l.Servers = append(l.Servers, server)
}
}
return true
}
// mergeable reports whether the given load-balancer can be merged with the receiver.
func (l *UDPServersLoadBalancer) mergeable(loadBalancer *UDPServersLoadBalancer) bool {
savedServers := l.Servers
defer func() {
l.Servers = savedServers

View file

@ -489,6 +489,7 @@ func (in *HRWService) DeepCopy() *HRWService {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPConfiguration) DeepCopyInto(out *HTTPConfiguration) {
*out = *in
out.HTTP = in.HTTP
if in.Routers != nil {
in, out := &in.Routers, &out.Routers
*out = make(map[string]*Router, len(*in))
@ -1390,6 +1391,7 @@ func (in *Retry) DeepCopy() *Retry {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Router) DeepCopyInto(out *Router) {
*out = *in
out.Router = in.Router
if in.EntryPoints != nil {
in, out := &in.EntryPoints, &out.EntryPoints
*out = make([]string, len(*in))
@ -1672,6 +1674,11 @@ func (in *ServersTransport) DeepCopy() *ServersTransport {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Service) DeepCopyInto(out *Service) {
*out = *in
if in.Middlewares != nil {
in, out := &in.Middlewares, &out.Middlewares
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.LoadBalancer != nil {
in, out := &in.LoadBalancer, &out.LoadBalancer
*out = new(ServersLoadBalancer)

View file

@ -466,42 +466,52 @@ func TestServiceTCPHealthChecker_Launch(t *testing.T) {
},
}
lb := &testLoadBalancer{}
// Create load balancer with event channel for synchronization.
lb := &testLoadBalancer{
RWMutex: &sync.RWMutex{},
eventCh: make(chan struct{}, len(test.server.StatusSequence)+5),
}
serviceInfo := &truntime.TCPServiceInfo{}
service := NewServiceTCPHealthChecker(ctx, test.config, lb, serviceInfo, targets, "serviceName")
go service.Launch(ctx)
// How much time to wait for the health check to actually complete.
deadline := time.Now().Add(200 * time.Millisecond)
// TLS handshake can take much longer.
// Timeout for each event - TLS handshake can take longer.
eventTimeout := 500 * time.Millisecond
if test.server.TLS {
deadline = time.Now().Add(1000 * time.Millisecond)
eventTimeout = 2 * time.Second
}
// Wait for all health checks to complete deterministically
// Wait for health check events using channel synchronization.
// Iterate over StatusSequence to release each connection via Next().
for i := range test.server.StatusSequence {
test.server.Next()
initialUpserted := lb.numUpsertedServers
initialRemoved := lb.numRemovedServers
for time.Now().Before(deadline) {
time.Sleep(5 * time.Millisecond)
if lb.numUpsertedServers > initialUpserted || lb.numRemovedServers > initialRemoved {
// Stop the health checker immediately after the last expected sequence completes
// to prevent extra health checks from firing and modifying the counters.
if i == len(test.server.StatusSequence)-1 {
cancel()
}
break
select {
case <-lb.eventCh:
// Event received
// On the last iteration, stop the health checker immediately
// to prevent extra checks from modifying the counters.
if i == len(test.server.StatusSequence)-1 {
test.server.Close()
cancel()
}
case <-time.After(eventTimeout):
t.Fatalf("timeout waiting for health check event %d/%d", i+1, len(test.server.StatusSequence))
}
}
assert.Equal(t, test.expNumRemovedServers, lb.numRemovedServers, "removed servers")
assert.Equal(t, test.expNumUpsertedServers, lb.numUpsertedServers, "upserted servers")
// Small delay to let goroutines clean up.
time.Sleep(10 * time.Millisecond)
lb.RLock()
removedServers := lb.numRemovedServers
upsertedServers := lb.numUpsertedServers
lb.RUnlock()
assert.Equal(t, test.expNumRemovedServers, removedServers, "removed servers")
assert.Equal(t, test.expNumUpsertedServers, upsertedServers, "upserted servers")
assert.Equal(t, map[string]string{test.server.Addr.String(): test.targetStatus}, serviceInfo.GetAllStatus())
})
}
@ -597,6 +607,8 @@ type sequencedTCPServer struct {
StatusSequence []tcpMockSequence
TLS bool
release chan struct{}
mu sync.Mutex
listener net.Listener
}
func newTCPServer(t *testing.T, tlsEnabled bool, statusSequence ...tcpMockSequence) *sequencedTCPServer {
@ -624,17 +636,28 @@ func (s *sequencedTCPServer) Next() {
s.release <- struct{}{}
}
func (s *sequencedTCPServer) Close() {
s.mu.Lock()
defer s.mu.Unlock()
if s.listener != nil {
s.listener.Close()
s.listener = nil
}
}
func (s *sequencedTCPServer) Start(t *testing.T) {
t.Helper()
go func() {
var listener net.Listener
for _, seq := range s.StatusSequence {
<-s.release
if listener != nil {
listener.Close()
s.mu.Lock()
if s.listener != nil {
s.listener.Close()
s.listener = nil
}
s.mu.Unlock()
if !seq.accept {
continue
@ -643,7 +666,7 @@ func (s *sequencedTCPServer) Start(t *testing.T) {
lis, err := net.ListenTCP("tcp", s.Addr)
require.NoError(t, err)
listener = lis
var listener net.Listener = lis
if s.TLS {
cert, err := tls.X509KeyPair(localhostCert, localhostKey)
@ -670,8 +693,18 @@ func (s *sequencedTCPServer) Start(t *testing.T) {
)
}
s.mu.Lock()
s.listener = listener
s.mu.Unlock()
conn, err := listener.Accept()
require.NoError(t, err)
if err != nil {
// Listener was closed during shutdown - this is expected behavior.
if strings.Contains(err.Error(), "use of closed network connection") {
return
}
require.NoError(t, err)
}
t.Cleanup(func() {
_ = conn.Close()
})

View file

@ -418,7 +418,12 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
targetURL, timeout := test.server.Start(t, cancel)
lb := &testLoadBalancer{RWMutex: &sync.RWMutex{}}
// Create load balancer with event channel for synchronization.
expectedEvents := test.expNumRemovedServers + test.expNumUpsertedServers
lb := &testLoadBalancer{
RWMutex: &sync.RWMutex{},
eventCh: make(chan struct{}, expectedEvents+5),
}
config := &dynamic.ServerHealthCheck{
Mode: test.mode,
@ -441,18 +446,30 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
wg.Done()
}()
select {
case <-time.After(timeout):
t.Fatal("test did not complete in time")
case <-ctx.Done():
wg.Wait()
// Wait for expected health check events using channel synchronization.
for i := range expectedEvents {
select {
case <-lb.eventCh:
// Event received.
// On the last event, cancel to prevent extra health checks.
if i == expectedEvents-1 {
cancel()
}
case <-time.After(timeout):
t.Fatalf("timeout waiting for health check event %d/%d", i+1, expectedEvents)
}
}
lb.Lock()
defer lb.Unlock()
// Wait for the health checker goroutine to exit before making assertions.
wg.Wait()
assert.Equal(t, test.expNumRemovedServers, lb.numRemovedServers, "removed servers")
assert.Equal(t, test.expNumUpsertedServers, lb.numUpsertedServers, "upserted servers")
lb.RLock()
removedServers := lb.numRemovedServers
upsertedServers := lb.numUpsertedServers
lb.RUnlock()
assert.Equal(t, test.expNumRemovedServers, removedServers, "removed servers")
assert.Equal(t, test.expNumUpsertedServers, upsertedServers, "upserted servers")
assert.InDelta(t, test.expGaugeValue, gauge.GaugeValue, delta, "ServerUp Gauge")
assert.Equal(t, []string{"service", "foobar", "url", targetURL.String()}, gauge.LastLabelValues)
assert.Equal(t, map[string]string{targetURL.String(): test.targetStatus}, serviceInfo.GetAllStatus())

View file

@ -168,14 +168,29 @@ type testLoadBalancer struct {
numRemovedServers int
numUpsertedServers int
// eventCh is used to signal when a status change occurs, allowing tests
// to synchronize with health check events deterministically.
eventCh chan struct{}
}
func (lb *testLoadBalancer) SetStatus(ctx context.Context, childName string, up bool) {
lb.Lock()
if up {
lb.numUpsertedServers++
} else {
lb.numRemovedServers++
}
lb.Unlock()
// Signal the event if a listener is registered.
if lb.eventCh != nil {
select {
case lb.eventCh <- struct{}{}:
default:
// Don't block if channel is full or no listener.
}
}
}
type MetricsMock struct {

View file

@ -13,14 +13,14 @@ const (
typeName = "Chain"
)
type chainBuilder interface {
BuildChain(ctx context.Context, middlewares []string) *alice.Chain
type middlewareChainBuilder interface {
BuildMiddlewareChain(ctx context.Context, middlewares []string) *alice.Chain
}
// New creates a chain middleware.
func New(ctx context.Context, next http.Handler, config dynamic.Chain, builder chainBuilder, name string) (http.Handler, error) {
func New(ctx context.Context, next http.Handler, config dynamic.Chain, builder middlewareChainBuilder, name string) (http.Handler, error) {
middlewares.GetLogger(ctx, name, typeName).Debug().Msg("Creating middleware")
middlewareChain := builder.BuildChain(ctx, config.Middlewares)
middlewareChain := builder.BuildMiddlewareChain(ctx, config.Middlewares)
return middlewareChain.Then(next)
}

View file

@ -3,6 +3,7 @@ package metrics
import (
"context"
"errors"
"strings"
"time"
"github.com/go-kit/kit/metrics/influx"
@ -138,11 +139,16 @@ func newInfluxDB2Client(config *otypes.InfluxDB2) (influxdb2.Client, error) {
return nil, errors.New("token, org or bucket property is missing")
}
token, err := config.Token.Read()
if err != nil {
return nil, err
}
// Disable InfluxDB2 logs.
// See https://github.com/influxdata/influxdb-client-go/blob/v2.7.0/options.go#L128
influxdb2log.Log = nil
return influxdb2.NewClient(config.Address, config.Token), nil
return influxdb2.NewClient(config.Address, strings.TrimSpace(string(token))), nil
}
type influxDB2Writer struct {

View file

@ -413,13 +413,13 @@ func TestPrometheusMetricRemoval(t *testing.T) {
th.WithRouter("foo@providerName", th.WithServiceName("bar")),
th.WithRouter("router2", th.WithServiceName("bar@providerName")),
),
th.WithLoadBalancerServices(
th.WithService("bar@providerName", th.WithServers(
th.WithServices(
th.WithService("bar@providerName", th.WithServiceServersLoadBalancer(th.WithServers(
th.WithServer("http://localhost:9000"),
th.WithServer("http://localhost:9999"),
th.WithServer("http://localhost:9998"),
)),
th.WithService("service1", th.WithServers(th.WithServer("http://localhost:9000"))),
))),
th.WithService("service1", th.WithServiceServersLoadBalancer(th.WithServers(th.WithServer("http://localhost:9000")))),
),
),
}
@ -429,8 +429,8 @@ func TestPrometheusMetricRemoval(t *testing.T) {
th.WithRouters(
th.WithRouter("foo@providerName", th.WithServiceName("bar")),
),
th.WithLoadBalancerServices(
th.WithService("bar@providerName", th.WithServers(th.WithServer("http://localhost:9000"))),
th.WithServices(
th.WithService("bar@providerName", th.WithServiceServersLoadBalancer(th.WithServers(th.WithServer("http://localhost:9000")))),
),
),
}
@ -500,8 +500,8 @@ func TestPrometheusMetricRemoveEndpointForRecoveredService(t *testing.T) {
conf1 := dynamic.Configuration{
HTTP: th.BuildConfiguration(
th.WithLoadBalancerServices(
th.WithService("service1", th.WithServers(th.WithServer("http://localhost:9000"))),
th.WithServices(
th.WithService("service1", th.WithServiceServersLoadBalancer(th.WithServers(th.WithServer("http://localhost:9000")))),
),
),
}
@ -512,8 +512,8 @@ func TestPrometheusMetricRemoveEndpointForRecoveredService(t *testing.T) {
conf3 := dynamic.Configuration{
HTTP: th.BuildConfiguration(
th.WithLoadBalancerServices(
th.WithService("service1", th.WithServers(th.WithServer("http://localhost:9001"))),
th.WithServices(
th.WithService("service1", th.WithServiceServersLoadBalancer(th.WithServers(th.WithServer("http://localhost:9001")))),
),
),
}
@ -539,8 +539,8 @@ func TestPrometheusRemovedMetricsReset(t *testing.T) {
conf1 := dynamic.Configuration{
HTTP: th.BuildConfiguration(
th.WithLoadBalancerServices(th.WithService("service",
th.WithServers(th.WithServer("http://localhost:9000"))),
th.WithServices(
th.WithService("service", th.WithServiceServersLoadBalancer(th.WithServers(th.WithServer("http://localhost:9000")))),
),
),
}

View file

@ -6,6 +6,7 @@ import (
"time"
"github.com/traefik/paerser/types"
tTypes "github.com/traefik/traefik/v3/pkg/types"
)
// Metrics provides options to expose and send Traefik metrics to different third party monitoring systems.
@ -87,15 +88,15 @@ func (s *Statsd) SetDefaults() {
// InfluxDB2 contains address, token and metrics pushing interval configuration.
type InfluxDB2 struct {
Address string `description:"InfluxDB v2 address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
Token string `description:"InfluxDB v2 access token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
PushInterval types.Duration `description:"InfluxDB v2 push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"`
Org string `description:"InfluxDB v2 org ID." json:"org,omitempty" toml:"org,omitempty" yaml:"org,omitempty" export:"true"`
Bucket string `description:"InfluxDB v2 bucket ID." json:"bucket,omitempty" toml:"bucket,omitempty" yaml:"bucket,omitempty" export:"true"`
AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"`
AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"`
AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"`
AdditionalLabels map[string]string `description:"Additional labels (influxdb tags) on all metrics" json:"additionalLabels,omitempty" toml:"additionalLabels,omitempty" yaml:"additionalLabels,omitempty" export:"true"`
Address string `description:"InfluxDB v2 address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
Token tTypes.FileOrContent `description:"InfluxDB v2 access token. It accepts either a token value or a file path to the token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
PushInterval types.Duration `description:"InfluxDB v2 push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"`
Org string `description:"InfluxDB v2 org ID." json:"org,omitempty" toml:"org,omitempty" yaml:"org,omitempty" export:"true"`
Bucket string `description:"InfluxDB v2 bucket ID." json:"bucket,omitempty" toml:"bucket,omitempty" yaml:"bucket,omitempty" export:"true"`
AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"`
AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"`
AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"`
AdditionalLabels map[string]string `description:"Additional labels (influxdb tags) on all metrics" json:"additionalLabels,omitempty" toml:"additionalLabels,omitempty" yaml:"additionalLabels,omitempty" export:"true"`
}
// SetDefaults sets the default values.

View file

@ -58,7 +58,7 @@ func (a *Account) GetPrivateKey() crypto.PrivateKey {
privateKey, err := x509.ParsePKCS1PrivateKey(a.PrivateKey)
if err != nil {
log.Error().Str(logs.ProviderName, "acme").
Err(err).Msgf("Cannot unmarshal private key %+v", a.PrivateKey)
Err(err).Msg("Cannot unmarshal private key")
return nil
}

View file

@ -812,8 +812,8 @@ func getCertificateRenewDurations(certificatesDuration int) (time.Duration, time
return 30 * 24 * time.Hour, 24 * time.Hour // 30 days, 1 day
case certificatesDuration >= 30*24: // >= 30 days
return 10 * 24 * time.Hour, 12 * time.Hour // 10 days, 12 hours
case certificatesDuration >= 7*24: // >= 7 days
return 24 * time.Hour, time.Hour // 1 days, 1 hour
case certificatesDuration >= 6*24: // >= 6 days
return 2 * 24 * time.Hour, 2 * time.Hour // 2 days, 2 hours
case certificatesDuration >= 24: // >= 1 days
return 6 * time.Hour, 10 * time.Minute // 6 hours, 10 minutes
default:

View file

@ -612,6 +612,12 @@ func Test_getCertificateRenewDurations(t *testing.T) {
expectRenewPeriod: time.Hour * 24 * 30,
expectRenewInterval: time.Hour * 24,
},
{
desc: "45 Days certificates (Let's Encrypt 2028 standard): 10 days renew period, 12 hour renew interval",
certificatesDurations: 24 * 45,
expectRenewPeriod: time.Hour * 24 * 10,
expectRenewInterval: time.Hour * 12,
},
{
desc: "30 Days certificates: 10 days renew period, 12 hour renew interval",
certificatesDurations: 24 * 30,
@ -619,10 +625,16 @@ func Test_getCertificateRenewDurations(t *testing.T) {
expectRenewInterval: time.Hour * 12,
},
{
desc: "7 Days certificates: 1 days renew period, 1 hour renew interval",
desc: "7 Days certificates: 2 days renew period, 2 hour renew interval",
certificatesDurations: 24 * 7,
expectRenewPeriod: time.Hour * 24,
expectRenewInterval: time.Hour,
expectRenewPeriod: time.Hour * 24 * 2,
expectRenewInterval: time.Hour * 2,
},
{
desc: "160 hour certificate (Let's Encrypt 'shortlived' profile): 2 days renew period, 2 hour renew interval",
certificatesDurations: 160,
expectRenewPeriod: time.Hour * 24 * 2,
expectRenewInterval: time.Hour * 2,
},
{
desc: "24 Hours certificates: 6 hours renew period, 10 minutes renew interval",

View file

@ -4,7 +4,6 @@ import (
"bytes"
"context"
"maps"
"reflect"
"slices"
"strings"
"text/template"
@ -14,388 +13,8 @@ import (
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/observability/logs"
"github.com/traefik/traefik/v3/pkg/tls"
)
// Merge merges multiple configurations.
func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration) *dynamic.Configuration {
logger := log.Ctx(ctx)
configuration := &dynamic.Configuration{
HTTP: &dynamic.HTTPConfiguration{
Routers: make(map[string]*dynamic.Router),
Middlewares: make(map[string]*dynamic.Middleware),
Services: make(map[string]*dynamic.Service),
ServersTransports: make(map[string]*dynamic.ServersTransport),
},
TCP: &dynamic.TCPConfiguration{
Routers: make(map[string]*dynamic.TCPRouter),
Services: make(map[string]*dynamic.TCPService),
Middlewares: make(map[string]*dynamic.TCPMiddleware),
ServersTransports: make(map[string]*dynamic.TCPServersTransport),
},
UDP: &dynamic.UDPConfiguration{
Routers: make(map[string]*dynamic.UDPRouter),
Services: make(map[string]*dynamic.UDPService),
},
TLS: &dynamic.TLSConfiguration{
Stores: make(map[string]tls.Store),
},
}
servicesToDelete := map[string]struct{}{}
services := map[string][]string{}
routersToDelete := map[string]struct{}{}
routers := map[string][]string{}
servicesTCPToDelete := map[string]struct{}{}
servicesTCP := map[string][]string{}
routersTCPToDelete := map[string]struct{}{}
routersTCP := map[string][]string{}
servicesUDPToDelete := map[string]struct{}{}
servicesUDP := map[string][]string{}
routersUDPToDelete := map[string]struct{}{}
routersUDP := map[string][]string{}
middlewaresToDelete := map[string]struct{}{}
middlewares := map[string][]string{}
middlewaresTCPToDelete := map[string]struct{}{}
middlewaresTCP := map[string][]string{}
transportsToDelete := map[string]struct{}{}
transports := map[string][]string{}
transportsTCPToDelete := map[string]struct{}{}
transportsTCP := map[string][]string{}
storesToDelete := map[string]struct{}{}
stores := map[string][]string{}
var sortedKeys []string
for key := range configurations {
sortedKeys = append(sortedKeys, key)
}
slices.Sort(sortedKeys)
for _, root := range sortedKeys {
conf := configurations[root]
for serviceName, service := range conf.HTTP.Services {
services[serviceName] = append(services[serviceName], root)
if !AddService(configuration.HTTP, serviceName, service) {
servicesToDelete[serviceName] = struct{}{}
}
}
for routerName, router := range conf.HTTP.Routers {
routers[routerName] = append(routers[routerName], root)
if !AddRouter(configuration.HTTP, routerName, router) {
routersToDelete[routerName] = struct{}{}
}
}
for transportName, transport := range conf.HTTP.ServersTransports {
transports[transportName] = append(transports[transportName], root)
if !AddTransport(configuration.HTTP, transportName, transport) {
transportsToDelete[transportName] = struct{}{}
}
}
for serviceName, service := range conf.TCP.Services {
servicesTCP[serviceName] = append(servicesTCP[serviceName], root)
if !AddServiceTCP(configuration.TCP, serviceName, service) {
servicesTCPToDelete[serviceName] = struct{}{}
}
}
for routerName, router := range conf.TCP.Routers {
routersTCP[routerName] = append(routersTCP[routerName], root)
if !AddRouterTCP(configuration.TCP, routerName, router) {
routersTCPToDelete[routerName] = struct{}{}
}
}
for transportName, transport := range conf.TCP.ServersTransports {
transportsTCP[transportName] = append(transportsTCP[transportName], root)
if !AddTransportTCP(configuration.TCP, transportName, transport) {
transportsTCPToDelete[transportName] = struct{}{}
}
}
for serviceName, service := range conf.UDP.Services {
servicesUDP[serviceName] = append(servicesUDP[serviceName], root)
if !AddServiceUDP(configuration.UDP, serviceName, service) {
servicesUDPToDelete[serviceName] = struct{}{}
}
}
for routerName, router := range conf.UDP.Routers {
routersUDP[routerName] = append(routersUDP[routerName], root)
if !AddRouterUDP(configuration.UDP, routerName, router) {
routersUDPToDelete[routerName] = struct{}{}
}
}
for middlewareName, middleware := range conf.HTTP.Middlewares {
middlewares[middlewareName] = append(middlewares[middlewareName], root)
if !AddMiddleware(configuration.HTTP, middlewareName, middleware) {
middlewaresToDelete[middlewareName] = struct{}{}
}
}
for middlewareName, middleware := range conf.TCP.Middlewares {
middlewaresTCP[middlewareName] = append(middlewaresTCP[middlewareName], root)
if !AddMiddlewareTCP(configuration.TCP, middlewareName, middleware) {
middlewaresTCPToDelete[middlewareName] = struct{}{}
}
}
for storeName, store := range conf.TLS.Stores {
stores[storeName] = append(stores[storeName], root)
if !AddStore(configuration.TLS, storeName, store) {
storesToDelete[storeName] = struct{}{}
}
}
}
for serviceName := range servicesToDelete {
logger.Error().Str(logs.ServiceName, serviceName).
Interface("configuration", services[serviceName]).
Msg("Service defined multiple times with different configurations")
delete(configuration.HTTP.Services, serviceName)
}
for routerName := range routersToDelete {
logger.Error().Str(logs.RouterName, routerName).
Interface("configuration", routers[routerName]).
Msg("Router defined multiple times with different configurations")
delete(configuration.HTTP.Routers, routerName)
}
for transportName := range transportsToDelete {
logger.Error().Str(logs.ServersTransportName, transportName).
Interface("configuration", transports[transportName]).
Msg("ServersTransport defined multiple times with different configurations")
delete(configuration.HTTP.ServersTransports, transportName)
}
for serviceName := range servicesTCPToDelete {
logger.Error().Str(logs.ServiceName, serviceName).
Interface("configuration", servicesTCP[serviceName]).
Msg("Service TCP defined multiple times with different configurations")
delete(configuration.TCP.Services, serviceName)
}
for routerName := range routersTCPToDelete {
logger.Error().Str(logs.RouterName, routerName).
Interface("configuration", routersTCP[routerName]).
Msg("Router TCP defined multiple times with different configurations")
delete(configuration.TCP.Routers, routerName)
}
for transportName := range transportsTCPToDelete {
logger.Error().Str(logs.ServersTransportName, transportName).
Interface("configuration", transportsTCP[transportName]).
Msg("ServersTransport TCP defined multiple times with different configurations")
delete(configuration.TCP.ServersTransports, transportName)
}
for serviceName := range servicesUDPToDelete {
logger.Error().Str(logs.ServiceName, serviceName).
Interface("configuration", servicesUDP[serviceName]).
Msg("UDP service defined multiple times with different configurations")
delete(configuration.UDP.Services, serviceName)
}
for routerName := range routersUDPToDelete {
logger.Error().Str(logs.RouterName, routerName).
Interface("configuration", routersUDP[routerName]).
Msg("UDP router defined multiple times with different configurations")
delete(configuration.UDP.Routers, routerName)
}
for middlewareName := range middlewaresToDelete {
logger.Error().Str(logs.MiddlewareName, middlewareName).
Interface("configuration", middlewares[middlewareName]).
Msg("Middleware defined multiple times with different configurations")
delete(configuration.HTTP.Middlewares, middlewareName)
}
for middlewareName := range middlewaresTCPToDelete {
logger.Error().Str(logs.MiddlewareName, middlewareName).
Interface("configuration", middlewaresTCP[middlewareName]).
Msg("TCP Middleware defined multiple times with different configurations")
delete(configuration.TCP.Middlewares, middlewareName)
}
for storeName := range storesToDelete {
logger.Error().Str("storeName", storeName).
Msgf("TLS store defined multiple times with different configurations in %v", stores[storeName])
delete(configuration.TLS.Stores, storeName)
}
return configuration
}
// AddServiceTCP adds a service to a configuration.
func AddServiceTCP(configuration *dynamic.TCPConfiguration, serviceName string, service *dynamic.TCPService) bool {
if _, ok := configuration.Services[serviceName]; !ok {
configuration.Services[serviceName] = service
return true
}
if !configuration.Services[serviceName].LoadBalancer.Mergeable(service.LoadBalancer) {
return false
}
uniq := map[string]struct{}{}
for _, server := range configuration.Services[serviceName].LoadBalancer.Servers {
uniq[server.Address] = struct{}{}
}
for _, server := range service.LoadBalancer.Servers {
if _, ok := uniq[server.Address]; !ok {
configuration.Services[serviceName].LoadBalancer.Servers = append(configuration.Services[serviceName].LoadBalancer.Servers, server)
}
}
return true
}
// AddRouterTCP adds a router to a configuration.
func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, router *dynamic.TCPRouter) bool {
if _, ok := configuration.Routers[routerName]; !ok {
configuration.Routers[routerName] = router
return true
}
return reflect.DeepEqual(configuration.Routers[routerName], router)
}
// AddMiddlewareTCP adds a middleware to a configuration.
func AddMiddlewareTCP(configuration *dynamic.TCPConfiguration, middlewareName string, middleware *dynamic.TCPMiddleware) bool {
if _, ok := configuration.Middlewares[middlewareName]; !ok {
configuration.Middlewares[middlewareName] = middleware
return true
}
return reflect.DeepEqual(configuration.Middlewares[middlewareName], middleware)
}
// AddTransportTCP adds a servers transport to a configuration.
func AddTransportTCP(configuration *dynamic.TCPConfiguration, transportName string, transport *dynamic.TCPServersTransport) bool {
if _, ok := configuration.ServersTransports[transportName]; !ok {
configuration.ServersTransports[transportName] = transport
return true
}
return reflect.DeepEqual(configuration.ServersTransports[transportName], transport)
}
// AddServiceUDP adds a service to a configuration.
func AddServiceUDP(configuration *dynamic.UDPConfiguration, serviceName string, service *dynamic.UDPService) bool {
if _, ok := configuration.Services[serviceName]; !ok {
configuration.Services[serviceName] = service
return true
}
if !configuration.Services[serviceName].LoadBalancer.Mergeable(service.LoadBalancer) {
return false
}
uniq := map[string]struct{}{}
for _, server := range configuration.Services[serviceName].LoadBalancer.Servers {
uniq[server.Address] = struct{}{}
}
for _, server := range service.LoadBalancer.Servers {
if _, ok := uniq[server.Address]; !ok {
configuration.Services[serviceName].LoadBalancer.Servers = append(configuration.Services[serviceName].LoadBalancer.Servers, server)
}
}
return true
}
// AddRouterUDP adds a router to a configuration.
func AddRouterUDP(configuration *dynamic.UDPConfiguration, routerName string, router *dynamic.UDPRouter) bool {
if _, ok := configuration.Routers[routerName]; !ok {
configuration.Routers[routerName] = router
return true
}
return reflect.DeepEqual(configuration.Routers[routerName], router)
}
// AddService adds a service to a configuration.
func AddService(configuration *dynamic.HTTPConfiguration, serviceName string, service *dynamic.Service) bool {
if _, ok := configuration.Services[serviceName]; !ok {
configuration.Services[serviceName] = service
return true
}
if !configuration.Services[serviceName].LoadBalancer.Mergeable(service.LoadBalancer) {
return false
}
uniq := map[string]struct{}{}
for _, server := range configuration.Services[serviceName].LoadBalancer.Servers {
uniq[server.URL] = struct{}{}
}
for _, server := range service.LoadBalancer.Servers {
if _, ok := uniq[server.URL]; !ok {
configuration.Services[serviceName].LoadBalancer.Servers = append(configuration.Services[serviceName].LoadBalancer.Servers, server)
}
}
return true
}
// AddRouter adds a router to a configuration.
func AddRouter(configuration *dynamic.HTTPConfiguration, routerName string, router *dynamic.Router) bool {
if _, ok := configuration.Routers[routerName]; !ok {
configuration.Routers[routerName] = router
return true
}
return reflect.DeepEqual(configuration.Routers[routerName], router)
}
// AddTransport adds a servers transport to a configuration.
func AddTransport(configuration *dynamic.HTTPConfiguration, transportName string, transport *dynamic.ServersTransport) bool {
if _, ok := configuration.ServersTransports[transportName]; !ok {
configuration.ServersTransports[transportName] = transport
return true
}
return reflect.DeepEqual(configuration.ServersTransports[transportName], transport)
}
// AddMiddleware adds a middleware to a configuration.
func AddMiddleware(configuration *dynamic.HTTPConfiguration, middlewareName string, middleware *dynamic.Middleware) bool {
if _, ok := configuration.Middlewares[middlewareName]; !ok {
configuration.Middlewares[middlewareName] = middleware
return true
}
return reflect.DeepEqual(configuration.Middlewares[middlewareName], middleware)
}
// AddStore adds a middleware to a configurations.
func AddStore(configuration *dynamic.TLSConfiguration, storeName string, store tls.Store) bool {
if _, ok := configuration.Stores[storeName]; !ok {
configuration.Stores[storeName] = store
return true
}
return reflect.DeepEqual(configuration.Stores[storeName], store)
}
// MakeDefaultRuleTemplate creates the default rule template.
func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*template.Template, error) {
defaultFuncMap := sprig.TxtFuncMap()

View file

@ -106,7 +106,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, items []itemData, cer
configurations[svcName] = confFromLabel
}
return provider.Merge(ctx, configurations)
return provider.Merge(ctx, provider.NameSortedConfigurations(configurations), provider.ResourceStrategyMerge)
}
func (p *Provider) keepContainer(ctx context.Context, item itemData) bool {

View file

@ -10,8 +10,9 @@ import (
// connectCert holds our certificates as a client of the Consul Connect protocol.
type connectCert struct {
root []string
leaf keyPair
trustDomain string
root []string
leaf keyPair
}
func (c *connectCert) getRoot() []types.FileOrContent {
@ -52,7 +53,8 @@ func (c *connectCert) equals(other *connectCert) bool {
}
func (c *connectCert) serversTransport(item itemData) *dynamic.ServersTransport {
spiffeID := fmt.Sprintf("spiffe:///ns/%s/dc/%s/svc/%s",
spiffeID := fmt.Sprintf("spiffe://%s/ns/%s/dc/%s/svc/%s",
c.trustDomain,
item.Namespace,
item.Datacenter,
item.Name,
@ -72,7 +74,8 @@ func (c *connectCert) serversTransport(item itemData) *dynamic.ServersTransport
}
func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTransport {
spiffeID := fmt.Sprintf("spiffe:///ns/%s/dc/%s/svc/%s",
spiffeID := fmt.Sprintf("spiffe://%s/ns/%s/dc/%s/svc/%s",
c.trustDomain,
item.Namespace,
item.Datacenter,
item.Name,

View file

@ -465,7 +465,7 @@ func (p *Provider) watchConnectTLS(ctx context.Context) error {
}
leafWatcher.HybridHandler = leafWatcherHandler(ctx, leafChan)
rootsChan := make(chan []string)
rootsChan := make(chan caRootList)
rootsWatcher, err := watch.Parse(map[string]any{
"type": "connect_roots",
})
@ -497,9 +497,9 @@ func (p *Provider) watchConnectTLS(ctx context.Context) error {
}()
var (
certInfo *connectCert
leafCerts keyPair
rootCerts []string
certInfo *connectCert
leafCert keyPair
caRoots caRootList
)
for {
@ -510,13 +510,14 @@ func (p *Provider) watchConnectTLS(ctx context.Context) error {
case err := <-errChan:
return fmt.Errorf("leaf or roots watcher terminated: %w", err)
case rootCerts = <-rootsChan:
case leafCerts = <-leafChan:
case caRoots = <-rootsChan:
case leafCert = <-leafChan:
}
newCertInfo := &connectCert{
root: rootCerts,
leaf: leafCerts,
trustDomain: caRoots.trustDomain,
root: caRoots.roots,
leaf: leafCert,
}
if newCertInfo.isReady() && !newCertInfo.equals(certInfo) {
log.Ctx(ctx).Debug().Msgf("Updating connect certs for service %s", p.ServiceName)
@ -546,7 +547,12 @@ func (p *Provider) includesHealthStatus(status string) bool {
return false
}
func rootsWatchHandler(ctx context.Context, dest chan<- []string) func(watch.BlockingParamVal, any) {
type caRootList struct {
trustDomain string
roots []string
}
func rootsWatchHandler(ctx context.Context, dest chan<- caRootList) func(watch.BlockingParamVal, any) {
return func(_ watch.BlockingParamVal, raw any) {
if raw == nil {
log.Ctx(ctx).Error().Msg("Root certificate watcher called with nil")
@ -566,7 +572,7 @@ func rootsWatchHandler(ctx context.Context, dest chan<- []string) func(watch.Blo
select {
case <-ctx.Done():
case dest <- roots:
case dest <- caRootList{trustDomain: v.TrustDomain, roots: roots}:
}
}
}

View file

@ -101,7 +101,7 @@ func (p *DynConfBuilder) build(ctx context.Context, containersInspected []docker
configurations[containerName] = confFromLabel
}
return provider.Merge(ctx, configurations)
return provider.Merge(ctx, provider.NameSortedConfigurations(configurations), provider.ResourceStrategyMerge)
}
func (p *DynConfBuilder) buildTCPServiceConfiguration(ctx context.Context, container dockerData, configuration *dynamic.TCPConfiguration) error {

View file

@ -86,7 +86,7 @@ func (p *Provider) buildConfiguration(ctx context.Context, instances []ecsInstan
configurations[instanceName] = confFromLabel
}
return provider.Merge(ctx, configurations)
return provider.Merge(ctx, provider.NameSortedConfigurations(configurations), provider.ResourceStrategyMerge)
}
func (p *Provider) buildTCPServiceConfiguration(instance ecsInstance, configuration *dynamic.TCPConfiguration) error {

View file

@ -221,7 +221,12 @@ func (p *Provider) buildConfiguration() (*dynamic.Configuration, error) {
ctx := log.With().Str(logs.ProviderName, providerName).Logger().WithContext(context.Background())
if len(p.Directory) > 0 {
return p.loadFileConfigFromDirectory(ctx, p.Directory, nil)
configurations, err := p.collectFileConfigs(ctx, p.Directory, "")
if err != nil {
return nil, fmt.Errorf("collecting file configs: %w", err)
}
return provider.Merge(ctx, configurations, provider.ResourceStrategySkipDuplicates), nil
}
if len(p.Filename) > 0 {
@ -376,47 +381,28 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem
return configuration, nil
}
func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory string, configuration *dynamic.Configuration) (*dynamic.Configuration, error) {
// collectFileConfigs recursively collects configurations from files in the given directory.
func (p *Provider) collectFileConfigs(ctx context.Context, directory, prefix string) ([]provider.NamedConfiguration, error) {
var configurations []provider.NamedConfiguration
fileList, err := os.ReadDir(directory)
if err != nil {
return configuration, fmt.Errorf("unable to read directory %s: %w", directory, err)
return nil, fmt.Errorf("reading directory %s: %w", directory, err)
}
if configuration == nil {
configuration = &dynamic.Configuration{
HTTP: &dynamic.HTTPConfiguration{
Routers: make(map[string]*dynamic.Router),
Middlewares: make(map[string]*dynamic.Middleware),
Services: make(map[string]*dynamic.Service),
ServersTransports: make(map[string]*dynamic.ServersTransport),
},
TCP: &dynamic.TCPConfiguration{
Routers: make(map[string]*dynamic.TCPRouter),
Services: make(map[string]*dynamic.TCPService),
Middlewares: make(map[string]*dynamic.TCPMiddleware),
ServersTransports: make(map[string]*dynamic.TCPServersTransport),
},
TLS: &dynamic.TLSConfiguration{
Stores: make(map[string]tls.Store),
Options: make(map[string]tls.Options),
},
UDP: &dynamic.UDPConfiguration{
Routers: make(map[string]*dynamic.UDPRouter),
Services: make(map[string]*dynamic.UDPService),
},
}
}
configTLSMaps := make(map[*tls.CertAndStores]struct{})
for _, item := range fileList {
logger := log.Ctx(ctx).With().Str("filename", item.Name()).Logger()
itemPath := filepath.Join(directory, item.Name())
filename := item.Name()
if prefix != "" {
filename = filepath.Join(prefix, item.Name())
}
if item.IsDir() {
configuration, err = p.loadFileConfigFromDirectory(logger.WithContext(ctx), filepath.Join(directory, item.Name()), configuration)
sub, err := p.collectFileConfigs(ctx, itemPath, filename)
if err != nil {
return configuration, fmt.Errorf("unable to load content configuration from subdirectory %s: %w", item, err)
return nil, fmt.Errorf("loading content configuration from subdirectory %s: %w", item, err)
}
configurations = append(configurations, sub...)
continue
}
@ -427,132 +413,18 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
continue
}
var c *dynamic.Configuration
c, err = p.loadFileConfig(logger.WithContext(ctx), filepath.Join(directory, item.Name()), true)
c, err := p.loadFileConfig(ctx, itemPath, true)
if err != nil {
return configuration, fmt.Errorf("%s: %w", filepath.Join(directory, item.Name()), err)
return nil, fmt.Errorf("%s: %w", itemPath, err)
}
for name, conf := range c.HTTP.Routers {
if _, exists := configuration.HTTP.Routers[name]; exists {
logger.Warn().Str(logs.RouterName, name).Msg("HTTP router already configured, skipping")
} else {
configuration.HTTP.Routers[name] = conf
}
}
for name, conf := range c.HTTP.Middlewares {
if _, exists := configuration.HTTP.Middlewares[name]; exists {
logger.Warn().Str(logs.MiddlewareName, name).Msg("HTTP middleware already configured, skipping")
} else {
configuration.HTTP.Middlewares[name] = conf
}
}
for name, conf := range c.HTTP.Services {
if _, exists := configuration.HTTP.Services[name]; exists {
logger.Warn().Str(logs.ServiceName, name).Msg("HTTP service already configured, skipping")
} else {
configuration.HTTP.Services[name] = conf
}
}
for name, conf := range c.HTTP.ServersTransports {
if _, exists := configuration.HTTP.ServersTransports[name]; exists {
logger.Warn().Str(logs.ServersTransportName, name).Msg("HTTP servers transport already configured, skipping")
} else {
configuration.HTTP.ServersTransports[name] = conf
}
}
for name, conf := range c.TCP.Routers {
if _, exists := configuration.TCP.Routers[name]; exists {
logger.Warn().Str(logs.RouterName, name).Msg("TCP router already configured, skipping")
} else {
configuration.TCP.Routers[name] = conf
}
}
for name, conf := range c.TCP.Middlewares {
if _, exists := configuration.TCP.Middlewares[name]; exists {
logger.Warn().Str(logs.MiddlewareName, name).Msg("TCP middleware already configured, skipping")
} else {
configuration.TCP.Middlewares[name] = conf
}
}
for name, conf := range c.TCP.Services {
if _, exists := configuration.TCP.Services[name]; exists {
logger.Warn().Str(logs.ServiceName, name).Msg("TCP service already configured, skipping")
} else {
configuration.TCP.Services[name] = conf
}
}
for name, conf := range c.TCP.ServersTransports {
if _, exists := configuration.TCP.ServersTransports[name]; exists {
logger.Warn().Str(logs.ServersTransportName, name).Msg("TCP servers transport already configured, skipping")
} else {
configuration.TCP.ServersTransports[name] = conf
}
}
for name, conf := range c.UDP.Routers {
if _, exists := configuration.UDP.Routers[name]; exists {
logger.Warn().Str(logs.RouterName, name).Msg("UDP router already configured, skipping")
} else {
configuration.UDP.Routers[name] = conf
}
}
for name, conf := range c.UDP.Services {
if _, exists := configuration.UDP.Services[name]; exists {
logger.Warn().Str(logs.ServiceName, name).Msg("UDP service already configured, skipping")
} else {
configuration.UDP.Services[name] = conf
}
}
for _, conf := range c.TLS.Certificates {
if _, exists := configTLSMaps[conf]; exists {
logger.Warn().Msgf("TLS configuration %v already configured, skipping", conf)
} else {
configTLSMaps[conf] = struct{}{}
}
}
for name, conf := range c.TLS.Options {
if _, exists := configuration.TLS.Options[name]; exists {
logger.Warn().Msgf("TLS options %v already configured, skipping", name)
} else {
if configuration.TLS.Options == nil {
configuration.TLS.Options = map[string]tls.Options{}
}
configuration.TLS.Options[name] = conf
}
}
for name, conf := range c.TLS.Stores {
if _, exists := configuration.TLS.Stores[name]; exists {
logger.Warn().Msgf("TLS store %v already configured, skipping", name)
} else {
if configuration.TLS.Stores == nil {
configuration.TLS.Stores = map[string]tls.Store{}
}
configuration.TLS.Stores[name] = conf
}
}
configurations = append(configurations, provider.NamedConfiguration{
Name: filename,
Configuration: c,
})
}
if len(configTLSMaps) > 0 && configuration.TLS == nil {
configuration.TLS = &dynamic.TLSConfiguration{}
}
for conf := range configTLSMaps {
configuration.TLS.Certificates = append(configuration.TLS.Certificates, conf)
}
return configuration, nil
return configurations, nil
}
func (p *Provider) decodeConfiguration(filePath, content string) (*dynamic.Configuration, error) {

View file

@ -0,0 +1,45 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: stripprefix
namespace: default
spec:
stripPrefix:
prefixes:
- /tobestripped
---
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
name: test-weighted
namespace: default
spec:
weighted:
services:
- name: whoami
port: 80
weight: 1
middlewares:
- name: stripprefix
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/bar`)
kind: Rule
priority: 12
services:
- name: test-weighted
kind: TraefikService

View file

@ -37,6 +37,7 @@ type LoadBalancerSpecApplyConfiguration struct {
Name *string `json:"name,omitempty"`
Kind *string `json:"kind,omitempty"`
Namespace *string `json:"namespace,omitempty"`
Middlewares []MiddlewareRefApplyConfiguration `json:"middlewares,omitempty"`
Sticky *dynamic.Sticky `json:"sticky,omitempty"`
Port *intstr.IntOrString `json:"port,omitempty"`
Scheme *string `json:"scheme,omitempty"`
@ -81,6 +82,19 @@ func (b *LoadBalancerSpecApplyConfiguration) WithNamespace(value string) *LoadBa
return b
}
// WithMiddlewares adds the given value to the Middlewares field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Middlewares field.
func (b *LoadBalancerSpecApplyConfiguration) WithMiddlewares(values ...*MiddlewareRefApplyConfiguration) *LoadBalancerSpecApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithMiddlewares")
}
b.Middlewares = append(b.Middlewares, *values[i])
}
return b
}
// WithSticky sets the Sticky field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Sticky field is set to the value of the last call.

View file

@ -70,6 +70,19 @@ func (b *MirroringApplyConfiguration) WithNamespace(value string) *MirroringAppl
return b
}
// WithMiddlewares adds the given value to the Middlewares field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Middlewares field.
func (b *MirroringApplyConfiguration) WithMiddlewares(values ...*MiddlewareRefApplyConfiguration) *MirroringApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithMiddlewares")
}
b.LoadBalancerSpecApplyConfiguration.Middlewares = append(b.LoadBalancerSpecApplyConfiguration.Middlewares, *values[i])
}
return b
}
// WithSticky sets the Sticky field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Sticky field is set to the value of the last call.

View file

@ -68,6 +68,19 @@ func (b *MirrorServiceApplyConfiguration) WithNamespace(value string) *MirrorSer
return b
}
// WithMiddlewares adds the given value to the Middlewares field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Middlewares field.
func (b *MirrorServiceApplyConfiguration) WithMiddlewares(values ...*MiddlewareRefApplyConfiguration) *MirrorServiceApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithMiddlewares")
}
b.LoadBalancerSpecApplyConfiguration.Middlewares = append(b.LoadBalancerSpecApplyConfiguration.Middlewares, *values[i])
}
return b
}
// WithSticky sets the Sticky field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Sticky field is set to the value of the last call.

View file

@ -67,6 +67,19 @@ func (b *ServiceApplyConfiguration) WithNamespace(value string) *ServiceApplyCon
return b
}
// WithMiddlewares adds the given value to the Middlewares field in the declarative configuration
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
// If called multiple times, values provided by each call will be appended to the Middlewares field.
func (b *ServiceApplyConfiguration) WithMiddlewares(values ...*MiddlewareRefApplyConfiguration) *ServiceApplyConfiguration {
for i := range values {
if values[i] == nil {
panic("nil value passed to WithMiddlewares")
}
b.LoadBalancerSpecApplyConfiguration.Middlewares = append(b.LoadBalancerSpecApplyConfiguration.Middlewares, *values[i])
}
return b
}
// WithSticky sets the Sticky field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the Sticky field is set to the value of the last call.

View file

@ -266,7 +266,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
continue
}
errorPage, errorPageService, err := p.createErrorPageMiddleware(client, middleware.Namespace, middleware.Spec.Errors)
errorPage, errorPageService, err := p.createErrorPageMiddleware(ctxMid, client, middleware.Namespace, middleware.Spec.Errors)
if err != nil {
logger.Error().Err(err).Msg("Error while reading error page middleware")
continue
@ -645,7 +645,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
return conf
}
func (p *Provider) createErrorPageMiddleware(client Client, namespace string, errorPage *traefikv1alpha1.ErrorPage) (*dynamic.ErrorPage, *dynamic.Service, error) {
func (p *Provider) createErrorPageMiddleware(ctx context.Context, client Client, namespace string, errorPage *traefikv1alpha1.ErrorPage) (*dynamic.ErrorPage, *dynamic.Service, error) {
if errorPage == nil {
return nil, nil, nil
}
@ -663,7 +663,7 @@ func (p *Provider) createErrorPageMiddleware(client Client, namespace string, er
allowEmptyServices: p.AllowEmptyServices,
}
balancerServerHTTP, err := cb.buildServersLB(namespace, errorPage.Service.LoadBalancerSpec)
balancerServerHTTP, err := cb.buildServersLB(ctx, namespace, errorPage.Service.LoadBalancerSpec)
if err != nil {
return nil, nil, err
}

View file

@ -82,7 +82,7 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli
serviceKey := makeServiceKey(route.Match, ingressName)
mds, err := p.makeMiddlewareKeys(ctx, ingressRoute.Namespace, route.Middlewares)
mds, err := makeMiddlewareKeys(ctx, ingressRoute.Namespace, route.Middlewares, p.AllowCrossNamespace)
if err != nil {
logger.Error().Err(err).Msg("Failed to create middleware keys")
continue
@ -172,13 +172,13 @@ func (p *Provider) loadIngressRouteConfiguration(ctx context.Context, client Cli
return conf
}
func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace string, middlewares []traefikv1alpha1.MiddlewareRef) ([]string, error) {
func makeMiddlewareKeys(ctx context.Context, namespace string, middlewares []traefikv1alpha1.MiddlewareRef, allowCrossNamespace bool) ([]string, error) {
var mds []string
for _, mi := range middlewares {
name := mi.Name
if !p.AllowCrossNamespace && strings.HasSuffix(mi.Name, providerNamespaceSeparator+providerName) {
if !allowCrossNamespace && strings.HasSuffix(mi.Name, providerNamespaceSeparator+providerName) {
// Since we are not able to know if another namespace is in the name (namespace-name@kubernetescrd),
// if the provider namespace kubernetescrd is used,
// we don't allow this format to avoid cross namespace references.
@ -196,10 +196,10 @@ func (p *Provider) makeMiddlewareKeys(ctx context.Context, ingRouteNamespace str
continue
}
ns := ingRouteNamespace
ns := namespace
if len(mi.Namespace) > 0 {
if !isNamespaceAllowed(p.AllowCrossNamespace, ingRouteNamespace, mi.Namespace) {
return nil, fmt.Errorf("middleware %s/%s is not in the IngressRoute namespace %s", mi.Namespace, mi.Name, ingRouteNamespace)
if !isNamespaceAllowed(allowCrossNamespace, namespace, mi.Namespace) {
return nil, fmt.Errorf("middleware %s/%s is not in the parent namespace %s", mi.Namespace, mi.Name, namespace)
}
ns = mi.Namespace
@ -333,6 +333,7 @@ func (c configBuilder) buildServicesLB(ctx context.Context, namespace string, tS
Sticky: sticky,
},
}
return nil
}
@ -378,7 +379,7 @@ func (c configBuilder) buildMirroring(ctx context.Context, tService *traefikv1al
}
// buildServersLB creates the configuration for the load-balancer of servers defined by svc.
func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.LoadBalancerSpec) (*dynamic.Service, error) {
func (c configBuilder) buildServersLB(ctx context.Context, namespace string, svc traefikv1alpha1.LoadBalancerSpec) (*dynamic.Service, error) {
lb := &dynamic.ServersLoadBalancer{}
lb.SetDefaults()
@ -501,7 +502,16 @@ func (c configBuilder) buildServersLB(namespace string, svc traefikv1alpha1.Load
return nil, err
}
return &dynamic.Service{LoadBalancer: lb}, nil
service := &dynamic.Service{LoadBalancer: lb}
if len(svc.Middlewares) > 0 {
mds, err := makeMiddlewareKeys(ctx, namespace, svc.Middlewares, c.allowCrossNamespace)
if err != nil {
return nil, fmt.Errorf("could not create middleware keys: %w", err)
}
service.Middlewares = mds
}
return service, nil
}
func (c configBuilder) makeServersTransportKey(parentNamespace string, serversTransportName string) (string, error) {
@ -687,7 +697,7 @@ func (c configBuilder) nameAndService(ctx context.Context, parentNamespace strin
switch service.Kind {
case "", "Service":
serversLB, err := c.buildServersLB(namespace, service)
serversLB, err := c.buildServersLB(ctx, namespace, service)
if err != nil {
return "", nil, err
}

View file

@ -3279,6 +3279,71 @@ func TestLoadIngressRoutes(t *testing.T) {
},
},
},
{
desc: "TraefikService with service middleware",
paths: []string{"services.yml", "with_traefik_service_middleware.yml"},
expected: &dynamic.Configuration{
UDP: &dynamic.UDPConfiguration{
Routers: map[string]*dynamic.UDPRouter{},
Services: map[string]*dynamic.UDPService{},
},
TLS: &dynamic.TLSConfiguration{},
TCP: &dynamic.TCPConfiguration{
Routers: map[string]*dynamic.TCPRouter{},
Middlewares: map[string]*dynamic.TCPMiddleware{},
Services: map[string]*dynamic.TCPService{},
ServersTransports: map[string]*dynamic.TCPServersTransport{},
},
HTTP: &dynamic.HTTPConfiguration{
Routers: map[string]*dynamic.Router{
"default-test-route-6b204d94623b3df4370c": {
EntryPoints: []string{"web"},
Service: "default-test-weighted",
Rule: "Host(`foo.com`) && PathPrefix(`/bar`)",
Priority: 12,
},
},
Middlewares: map[string]*dynamic.Middleware{
"default-stripprefix": {
StripPrefix: &dynamic.StripPrefix{
Prefixes: []string{"/tobestripped"},
},
},
},
Services: map[string]*dynamic.Service{
"default-test-weighted": {
Weighted: &dynamic.WeightedRoundRobin{
Services: []dynamic.WRRService{
{
Name: "default-whoami-80",
Weight: pointer(1),
},
},
},
},
"default-whoami-80": {
Middlewares: []string{"default-stripprefix"},
LoadBalancer: &dynamic.ServersLoadBalancer{
Strategy: dynamic.BalancerStrategyWRR,
Servers: []dynamic.Server{
{
URL: "http://10.10.0.1:80",
},
{
URL: "http://10.10.0.2:80",
},
},
PassHostHeader: pointer(true),
ResponseForwarding: &dynamic.ResponseForwarding{
FlushInterval: ptypes.Duration(100 * time.Millisecond),
},
},
},
},
ServersTransports: map[string]*dynamic.ServersTransport{},
},
},
},
{
desc: "one kube services in a highest random weight",
paths: []string{"with_highest_random_weight.yml"},

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