2019-08-31 07:28:04 +00:00
# Migration Guide: From v1 to v2
How to Migrate from Traefik v1 to Traefik v2.
{: .subtitle }
2019-10-14 15:26:05 +00:00
The version 2 of Traefik introduces a number of breaking changes,
2019-08-31 07:28:04 +00:00
which require one to update their configuration when they migrate from v1 to v2.
2019-10-14 15:26:05 +00:00
The goal of this page is to recapitulate all of these changes, and in particular to give examples,
2019-08-31 07:28:04 +00:00
feature by feature, of how the configuration looked like in v1, and how it now looks like in v2.
2019-09-23 12:32:04 +00:00
!!! info "Migration Helper"
2019-10-14 15:26:05 +00:00
2019-09-09 08:36:08 +00:00
We created a tool to help during the migration: [traefik-migration-tool ](https://github.com/containous/traefik-migration-tool )
This tool allows to:
- convert `Ingress` to Traefik `IngressRoute` resources.
- convert `acme.json` file from v1 to v2 format.
2019-09-23 12:32:04 +00:00
- migrate the static configuration contained in the file `traefik.toml` to a Traefik v2 file.
2019-09-09 08:36:08 +00:00
2019-08-31 07:28:04 +00:00
## Frontends and Backends Are Dead... <br/>... Long Live Routers, Middlewares, and Services
During the transition from v1 to v2, a number of internal pieces and components of Traefik were rewritten and reorganized.
2019-09-18 06:38:05 +00:00
As such, the combination of core notions such as frontends and backends has been replaced with the combination of [routers ](../routing/routers/index.md ), [services ](../routing/services/index.md ), and [middlewares ](../middlewares/overview.md ).
2019-08-31 07:28:04 +00:00
Typically, a router replaces a frontend, and a service assumes the role of a backend, with each router referring to a service.
However, even though a backend was in charge of applying any desired modification on the fly to the incoming request,
the router defers that responsibility to another component.
Instead, a dedicated middleware is now defined for each kind of such modification.
Then any router can refer to an instance of the wanted middleware.
!!! example "One frontend with basic auth and one backend, become one router, one service, and one basic auth middleware."
2019-09-18 06:38:05 +00:00
!!! info "v1"
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```yaml tab="Docker"
labels:
- "traefik.frontend.rule=Host:test.localhost;PathPrefix:/test"
2019-09-30 16:32:04 +00:00
- "traefik.frontend.auth.basic.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
2019-08-31 07:28:04 +00:00
```
```yaml tab="K8s Ingress"
2020-01-16 09:14:06 +00:00
apiVersion: networking.k8s.io/v1beta1
2019-08-31 07:28:04 +00:00
kind: Ingress
metadata:
name: traefik
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/rule-type: PathPrefix
spec:
rules:
2020-04-08 16:54:03 +00:00
- host: test.localhost
2019-08-31 07:28:04 +00:00
http:
paths:
- path: /test
backend:
serviceName: server0
servicePort: 80
- path: /test
backend:
serviceName: server1
servicePort: 80
```
```toml tab="File (TOML)"
[frontends]
[frontends.frontend1]
entryPoints = ["http"]
backend = "backend1"
[frontends.frontend1.routes]
[frontends.frontend1.routes.route0]
rule = "Host:test.localhost"
[frontends.frontend1.routes.route0]
rule = "PathPrefix:/test"
[frontends.frontend1.auth]
[frontends.frontend1.auth.basic]
users = [
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
[backends]
[backends.backend1]
[backends.backend1.servers.server0]
url = "http://10.10.10.1:80"
[backends.backend1.servers.server1]
url = "http://10.10.10.2:80"
[backends.backend1.loadBalancer]
method = "wrr"
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```yaml tab="Docker"
labels:
2020-06-09 10:18:04 +00:00
- "traefik.http.routers.router0.rule=Host(`test.localhost`) && PathPrefix(`/test`)"
2019-08-31 07:28:04 +00:00
- "traefik.http.routers.router0.middlewares=auth"
2019-09-30 16:32:04 +00:00
- "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
2019-08-31 07:28:04 +00:00
```
```yaml tab="K8s IngressRoute"
2019-10-14 15:26:05 +00:00
# The definitions below require the definitions for the Middleware and IngressRoute kinds.
2020-03-05 20:46:04 +00:00
# https://docs.traefik.io/v2.2/reference/dynamic-configuration/kubernetes-crd/#definitions
2019-08-31 07:28:04 +00:00
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: basicauth
namespace: foo
spec:
basicAuth:
users:
- test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/
- test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- http
routes:
- match: Host(`test.localhost`) && PathPrefix(`/test`)
kind: Rule
services:
- name: server0
port: 80
- name: server1
port: 80
middlewares:
- name: basicauth
namespace: foo
```
```toml tab="File (TOML)"
[http.routers]
[http.routers.router0]
rule = "Host(`test.localhost`) & & PathPrefix(`/test`)"
middlewares = ["auth"]
service = "my-service"
[http.services]
[[http.services.my-service.loadBalancer.servers]]
url = "http://10.10.10.1:80"
[[http.services.my-service.loadBalancer.servers]]
url = "http://10.10.10.2:80"
[http.middlewares]
[http.middlewares.auth.basicAuth]
users = [
2019-10-14 15:26:05 +00:00
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
2019-08-31 07:28:04 +00:00
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
]
```
```yaml tab="File (YAML)"
http:
routers:
router0:
rule: "Host(`test.localhost`) & & PathPrefix(`/test`)"
service: my-service
middlewares:
2019-09-23 15:00:06 +00:00
- auth
2019-08-31 07:28:04 +00:00
services:
my-service:
loadBalancer:
servers:
2019-09-23 15:00:06 +00:00
- url: http://10.10.10.1:80
- url: http://10.10.10.2:80
2019-08-31 07:28:04 +00:00
middlewares:
auth:
basicAuth:
users:
2019-09-23 15:00:06 +00:00
- "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
2019-08-31 07:28:04 +00:00
```
2020-01-20 14:04:09 +00:00
## TLS Configuration is Now Dynamic, per Router.
2019-08-31 07:28:04 +00:00
TLS parameters used to be specified in the static configuration, as an entryPoint field.
With Traefik v2, a new dynamic TLS section at the root contains all the desired TLS configurations.
2019-09-18 06:38:05 +00:00
Then, a [router's TLS field ](../routing/routers/index.md#tls ) can refer to one of the [TLS configurations ](../https/tls.md ) defined at the root, hence defining the [TLS configuration ](../https/tls.md ) for that router.
2019-08-31 07:28:04 +00:00
2020-01-23 15:36:08 +00:00
!!! example "TLS on websecure entryPoint becomes TLS option on Router-1"
2019-08-31 07:28:04 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v1"
2019-08-31 07:28:04 +00:00
```toml tab="File (TOML)"
# static configuration
[entryPoints]
2020-01-23 15:36:08 +00:00
[entryPoints.websecure]
2019-08-31 07:28:04 +00:00
address = ":443"
2020-01-23 15:36:08 +00:00
[entryPoints.websecure.tls]
2019-08-31 07:28:04 +00:00
minVersion = "VersionTLS12"
cipherSuites = [
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
2019-10-08 12:38:04 +00:00
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
2020-02-26 14:30:06 +00:00
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
2019-10-08 12:38:04 +00:00
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
2020-01-20 14:04:09 +00:00
]
2020-01-23 15:36:08 +00:00
[[entryPoints.websecure.tls.certificates]]
2019-08-31 07:28:04 +00:00
certFile = "path/to/my.cert"
keyFile = "path/to/my.key"
```
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```bash tab="CLI"
2020-02-26 14:30:06 +00:00
--entryPoints='Name:websecure Address::443 TLS:path/to/my.cert,path/to/my.key TLS.MinVersion:VersionTLS12 TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
2019-08-31 07:28:04 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```toml tab="File (TOML)"
# dynamic configuration
[http.routers]
[http.routers.Router-1]
2020-03-13 21:50:05 +00:00
rule = "Host(`example.com`)"
2019-08-31 07:28:04 +00:00
service = "service-id"
# will terminate the TLS request
[http.routers.Router-1.tls]
options = "myTLSOptions"
[[tls.certificates]]
certFile = "/path/to/domain.cert"
keyFile = "/path/to/domain.key"
[tls.options]
[tls.options.myTLSOptions]
2020-02-17 16:38:05 +00:00
minVersion = "VersionTLS12"
2019-08-31 07:28:04 +00:00
cipherSuites = [
2020-01-20 14:04:09 +00:00
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
2020-02-26 14:30:06 +00:00
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
2020-01-20 14:04:09 +00:00
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
]
2019-08-31 07:28:04 +00:00
```
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```yaml tab="File (YAML)"
http:
routers:
Router-1:
2020-03-13 21:50:05 +00:00
rule: "Host(`example.com`)"
2019-08-31 07:28:04 +00:00
service: service-id
# will terminate the TLS request
tls:
options: myTLSOptions
tls:
certificates:
- certFile: /path/to/domain.cert
keyFile: /path/to/domain.key
options:
myTLSOptions:
2020-02-17 16:38:05 +00:00
minVersion: VersionTLS12
2019-08-31 07:28:04 +00:00
cipherSuites:
2019-10-08 12:38:04 +00:00
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
2020-02-26 14:30:06 +00:00
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
2019-10-08 12:38:04 +00:00
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
2019-08-31 07:28:04 +00:00
```
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```yaml tab="K8s IngressRoute"
2019-10-14 15:26:05 +00:00
# The definitions below require the definitions for the TLSOption and IngressRoute kinds.
2020-03-05 20:46:04 +00:00
# https://docs.traefik.io/v2.2/reference/dynamic-configuration/kubernetes-crd/#definitions
2019-08-31 07:28:04 +00:00
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: mytlsoption
namespace: default
spec:
2020-02-17 16:38:05 +00:00
minVersion: VersionTLS12
2019-08-31 07:28:04 +00:00
cipherSuites:
2019-10-08 12:38:04 +00:00
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
2020-02-26 14:30:06 +00:00
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
2019-10-08 12:38:04 +00:00
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
2019-08-31 07:28:04 +00:00
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- web
routes:
2020-03-13 21:50:05 +00:00
- match: Host(`example.com`)
2019-09-23 15:00:06 +00:00
kind: Rule
services:
- name: whoami
port: 80
2019-08-31 07:28:04 +00:00
tls:
2019-10-14 15:26:05 +00:00
options:
2019-08-31 07:28:04 +00:00
name: mytlsoption
namespace: default
```
2019-10-14 15:26:05 +00:00
2019-08-31 07:28:04 +00:00
```yaml tab="Docker"
labels:
# myTLSOptions must be defined by another provider, in this instance in the File Provider.
# see the cross provider section
- "traefik.http.routers.router0.tls.options=myTLSOptions@file"
```
2020-01-20 14:04:09 +00:00
## HTTP to HTTPS Redirection is Now Configured on Routers
2019-08-31 07:28:04 +00:00
2019-09-18 06:38:05 +00:00
Previously on Traefik v1, the redirection was applied on an entry point or on a frontend.
2020-03-09 12:22:06 +00:00
With Traefik v2 it is applied on an entry point or a [Router ](../routing/routers/index.md ).
2019-08-31 07:28:04 +00:00
2020-03-09 12:22:06 +00:00
To apply a redirection:
- on an entry point, the [HTTP redirection ](../routing/entrypoints.md#redirection ) has to be configured.
- on a router, one of the redirect middlewares, [RedirectRegex ](../middlewares/redirectregex.md ) or [RedirectScheme ](../middlewares/redirectscheme.md ), has to be configured and added to the router middlewares list.
2019-08-31 07:28:04 +00:00
2020-01-20 14:04:09 +00:00
!!! example "Global HTTP to HTTPS redirection"
2019-09-18 06:38:05 +00:00
!!! info "v1"
```toml tab="File (TOML)"
# static configuration
2020-01-20 14:04:09 +00:00
defaultEntryPoints = ["web", "websecure"]
2019-09-18 06:38:05 +00:00
[entryPoints]
2020-01-20 14:04:09 +00:00
[entryPoints.web]
2019-09-18 06:38:05 +00:00
address = ":80"
2020-01-20 14:04:09 +00:00
[entryPoints.web.redirect]
entryPoint = "websecure"
2019-09-18 06:38:05 +00:00
2020-01-20 14:04:09 +00:00
[entryPoints.websecure]
2019-09-18 06:38:05 +00:00
address = ":443"
2020-01-20 14:04:09 +00:00
[entryPoints.websecure.tls]
```
```bash tab="CLI"
--entrypoints=Name:web Address::80 Redirect.EntryPoint:websecure
--entryPoints='Name:websecure Address::443 TLS'
```
!!! info "v2"
2020-03-09 12:22:06 +00:00
```bash tab="CLI"
## static configuration
2020-01-20 14:04:09 +00:00
2020-03-09 12:22:06 +00:00
--entrypoints.web.address=:80
--entrypoints.web.http.redirections.entrypoint.to=websecure
--entrypoints.web.http.redirections.entrypoint.scheme=https
--entrypoints.websecure.address=:443
--providers.docker=true
2020-01-20 14:04:09 +00:00
```
```toml tab="File (TOML)"
# traefik.toml
## static configuration
2020-03-09 12:22:06 +00:00
[entryPoints.web]
2020-04-02 11:20:05 +00:00
address = ":80"
2020-03-09 12:22:06 +00:00
[entryPoints.web.http.redirections.entryPoint]
to = "websecure"
2020-01-20 14:04:09 +00:00
scheme = "https"
2020-03-09 12:22:06 +00:00
[entryPoints.websecure]
2020-04-02 11:20:05 +00:00
address = ":443"
2020-01-20 14:04:09 +00:00
```
```yaml tab="File (YAML)"
# traefik.yaml
## static configuration
entryPoints:
web:
address: 80
2020-03-09 12:22:06 +00:00
http:
redirections:
entrypoint:
to: websecure
scheme: https
2020-01-20 14:04:09 +00:00
websecure:
address: 443
```
!!! example "HTTP to HTTPS redirection per domain"
!!! info "v1"
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[entryPoints.websecure.tls]
2020-03-09 12:22:06 +00:00
[file]
[frontends]
[frontends.frontend1]
entryPoints = ["web", "websecure"]
[frontends.frontend1.routes]
[frontends.frontend1.routes.route0]
2020-03-13 21:50:05 +00:00
rule = "Host:example.net"
2020-03-09 12:22:06 +00:00
[frontends.frontend1.redirect]
entryPoint = "websecure"
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="Docker"
labels:
2020-03-13 21:50:05 +00:00
traefik.http.routers.app.rule: Host(`example.net`)
2020-01-20 14:04:09 +00:00
traefik.http.routers.app.entrypoints: web
traefik.http.routers.app.middlewares: https_redirect
2020-03-13 21:50:05 +00:00
traefik.http.routers.appsecured.rule: Host(`example.net`)
2020-01-20 14:04:09 +00:00
traefik.http.routers.appsecured.entrypoints: websecure
traefik.http.routers.appsecured.tls: true
traefik.http.middlewares.https_redirect.redirectscheme.scheme: https
traefik.http.middlewares.https_redirect.redirectscheme.permanent: true
2019-09-18 06:38:05 +00:00
```
```yaml tab="K8s IngressRoute"
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: http-redirect-ingressRoute
spec:
entryPoints:
- web
routes:
2020-03-13 21:50:05 +00:00
- match: Host(`example.net`)
2019-09-18 06:38:05 +00:00
kind: Rule
services:
- name: whoami
port: 80
middlewares:
2020-08-03 15:30:04 +00:00
- name: https-redirect
2019-09-18 06:38:05 +00:00
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: https-ingressRoute
spec:
entryPoints:
2020-01-20 14:04:09 +00:00
- websecure
2019-09-18 06:38:05 +00:00
routes:
- match: Host(`foo`)
kind: Rule
services:
- name: whoami
port: 80
tls: {}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
2020-08-03 15:30:04 +00:00
name: https-redirect
2019-09-18 06:38:05 +00:00
spec:
redirectScheme:
scheme: https
2020-01-20 14:04:09 +00:00
permanent: true
2019-09-18 06:38:05 +00:00
```
```toml tab="File (TOML)"
## dynamic configuration
2019-09-26 16:20:04 +00:00
# dynamic-conf.toml
2019-09-18 06:38:05 +00:00
[http.routers]
[http.routers.router0]
2020-03-13 21:50:05 +00:00
rule = "Host(`example.net`)"
2019-09-18 06:38:05 +00:00
service = "my-service"
2019-09-23 08:30:04 +00:00
entrypoints = ["web"]
2020-01-20 14:04:09 +00:00
middlewares = ["https_redirect"]
2019-09-18 06:38:05 +00:00
[http.routers.router1]
2020-03-13 21:50:05 +00:00
rule = "Host(`example.net`)"
2019-09-18 06:38:05 +00:00
service = "my-service"
2020-01-20 14:04:09 +00:00
entrypoints = ["websecure"]
2019-09-18 06:38:05 +00:00
[http.routers.router1.tls]
[http.middlewares]
2020-08-15 14:04:03 +00:00
[http.middlewares.https_redirect.redirectScheme]
2019-09-18 06:38:05 +00:00
scheme = "https"
2020-01-20 14:04:09 +00:00
permanent = true
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="File (YAML)"
## dynamic configuration
2019-09-26 16:20:04 +00:00
# dynamic-conf.yml
2019-09-18 06:38:05 +00:00
http:
routers:
router0:
2020-03-13 21:50:05 +00:00
rule: "Host(`example.net`)"
2019-09-20 14:44:04 +00:00
entryPoints:
2019-09-23 15:00:06 +00:00
- web
2019-09-20 14:44:04 +00:00
middlewares:
2020-01-20 14:04:09 +00:00
- https_redirect
2019-09-20 14:44:04 +00:00
service: my-service
2019-09-18 06:38:05 +00:00
router1:
2020-03-13 21:50:05 +00:00
rule: "Host(`example.net`)"
2019-09-20 14:44:04 +00:00
entryPoints:
2020-01-20 14:04:09 +00:00
- websecure
2019-09-20 14:44:04 +00:00
service: my-service
tls: {}
2019-09-18 06:38:05 +00:00
middlewares:
2020-08-03 15:30:04 +00:00
https-redirect:
2019-09-18 06:38:05 +00:00
redirectScheme:
scheme: https
2020-01-20 14:04:09 +00:00
permanent: true
2019-10-14 15:26:05 +00:00
```
## Strip and Rewrite Path Prefixes
With the new core notions of v2 (introduced earlier in the section
["Frontends and Backends Are Dead... Long Live Routers, Middlewares, and Services" ](#frontends-and-backends-are-dead-long-live-routers-middlewares-and-services )),
2020-01-20 14:04:09 +00:00
transforming the URL path prefix of incoming requests is configured with [middlewares ](../middlewares/overview.md ),
2020-02-17 10:04:04 +00:00
after the routing step with [router rule `PathPrefix` ](../routing/routers/index.md#rule ).
2019-10-14 15:26:05 +00:00
2020-03-13 21:50:05 +00:00
Use Case: Incoming requests to `http://example.org/admin` are forwarded to the webapplication "admin",
2019-10-14 15:26:05 +00:00
with the path `/admin` stripped, e.g. to `http://<IP>:<port>/` . In this case, you must:
2020-03-09 12:22:06 +00:00
- First, configure a router named `admin` with a rule matching at least the path prefix with the `PathPrefix` keyword,
- Then, define a middleware of type [`stripprefix` ](../middlewares/stripprefix.md ), which removes the prefix `/admin` , associated to the router `admin` .
2019-10-14 15:26:05 +00:00
!!! example "Strip Path Prefix When Forwarding to Backend"
!!! info "v1"
```yaml tab="Docker"
labels:
2020-03-13 21:50:05 +00:00
- "traefik.frontend.rule=Host:example.org;PathPrefixStrip:/admin"
2019-10-14 15:26:05 +00:00
```
```yaml tab="Kubernetes Ingress"
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: traefik
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
rules:
2020-03-13 21:50:05 +00:00
- host: example.org
2019-10-14 15:26:05 +00:00
http:
paths:
- path: /admin
backend:
serviceName: admin-svc
servicePort: admin
```
```toml tab="File (TOML)"
[frontends.admin]
[frontends.admin.routes.admin_1]
2020-03-13 21:50:05 +00:00
rule = "Host:example.org;PathPrefixStrip:/admin"
2019-10-14 15:26:05 +00:00
```
!!! info "v2"
```yaml tab="Docker"
labels:
2020-03-13 21:50:05 +00:00
- "traefik.http.routers.admin.rule=Host(`example.org`) && PathPrefix(`/admin`)"
2019-12-05 23:42:04 +00:00
- "traefik.http.routers.admin.middlewares=admin-stripprefix"
2019-10-14 15:26:05 +00:00
- "traefik.http.middlewares.admin-stripprefix.stripprefix.prefixes=/admin"
```
```yaml tab="Kubernetes IngressRoute"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: http-redirect-ingressRoute
namespace: admin-web
spec:
entryPoints:
- web
routes:
2020-03-13 21:50:05 +00:00
- match: Host(`example.org`) && PathPrefix(`/admin`)
2019-10-14 15:26:05 +00:00
kind: Rule
services:
- name: admin-svc
port: admin
middlewares:
- name: admin-stripprefix
---
2020-04-27 15:26:06 +00:00
apiVersion: traefik.containo.us/v1alpha1
2019-10-14 15:26:05 +00:00
kind: Middleware
metadata:
name: admin-stripprefix
spec:
stripPrefix:
prefixes:
- /admin
```
```toml tab="File (TOML)"
## Dynamic configuration
# dynamic-conf.toml
[http.routers.router1]
2020-03-13 21:50:05 +00:00
rule = "Host(`example.org`) & & PathPrefix(`/admin`)"
2019-10-14 15:26:05 +00:00
service = "admin-svc"
entrypoints = ["web"]
middlewares = ["admin-stripprefix"]
[http.middlewares]
[http.middlewares.admin-stripprefix.stripPrefix]
prefixes = ["/admin"]
# ...
```
```yaml tab="File (YAML)"
## Dynamic Configuration
# dynamic-conf.yml
# As YAML Configuration File
http:
routers:
admin:
service: admin-svc
middlewares:
- "admin-stripprefix"
2020-03-13 21:50:05 +00:00
rule: "Host(`example.org`) & & PathPrefix(`/admin`)"
2019-10-14 15:26:05 +00:00
middlewares:
admin-stripprefix:
2019-10-20 21:40:03 +00:00
stripPrefix:
prefixes:
- "/admin"
2019-10-14 15:26:05 +00:00
# ...
```
??? question "What About Other Path Transformations?"
Instead of removing the path prefix with the [`stripprefix` middleware ](../../middlewares/stripprefix/ ), you can also:
2020-03-09 12:22:06 +00:00
- Add a path prefix with the [`addprefix` middleware ](../../middlewares/addprefix/ )
- Replace the complete path of the request with the [`replacepath` middleware ](../../middlewares/replacepath/ )
- ReplaceRewrite path using Regexp with the [`replacepathregex` middleware ](../../middlewares/replacepathregex/ )
- And a lot more on the [`middlewares` page ](../../middlewares/overview/ )
2019-09-18 06:38:05 +00:00
## ACME (LetsEncrypt)
[ACME ](../https/acme.md ) is now a certificate resolver (under a certificatesResolvers section) but remains in the static configuration.
!!! example "ACME from provider to a specific Certificate Resolver"
!!! info "v1"
```toml tab="File (TOML)"
# static configuration
2020-01-23 15:36:08 +00:00
defaultEntryPoints = ["websecure","web"]
2019-09-18 06:38:05 +00:00
[entryPoints.web]
address = ":80"
[entryPoints.web.redirect]
entryPoint = "webs"
2020-01-23 15:36:08 +00:00
[entryPoints.websecure]
2019-09-18 06:38:05 +00:00
address = ":443"
2020-02-17 10:04:04 +00:00
[entryPoints.websecure.tls]
2019-09-18 06:38:05 +00:00
[acme]
2020-03-13 21:50:05 +00:00
email = "your-email-here@example.com"
2019-09-18 06:38:05 +00:00
storage = "acme.json"
2020-01-23 15:36:08 +00:00
entryPoint = "websecure"
2019-09-18 06:38:05 +00:00
onHostRule = true
2020-03-09 12:22:06 +00:00
[acme.tlsChallenge]
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
2020-01-23 15:36:08 +00:00
--defaultentrypoints=websecure,web
--entryPoints=Name:web Address::80 Redirect.EntryPoint:websecure
--entryPoints=Name:websecure Address::443 TLS
2020-03-13 21:50:05 +00:00
--acme.email=your-email-here@example.com
2019-09-18 06:38:05 +00:00
--acme.storage=acme.json
2020-01-23 15:36:08 +00:00
--acme.entryPoint=websecure
2019-09-18 06:38:05 +00:00
--acme.onHostRule=true
2020-03-09 12:22:06 +00:00
--acme.tlschallenge=true
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[entryPoints]
[entryPoints.web]
address = ":80"
2020-01-23 15:36:08 +00:00
[entryPoints.websecure]
2019-09-18 06:38:05 +00:00
address = ":443"
2020-03-09 12:22:06 +00:00
[entryPoints.websecure.http.tls]
certResolver = "myresolver"
2019-09-18 06:38:05 +00:00
2020-02-17 10:04:04 +00:00
[certificatesResolvers.myresolver.acme]
2020-03-13 21:50:05 +00:00
email = "your-email@example.com"
2019-09-18 06:38:05 +00:00
storage = "acme.json"
2020-03-09 12:22:06 +00:00
[certificatesResolvers.myresolver.acme.tlsChallenge]
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="File (YAML)"
entryPoints:
web:
address: ":80"
2020-01-23 15:36:08 +00:00
websecure:
2019-09-18 06:38:05 +00:00
address: ":443"
2020-03-09 12:22:06 +00:00
http:
tls:
certResolver: myresolver
2019-09-18 06:38:05 +00:00
certificatesResolvers:
2020-02-17 10:04:04 +00:00
myresolver:
2019-09-18 06:38:05 +00:00
acme:
2020-03-13 21:50:05 +00:00
email: your-email@example.com
2019-09-18 06:38:05 +00:00
storage: acme.json
2020-03-09 12:22:06 +00:00
tlsChallenge: {}
2019-10-14 15:26:05 +00:00
```
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
2020-03-09 12:22:06 +00:00
--entrypoints.web.address=:80
--entrypoints.websecure.address=:443
2020-03-13 21:50:05 +00:00
--certificatesresolvers.myresolver.acme.email=your-email@example.com
2020-03-09 12:22:06 +00:00
--certificatesresolvers.myresolver.acme.storage=acme.json
--certificatesresolvers.myresolver.acme.tlschallenge=true
2019-09-18 06:38:05 +00:00
```
2019-08-31 07:28:04 +00:00
## Traefik Logs
2019-09-18 06:38:05 +00:00
In the v2, all the [log configuration ](../observability/logs.md ) remains in the static part but are unified under a `log` section.
There is no more log configuration at the root level.
!!! example "Simple log configuration"
!!! info "v1"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
logLevel = "DEBUG"
[traefikLog]
filePath = "/path/to/traefik.log"
format = "json"
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
2019-11-19 09:18:05 +00:00
--logLevel=DEBUG
--traefikLog.filePath=/path/to/traefik.log
--traefikLog.format=json
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[log]
level = "DEBUG"
filePath = "/path/to/log-file.log"
format = "json"
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="File (YAML)"
# static configuration
log:
level: DEBUG
filePath: /path/to/log-file.log
format: json
2019-10-14 15:26:05 +00:00
```
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
2019-11-19 09:18:05 +00:00
--log.level=DEBUG
--log.filePath=/path/to/traefik.log
--log.format=json
2019-09-18 06:38:05 +00:00
```
2019-08-31 07:28:04 +00:00
2020-04-22 09:12:05 +00:00
## Access Logs
Access Logs are configured in the same way as before.
But all request headers are now filtered out by default in Traefik v2.
So during migration, you might want to consider enabling some needed fields (see [access log configuration ](../observability/access-logs.md )).
2019-08-31 07:28:04 +00:00
## Tracing
2019-09-18 06:38:05 +00:00
Traefik v2 retains OpenTracing support. The `backend` root option from the v1 is gone, you just have to set your [tracing configuration ](../observability/tracing/overview.md ).
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! example "Simple Jaeger tracing configuration"
!!! info "v1"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[tracing]
backend = "jaeger"
servicename = "tracing"
[tracing.jaeger]
samplingParam = 1.0
samplingServerURL = "http://12.0.0.1:5778/sampling"
samplingType = "const"
localAgentHostPort = "12.0.0.1:6831"
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
2019-11-19 09:18:05 +00:00
--tracing.backend=jaeger
--tracing.servicename=tracing
--tracing.jaeger.localagenthostport=12.0.0.1:6831
--tracing.jaeger.samplingparam=1.0
--tracing.jaeger.samplingserverurl=http://12.0.0.1:5778/sampling
--tracing.jaeger.samplingtype=const
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[tracing]
servicename = "tracing"
[tracing.jaeger]
samplingParam = 1.0
samplingServerURL = "http://12.0.0.1:5778/sampling"
samplingType = "const"
localAgentHostPort = "12.0.0.1:6831"
2019-09-19 09:10:04 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="File (YAML)"
# static configuration
tracing:
servicename: tracing
jaeger:
samplingParam: 1
samplingServerURL: 'http://12.0.0.1:5778/sampling'
samplingType: const
localAgentHostPort: '12.0.0.1:6831'
2019-10-14 15:26:05 +00:00
```
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
2019-11-19 09:18:05 +00:00
--tracing.servicename=tracing
--tracing.jaeger.localagenthostport=12.0.0.1:6831
--tracing.jaeger.samplingparam=1.0
--tracing.jaeger.samplingserverurl=http://12.0.0.1:5778/sampling
--tracing.jaeger.samplingtype=const
2019-09-18 06:38:05 +00:00
```
2019-08-31 07:28:04 +00:00
## Metrics
2019-09-18 06:38:05 +00:00
The v2 retains metrics tools and allows metrics to be configured for the entrypoints and/or services.
2019-10-14 15:26:05 +00:00
For a basic configuration, the [metrics configuration ](../observability/metrics/overview.md ) remains the same.
2019-09-18 06:38:05 +00:00
!!! example "Simple Prometheus metrics configuration"
!!! info "v1"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[metrics.prometheus]
2019-09-20 14:44:04 +00:00
buckets = [0.1,0.3,1.2,5.0]
entryPoint = "traefik"
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
--metrics.prometheus.buckets=[0.1,0.3,1.2,5.0]
2019-11-19 09:18:05 +00:00
--metrics.prometheus.entrypoint=traefik
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[metrics.prometheus]
2019-09-20 14:44:04 +00:00
buckets = [0.1,0.3,1.2,5.0]
entryPoint = "metrics"
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="File (YAML)"
# static configuration
metrics:
prometheus:
buckets:
- 0.1
- 0.3
- 1.2
- 5
entryPoint: metrics
2019-10-14 15:26:05 +00:00
```
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
--metrics.prometheus.buckets=[0.1,0.3,1.2,5.0]
2019-11-19 09:18:05 +00:00
--metrics.prometheus.entrypoint=metrics
2019-09-18 06:38:05 +00:00
```
2019-08-31 07:28:04 +00:00
2019-10-14 15:26:05 +00:00
## No More Root Level Key/Values
2019-08-31 07:28:04 +00:00
2019-09-18 06:38:05 +00:00
To avoid any source of confusion, there are no more configuration at the root level.
Each root item has been moved to a related section or removed.
!!! example "From root to dedicated section"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v1"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
checkNewVersion = false
sendAnonymousUsage = true
logLevel = "DEBUG"
insecureSkipVerify = true
rootCAs = [ "/mycert.cert" ]
maxIdleConnsPerHost = 200
providersThrottleDuration = "2s"
AllowMinWeightZero = true
debug = true
2020-01-23 15:36:08 +00:00
defaultEntryPoints = ["web", "websecure"]
2019-09-18 06:38:05 +00:00
keepTrailingSlash = false
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
--checknewversion=false
--sendanonymoususage=true
2019-11-19 09:18:05 +00:00
--loglevel=DEBUG
2019-09-18 06:38:05 +00:00
--insecureskipverify=true
2019-11-19 09:18:05 +00:00
--rootcas=/mycert.cert
2019-09-18 06:38:05 +00:00
--maxidleconnsperhost=200
2019-11-19 09:18:05 +00:00
--providersthrottleduration=2s
2019-09-18 06:38:05 +00:00
--allowminweightzero=true
--debug=true
2020-01-23 15:36:08 +00:00
--defaultentrypoints=web,websecure
2019-09-18 06:38:05 +00:00
--keeptrailingslash=true
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```toml tab="File (TOML)"
# static configuration
[global]
checkNewVersion = true
sendAnonymousUsage = true
[log]
level = "DEBUG"
[serversTransport]
2019-09-20 14:44:04 +00:00
insecureSkipVerify = true
rootCAs = [ "/mycert.cert" ]
maxIdleConnsPerHost = 42
2019-09-18 06:38:05 +00:00
[providers]
2019-10-14 15:26:05 +00:00
providersThrottleDuration = 42
2019-09-18 06:38:05 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-18 06:38:05 +00:00
```yaml tab="File (YAML)"
# static configuration
global:
checkNewVersion: true
sendAnonymousUsage: true
log:
level: DEBUG
serversTransport:
insecureSkipVerify: true
rootCAs:
- /mycert.cert
maxIdleConnsPerHost: 42
providers:
providersThrottleDuration: 42
2019-10-14 15:26:05 +00:00
```
2019-09-18 06:38:05 +00:00
```bash tab="CLI"
--global.checknewversion=true
--global.sendanonymoususage=true
2019-11-19 09:18:05 +00:00
--log.level=DEBUG
2019-09-18 06:38:05 +00:00
--serverstransport.insecureskipverify=true
2019-11-19 09:18:05 +00:00
--serverstransport.rootcas=/mycert.cert
2019-09-18 06:38:05 +00:00
--serverstransport.maxidleconnsperhost=42
--providers.providersthrottleduration=42
```
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
## Dashboard
2019-10-07 12:38:06 +00:00
You need to activate the API to access the [dashboard ](../operations/dashboard.md ).
2019-09-20 14:44:04 +00:00
2020-03-09 12:22:06 +00:00
To activate the dashboard, you can either:
2019-09-20 14:44:04 +00:00
2020-03-09 12:22:06 +00:00
- use the [secure mode ](../operations/dashboard.md#secure-mode ) with the `api@internal` service like in the following examples
- or use the [insecure mode ](../operations/api.md#insecure )
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
!!! example "Activate and access the dashboard"
!!! info "v1"
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
```toml tab="File (TOML)"
## static configuration
# traefik.toml
2020-01-23 15:36:08 +00:00
[entryPoints.websecure]
2019-09-20 14:44:04 +00:00
address = ":443"
2020-01-23 15:36:08 +00:00
[entryPoints.websecure.tls]
[entryPoints.websecure.auth]
[entryPoints.websecure.auth.basic]
2019-09-20 14:44:04 +00:00
users = [
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
]
[api]
2020-01-23 15:36:08 +00:00
entryPoint = "websecure"
2019-09-20 14:44:04 +00:00
```
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
```bash tab="CLI"
2020-01-23 15:36:08 +00:00
--entryPoints='Name:websecure Address::443 TLS Auth.Basic.Users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
2019-09-20 14:44:04 +00:00
--api
```
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
!!! info "v2"
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
```yaml tab="Docker"
# dynamic configuration
labels:
- "traefik.http.routers.api.rule=Host(`traefik.docker.localhost`)"
2020-03-09 12:22:06 +00:00
- "traefik.http.routers.api.entrypoints=websecure"
2019-09-20 14:44:04 +00:00
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.middlewares=myAuth"
- "traefik.http.routers.api.tls"
2019-09-30 16:32:04 +00:00
- "traefik.http.middlewares.myAuth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
2019-09-20 14:44:04 +00:00
```
2019-08-31 07:28:04 +00:00
2019-09-20 14:44:04 +00:00
```toml tab="File (TOML)"
## static configuration
# traefik.toml
2020-01-23 15:36:08 +00:00
[entryPoints.websecure]
2019-09-20 14:44:04 +00:00
address = ":443"
[api]
[providers.file]
2019-12-09 10:48:05 +00:00
directory = "/path/to/dynamic/config"
2019-09-20 14:44:04 +00:00
##---------------------##
## dynamic configuration
2019-12-09 10:48:05 +00:00
# /path/to/dynamic/config/dynamic-conf.toml
2019-09-20 14:44:04 +00:00
[http.routers.api]
rule = "Host(`traefik.docker.localhost`)"
2020-01-23 15:36:08 +00:00
entrypoints = ["websecure"]
2019-09-20 14:44:04 +00:00
service = "api@internal"
middlewares = ["myAuth"]
[http.routers.api.tls]
[http.middlewares.myAuth.basicAuth]
users = [
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
]
```
2019-10-14 15:26:05 +00:00
2019-09-20 14:44:04 +00:00
```yaml tab="File (YAML)"
## static configuration
# traefik.yaml
entryPoints:
2020-01-23 15:36:08 +00:00
websecure:
2019-09-20 14:44:04 +00:00
address: ':443'
api: {}
providers:
file:
2019-12-09 10:48:05 +00:00
directory: /path/to/dynamic/config
2019-09-20 14:44:04 +00:00
##---------------------##
## dynamic configuration
2019-12-09 10:48:05 +00:00
# /path/to/dynamic/config/dynamic-conf.yaml
2019-09-20 14:44:04 +00:00
http:
routers:
api:
rule: Host(`traefik.docker.localhost`)
entrypoints:
2020-01-23 15:36:08 +00:00
- websecure
2019-09-20 14:44:04 +00:00
service: api@internal
middlewares:
- myAuth
tls: {}
middlewares:
myAuth:
basicAuth:
users:
- 'test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
2019-10-14 15:26:05 +00:00
```
2019-08-31 07:28:04 +00:00
## Providers
2019-09-18 06:38:05 +00:00
Supported [providers ](../providers/overview.md ), for now:
2019-08-31 07:28:04 +00:00
2020-03-09 12:22:06 +00:00
- [ ] Azure Service Fabric
- [x] Consul
- [x] Consul Catalog
- [x] Docker
- [ ] DynamoDB
- [ ] ECS
- [x] Etcd
- [ ] Eureka
- [x] File
- [x] Kubernetes Ingress
- [x] Kubernetes IngressRoute
- [x] Marathon
- [ ] Mesos
- [x] Rancher
- [x] Redis
- [x] Rest
- [x] Zookeeper
2019-09-20 14:44:04 +00:00
2019-10-14 15:26:05 +00:00
## Some Tips You Should Know
2019-09-20 14:44:04 +00:00
2020-03-09 12:22:06 +00:00
- Different sources of static configuration (file, CLI flags, ...) cannot be [mixed ](../getting-started/configuration-overview.md#the-static-configuration ).
- Now, configuration elements can be referenced between different providers by using the provider namespace notation: `@<provider>` .
2019-09-20 14:44:04 +00:00
For instance, a router named `myrouter` in a File Provider can refer to a service named `myservice` defined in Docker Provider with the following notation: `myservice@docker` .
2020-03-09 12:22:06 +00:00
- Middlewares are applied in the same order as their declaration in router.
- If you have any questions feel free to join our [community forum ](https://community.containo.us ).