--- obj: application website: https://traefik.io repo: https://github.com/traefik/traefik --- # traefik Traefik is an open-source Edge Router (Reverse Proxy) that makes publishing your services a fun and easy experience. It receives requests on behalf of your system and finds out which components are responsible for handling them. Traefik is based on the concept of EntryPoints, Routers, Middlewares and Services. - EntryPoints: EntryPoints are the network entry points into Traefik. They define the port which will receive the packets, and whether to listen for [TCP](../../internet/TCP.md) or [UDP](../../internet/UDP.md). - Routers: A router is in charge of connecting incoming requests to the services that can handle them. - Middlewares: Attached to the routers, middlewares can modify the requests or responses before they are sent to your service - Services: Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests. ## Docker Compose ```yaml version: "3" services: traefik: image: traefik:v2.10.4 ports: - 80:80 - 443:443 - 28080:8080 volumes: - ./conf:/etc/traefik - ./logs:/var/log/traefik/ - /var/run/docker.sock:/var/run/docker.sock:ro restart: unless-stopped ``` ## Configuration Configuration is done via the file `traefik.yaml`. ### Entrypoints You need to define some entrypoints which accept incoming traffik. ```yaml entryPoints: web: address: ":80" websecure: address: ":443" ``` ### Routers A router is in charge of connecting incoming requests to the services that can handle them. In the process, routers may use pieces of middleware to update the request, or act before forwarding the request to the service. Routers can handle [HTTP](../../internet/HTTP.md), [TCP](../../internet/TCP.md) and [UDP](../../internet/UDP.md) traffik. Example: ```yaml http: routers: my-router: rule: "Path(`/foo`)" service: service-foo ``` #### Entrypoints If not specified, [HTTP](../../internet/HTTP.md) routers will accept requests from all defined entry points. If you want to limit the router scope to a set of entry points, set the entryPoints option. Listen only to specific entrypoints: ```yaml http: routers: Router-1: # won't listen to entry point web entryPoints: - "websecure" - "other" rule: "Host(`example.com`)" service: "service-1" ``` #### Rules Rules are a set of matchers configured with values, that determine if a particular request matches specific criteria. If the rule is verified, the router becomes active, calls middlewares, and then forwards the request to the service. ```yaml http: routers: Router: rule: "Host(`example.com`)" ``` The table below lists all the available matchers: | Rule | Description | | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | Headers(\`key\`, \`value\`) | Check if there is a key `key` defined in the headers, with the value `value` | | HeadersRegexp(\`key\`, \`regexp\`) | Check if there is a key `key` defined in the headers, with a value that matches the [regular expression](../../tools/Regex.md) `regexp` | | Host(\`example.com\`, ...) | Check if the request [domain](../../internet/Domain.md) (host header value) targets one of the given `domains`. | | HostRegexp(\`example.com\`, \`{subdomain:\[a-z]+}.example.com\`, ...) | Match the request [domain](../../internet/Domain.md) | | Method(\`GET\`, ...) | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) | | Path(\`/path\`, \`/articles/{cat:\[a-z]+}/{id:\[0-9]+}\`, ...) | Match exact request path | | PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`) | Match request prefix path | | Query(\`foo=bar\`, \`bar=baz\`) | Match Query String parameters. It accepts a sequence of `key=value` pairs. | | ClientIP(\`10.0.0.0/16\`, \`::1\`) | Match if the request client IP is one of the given IP/CIDR. It accepts IPv4, IPv6 and CIDR formats. | #### Middlewares You can attach a list of middlewares to each [HTTP](../../internet/HTTP.md) router. The middlewares will take effect only if the rule matches, and before forwarding the request to the service. ```yaml http: routers: my-router: rule: "Path(`/foo`)" middlewares: - authentication service: service-foo ``` #### Service Each request must eventually be handled by a service, which is why each router definition should include a service target, which is basically where the request will be passed along to. In general, a service assigned to a router should have been defined, but there are exceptions for label-based providers. #### TLS When a TLS section is specified, it instructs Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore [HTTP](../../internet/HTTP.md) (non TLS) requests). Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services). ```yaml http: routers: Router-1: rule: "Host(`foo-domain`) && Path(`/foo-path/`)" service: service-id # will terminate the TLS request tls: {} ``` - `certResolver` If `certResolver` is defined, Traefik will try to generate certificates based on routers `Host` & `HostSNI` rules. ```yaml http: routers: routerfoo: rule: "Host(`snitest.com`) && Path(`/foo`)" tls: certResolver: foo ``` - `domains` You can set SANs (alternative domains) for each main [domain](../../internet/Domain.md). Every [domain](../../internet/Domain.md) must have A/AAAA records pointing to Traefik. Each [domain](../../internet/Domain.md) & SAN will lead to a certificate request. ```yaml http: routers: routerbar: rule: "Host(`snitest.com`) && Path(`/bar`)" tls: certResolver: "bar" domains: - main: "snitest.com" sans: - "*.snitest.com" ``` ### Services The Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests. Example: ```yaml http: services: my-service: loadBalancer: servers: - url: "http://:/" - url: "http://:/" tcp: services: my-service: loadBalancer: servers: - address: ":" - address: ":" ``` #### Load Balancing Traefik can load balance across multiple servers with the `loadBalancer.servers` list. ```yaml http: services: my-service: loadBalancer: servers: - url: "http://server1:8080" - url: "http://server2:8080 ``` #### Servers Transport `serversTransport` allows to reference a ServersTransport configuration for the communication between Traefik and your servers. ```yaml http: services: Service01: loadBalancer: serversTransport: mytransport ``` Define a serverTransport configuration: ```yaml http: serversTransports: mytransport: ``` You can define root CAs used for verifying SSL between traefik and your servers: ```yaml http: serversTransports: mytransport: rootCAs: - foo.crt - bar.crt ``` Or skip SSL verification: ```yaml http: serversTransports: mytransport: insecureSkipVerify: true ``` ### TLS Traefik supports HTTPS & TLS, which concerns roughly two parts of the configuration: routers, and the TLS connection (and its underlying certificates). Traefik requires you to define "Certificate Resolvers" in the static configuration, which are responsible for retrieving certificates from an ACME server. ```yaml certificatesResolvers: myresolver: # Enable ACME (Let's Encrypt): automatic SSL. acme: email: "test@example.com" # File or key used for certificates storage. storage: "acme.json" # The certificates' duration in hours. # It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration. # # Optional # Default: 2160 # certificatesDuration: 2160 # Use a TLS-ALPN-01 ACME challenge. # # Optional (but recommended) # tlsChallenge: # Use a HTTP-01 ACME challenge. # # Optional # httpChallenge: # EntryPoint to use for the HTTP-01 challenges. # # Required # entryPoint: web # Use a DNS-01 ACME challenge rather than HTTP-01 challenge. # Note: mandatory for wildcard certificate generation. # # Optional # dnsChallenge: # DNS provider used. # # Required # provider: digitalocean # By default, the provider will verify the TXT DNS challenge record before letting ACME verify. # If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds. # Useful if internal networks block external DNS queries. # # Optional # Default: 0 # delayBeforeCheck: 0 # Use following DNS servers to resolve the FQDN authority. # # Optional # Default: empty # resolvers - "1.1.1.1:53" - "8.8.8.8:53" ``` ### Middlewares Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service (or before the answer from the services are sent to the clients). ```yaml http: routers: router1: service: myService middlewares: - "foo-add-prefix" rule: "Host(`example.com`)" middlewares: foo-add-prefix: addPrefix: prefix: "/foo" services: service1: loadBalancer: servers: - url: "http://127.0.0.1:80" ``` #### [HTTP](../../internet/HTTP.md) Middlewares ##### Add Prefix The AddPrefix middleware updates the path of a request before forwarding it. So `http://domain/path` would be `http://domain/prefix/path` if used. ```yaml http: middlewares: add-foo: addPrefix: prefix: "/prefix" ``` ##### BasicAuth The BasicAuth middleware grants access to services to authorized users only. - `users` The `users` option is an array of authorized users. Each user must be declared using the name:hashed-password format. ```yaml http: middlewares: test-auth: basicAuth: users: - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" ``` - `usersFile` The `usersFile` option is the path to an external file that contains the authorized users for the middleware. ```yaml http: middlewares: test-auth: basicAuth: usersFile: "/path/to/my/usersfile" ``` - `headerField` You can define a header field to store the authenticated user using the `headerFieldoption`. ```yaml http: middlewares: my-auth: basicAuth: # ... headerField: "X-WebAuth-User" ``` - `removeHeader` Set the `removeHeader` option to `true` to remove the authorization header before forwarding the request to your service. (Default value is `false`.) ##### Compress Compress Responses before Sending them to the Client. The Compress middleware uses gzip compression. - `excludedContentTypes` specifies a list of content types to compare the Content-Type header of the incoming requests and responses before compressing. The responses with content types defined in `excludedContentTypes` are not compressed. - `minResponseBodyBytes` specifies the minimum amount of bytes a response body must have to be compressed. The default value is 1024, which should be a reasonable value for most cases. ```yaml http: middlewares: test-compress: compress: excludedContentTypes: - text/event-stream minResponseBodyBytes: 1200 ``` ##### ContentType The Content-Type middleware - or rather its `autoDetect` option - specifies whether to let the Content-Type header, if it has not been defined by the backend, be automatically set to a value derived from the contents of the response. ```yaml http: middlewares: autodetect: contentType: autoDetect: true ``` ##### DigestAuth Adding Digest Authentication. The configuration options are the same as BasicAuth middleware. ```yaml http: middlewares: test-auth: digestAuth: users: - "test:traefik:a2688e031edb4be6a3797f3882655c05" - "test2:traefik:518845800f9e2bfb1f1f740ec24f074e" ``` ##### Errors The Errors middleware returns a custom page in lieu of the default, according to configured ranges of [HTTP](../../internet/HTTP.md) Status codes. ```yaml http: middlewares: test-errors: errors: status: - "500" - "501" - "503" - "505-599" service: serviceError query: "/{status}.html" ``` - `status` The status option defines which status or range of statuses should result in an error page. The status code ranges are inclusive (`505-599` will trigger with every code between `505` and `599`, `505` and `599` included). - `service` The service that will serve the new requested error page. - `query` The [URL](../../internet/URL.md) for the error page (hosted by `service`). There are multiple variables that can be placed in the query option to insert values in the [URL](../../internet/URL.md). The table below lists all the available variables and their associated values. | Variable | Value | | ---------- | ------------------------- | | `{status}` | The response status code. | | `{url}` | The escaped request [URL](../../internet/URL.md). | ##### ForwardAuth The ForwardAuth middleware delegates authentication to an external service. If the service answers with a 2XX code, access is granted, and the original request is performed. Otherwise, the response from the authentication server is returned. ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" ``` ###### Forward-Request Headers The following request properties are provided to the forward-auth target endpoint as X-Forwarded- headers: | Property | Forward-Request Header | | ----------------- | ---------------------- | | [HTTP](../../internet/HTTP.md) Method | `X-Forwarded-Method` | | Protocol | `X-Forwarded-Proto` | | Host | `X-Forwarded-Host` | | Request URI | `X-Forwarded-Uri` | | Source IP-Address | `X-Forwarded-For` | - `address`: The `address` option defines the authentication server address. ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" ``` - `trustForwardHeader` Set the `trustForwardHeader` option to `true` to trust all `X-Forwarded-*` headers. ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" trustForwardHeader: true ``` - `authResponseHeaders` The `authResponseHeaders` option is the list of headers to copy from the authentication server response and set on forwarded request, replacing any existing conflicting headers. ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" authResponseHeaders: - "X-Auth-User" - "X-Secret" ``` - `authResponseHeadersRegex` The `authResponseHeadersRegex` option is the [regex](../../tools/Regex.md) to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the [regex](../../tools/Regex.md). ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" authResponseHeadersRegex: "^X-" ``` - `authRequestHeaders` The `authRequestHeaders` option is the list of the headers to copy from the request to the authentication server. It allows filtering headers that should not be passed to the authentication server. If not set or empty then all request headers are passed. ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" authRequestHeaders: - "Accept" - "X-CustomHeader" ``` - `tls` Defines the TLS configuration used for the secure connection to the authentication server. ```yaml http: middlewares: test-auth: forwardAuth: address: "https://example.com/auth" tls: # CA used for SSL ca: "path/to/local.crt" # Skip SSL insecureSkipVerify: true ``` ##### Headers Managing Request/Response headers ```yaml http: middlewares: testHeader: headers: customRequestHeaders: X-Script-Name: "test" customResponseHeaders: X-Custom-Response-Header: "value" ``` - Add/Remove Headers ```yaml http: middlewares: testHeader: headers: customRequestHeaders: X-Script-Name: "test" # Adds X-Custom-Request-Header: "" # Removes customResponseHeaders: X-Custom-Response-Header: "" # Removes ``` - CORS Headers ```yaml http: middlewares: testHeader: headers: accessControlAllowMethods: - GET - OPTIONS - PUT accessControlAllowHeaders: "*" accessControlAllowOriginList: - https://foo.bar.org - https://example.org accessControlMaxAge: 100 addVaryHeader: true ``` ##### IPWhiteList Limiting Clients to Specific IPs IPWhitelist accepts / refuses requests based on the client IP. ```yaml http: middlewares: test-ipwhitelist: ipWhiteList: sourceRange: - "127.0.0.1/32" - "192.168.1.7" ``` ##### Ratelimit The RateLimit middleware ensures that services will receive a fair amount of requests, and allows one to define what fair is. It is based on a token bucket implementation. In this analogy, the average parameter (defined below) is the rate at which the bucket refills, and the burst is the size (volume) of the bucket. ```yaml http: middlewares: test-ratelimit: rateLimit: average: 100 burst: 50 ``` - `average` `average` is the maximum rate, by default in requests per second, allowed from a given source. It defaults to `0`, which means no rate limiting. The rate is actually defined by dividing `average` by `period`. - `period` `period`, in combination with `average`, defines the actual maximum rate. It defaults to `1` second. - `burst` `burst` is the maximum number of requests allowed to go through in the same arbitrarily small period of time. It defaults to `1`. You can exclude IPs from rate limiting: ```yaml http: middlewares: test-ratelimit: rateLimit: sourceCriterion: ipStrategy: excludedIPs: - "127.0.0.1/32" - "192.168.1.7" ``` ##### RedirectScheme The RedirectScheme middleware redirects the request if the request scheme is different from the configured scheme. ```yaml http: middlewares: test-redirectscheme: redirectScheme: scheme: https permanent: true ``` ##### RedirectRegex The RedirectRegex redirects a request using [regex](../../tools/Regex.md) matching and replacement. ```yaml http: middlewares: test-redirectregex: redirectRegex: regex: "^http://localhost/(.*)" replacement: "http://mydomain/${1}" ``` ##### ReplacePath The ReplacePath middleware will: - replace the actual path with the specified one. - store the original path in a `X-Replaced-Path` header. ```yaml http: middlewares: test-replacepath: replacePath: path: "/foo" ``` ##### ReplacePathRegex The ReplacePathRegex middleware will: - replace the matching path with the specified one. - store the original path in a `X-Replaced-Path` header. ```yaml http: middlewares: test-replacepathregex: replacePathRegex: regex: "^/foo/(.*)" replacement: "/bar/$1" ``` ##### Retry The Retry middleware reissues requests a given number of times to a backend server if that server does not reply. As soon as the server answers, the middleware stops retrying, regardless of the response status. The Retry middleware has an optional configuration to enable an exponential backoff. ```yaml http: middlewares: test-retry: retry: attempts: 4 initialInterval: 100ms ``` ##### StripPrefix Remove the specified prefixes from the [URL](../../internet/URL.md) path. ```yaml http: middlewares: test-stripprefix: stripPrefix: prefixes: - "/foobar" - "/fiibar" ``` ##### StripPrefixRegex Remove the matching prefixes from the [URL](../../internet/URL.md) path. ```yaml http: middlewares: test-stripprefixregex: stripPrefixRegex: regex: - "/foo/[a-z0-9]+/[0-9]+/" ``` ### Access log Access logs allow you to keep track of what request are made to your server. To enable the access logs: ```yaml accessLog: {} ``` - `filePath`: By default access logs are written to the standard output. To write the logs into a [log file](../../dev/Log.md), use the `filePath` option. ```yaml accessLog: filePath: "/path/to/access.log" ``` - `format`: By default, logs are written using the Common Log Format (CLF). To write logs in [JSON](../../files/JSON.md), use `json` in the `format` option. If the given format is unsupported, the default (CLF) is used instead. > Common Log Format > ``` > - [] " " "" "" "" "" m >``` - `bufferingSize` To write the logs in an asynchronous fashion, specify a `bufferingSize` option. This option represents the number of log lines Traefik will keep in memory before writing them to the selected output. In some cases, this option can greatly help performances. ```yaml # Configuring a buffer of 100 lines accessLog: filePath: "/path/to/access.log" bufferingSize: 100 ``` #### Filtering To filter logs, you can specify a set of filters which are logically "OR-connected". Thus, specifying multiple filters will keep more access logs than specifying only one. The available filters are: - `statusCodes`, to limit the access logs to requests with a status codes in the specified range - `retryAttempts`, to keep the access logs when at least one retry has happened - `minDuration`, to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format) ```yaml # Configuring Multiple Filters accessLog: filePath: "/path/to/access.log" format: json filters: statusCodes: - "200" - "300-302" retryAttempts: true minDuration: "10ms" ``` ##### Limiting the Fields/Including Headers You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.headers` options. Each field can be set to: - `keep` to keep the value - `drop` to drop the value - `redact` to replace the value with "redacted" The `defaultMode` for `fields.names` is `keep`. The `defaultMode` for `fields.headers` is `drop`. ```yaml # Limiting the Logs to Specific Fields accessLog: filePath: "/path/to/access.log" format: json fields: defaultMode: keep names: ClientUsername: drop headers: defaultMode: keep names: User-Agent: redact Authorization: drop Content-Type: keep ```