From 24862402e5f1acab8815bc9bfccc425338bd037d Mon Sep 17 00:00:00 2001 From: Julien Maitrehenry Date: Fri, 25 Aug 2017 15:32:33 -0400 Subject: [PATCH] Refactor doc pages --- docs/backends/api.md | 249 +++++ docs/backends/boltdb.md | 39 + docs/backends/consul.md | 121 +++ docs/backends/docker.md | 110 ++ docs/backends/dynamodb.md | 68 ++ docs/backends/ecs.md | 120 +++ docs/backends/etcd.md | 58 + docs/backends/eureka.md | 38 + docs/backends/file.md | 173 +++ docs/backends/kubernetes.md | 104 ++ docs/backends/marathon.md | 166 +++ docs/backends/mesos.md | 85 ++ docs/backends/rancher.md | 117 ++ docs/backends/zookeeper.md | 41 + docs/configuration/acme.md | 125 +++ docs/configuration/toml.md | 412 +++++++ docs/img/traefik-health.png | Bin 53776 -> 102955 bytes docs/toml.md | 2017 ----------------------------------- mkdocs.yml | 18 +- 19 files changed, 2043 insertions(+), 2018 deletions(-) create mode 100644 docs/backends/api.md create mode 100644 docs/backends/boltdb.md create mode 100644 docs/backends/consul.md create mode 100644 docs/backends/docker.md create mode 100644 docs/backends/dynamodb.md create mode 100644 docs/backends/ecs.md create mode 100644 docs/backends/etcd.md create mode 100644 docs/backends/eureka.md create mode 100644 docs/backends/file.md create mode 100644 docs/backends/kubernetes.md create mode 100644 docs/backends/marathon.md create mode 100644 docs/backends/mesos.md create mode 100644 docs/backends/rancher.md create mode 100644 docs/backends/zookeeper.md create mode 100644 docs/configuration/acme.md create mode 100644 docs/configuration/toml.md delete mode 100644 docs/toml.md diff --git a/docs/backends/api.md b/docs/backends/api.md new file mode 100644 index 000000000..c9f5001ec --- /dev/null +++ b/docs/backends/api.md @@ -0,0 +1,249 @@ +# API backend + +Træfik can be configured using a RESTful api. + +## Configuration +### CLI + +| Flag | Description | Default | +|------------------------------------|----------------------------------|---------------------| +| `--web` | Enable Web backend | `"true"` | +| `--web.address` | Web administration port | `":8080"` | +| `--web.certfile` | SSL certificate | | +| `--web.keyfile` | SSL key | | +| `--web.metrics` | Enable a metrics exporter | `"true"` | +| `--web.metrics.prometheus` | Prometheus metrics exporter type | `"true"` | +| `--web.metrics.prometheus.buckets` | Buckets for latency metrics | `"[0.1 0.3 1.2 5]"` | +| `--web.path` | Root path for dashboard and API | | +| `--web.readonly` | Enable read only API | `"false"` | +| `--web.statistics` | Enable more detailed statistics | `"false"` | +| `--web.statistics.recenterrors` | Number of recent errors logged | `"10"` | + +### traefik.toml: + +```toml +[web] +address = ":8080" + +# Set the root path for webui and API +# +# Optional +# +# path = "/mypath" +# +# SSL certificate and key used +# +# Optional +# +# CertFile = "traefik.crt" +# KeyFile = "traefik.key" +# +# Set REST API to read-only mode +# +# Optional +# ReadOnly = false +# +# To enable more detailed statistics +# [web.statistics] +# RecentErrors = 10 +# +# To enable Traefik to export internal metrics to Prometheus +# [web.metrics.prometheus] +# Buckets=[0.1,0.3,1.2,5.0] +# +# To enable Traefik to export internal metics to DataDog +# [web.metrics.datadog] +# Address = localhost:8125 +# PushInterval = "10s" +# +# To enable Traefik to export internal metics to StatsD +# [web.metrics.statsd] +# Address = localhost:8125 +# PushInterval = "10s" +# +# To enable basic auth on the webui +# with 2 user/pass: test:test and test2:test2 +# Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones +# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence +# [web.auth.basic] +# users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] +# usersFile = "/path/to/.htpasswd" +# To enable digest auth on the webui +# with 2 user/realm/pass: test:traefik:test and test2:traefik:test2 +# You can use htdigest to generate those ones +# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence +# [web.auth.digest] +# users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"] +# usersFile = "/path/to/.htdigest" +``` + +## Web UI +![Web UI Providers](/img/web.frontend.png) + +![Web UI Health](/img/traefik-health.png) + +## API + +| Path | Method | Description | +|-----------------------------------------------------------------|:-------------:|----------------------------------------------------------------------------------------------------| +| `/` | `GET` | Provides a simple HTML frontend of Træfik | +| `/ping` | `GET`, `HEAD` | A simple endpoint to check for Træfik process liveness. Return a code `200` with the content: `OK` | +| `/health` | `GET` | json health metrics | +| `/api` | `GET` | Configuration for all providers | +| `/api/providers` | `GET` | Providers | +| `/api/providers/{provider}` | `GET`, `PUT` | Get or update provider | +| `/api/providers/{provider}/backends` | `GET` | List backends | +| `/api/providers/{provider}/backends/{backend}` | `GET` | Get backend | +| `/api/providers/{provider}/backends/{backend}/servers` | `GET` | List servers in backend | +| `/api/providers/{provider}/backends/{backend}/servers/{server}` | `GET` | Get a server in a backend | +| `/api/providers/{provider}/frontends` | `GET` | List frontends | +| `/api/providers/{provider}/frontends/{frontend}` | `GET` | Get a frontend | +| `/api/providers/{provider}/frontends/{frontend}/routes` | `GET` | List routes in a frontend | +| `/api/providers/{provider}/frontends/{frontend}/routes/{route}` | `GET` | Get a route in a frontend | +| `/metrics` | `GET` | Export internal metrics | + +> You can enable Traefik to export internal metrics to different monitoring systems (Only Prometheus is supported at the moment). + +>```bash +>$ traefik --web.metrics.prometheus --web.metrics.prometheus.buckets="0.1,0.3,1.2,5.0" +>``` + +### Example +#### Ping +```shell +$ curl -sv "http://localhost:8080/ping" +* Trying ::1... +* Connected to localhost (::1) port 8080 (#0) +> GET /ping HTTP/1.1 +> Host: localhost:8080 +> User-Agent: curl/7.43.0 +> Accept: */* +> +< HTTP/1.1 200 OK +< Date: Thu, 25 Aug 2016 01:35:36 GMT +< Content-Length: 2 +< Content-Type: text/plain; charset=utf-8 +< +* Connection #0 to host localhost left intact +OK +``` + +#### Health +```shell +$ curl -s "http://localhost:8080/health" | jq . +{ + // Træfik PID + "pid": 2458, + // Træfik server uptime (formated time) + "uptime": "39m6.885931127s", + // Træfik server uptime in seconds + "uptime_sec": 2346.885931127, + // current server date + "time": "2015-10-07 18:32:24.362238909 +0200 CEST", + // current server date in seconds + "unixtime": 1444235544, + // count HTTP response status code in realtime + "status_code_count": { + "502": 1 + }, + // count HTTP response status code since Træfik started + "total_status_code_count": { + "200": 7, + "404": 21, + "502": 13 + }, + // count HTTP response + "count": 1, + // count HTTP response + "total_count": 41, + // sum of all response time (formated time) + "total_response_time": "35.456865605s", + // sum of all response time in seconds + "total_response_time_sec": 35.456865605, + // average response time (formated time) + "average_response_time": "864.8016ms", + // average response time in seconds + "average_response_time_sec": 0.8648016000000001, + + // request statistics [requires --web.statistics to be set] + // ten most recent requests with 4xx and 5xx status codes + "recent_errors": [ + { + // status code + "status_code": 500, + // description of status code + "status": "Internal Server Error", + // request HTTP method + "method": "GET", + // request hostname + "host": "localhost", + // request path + "path": "/path", + // RFC 3339 formatted date/time + "time": "2016-10-21T16:59:15.418495872-07:00" + } + ] +} +``` + +#### Provider configurations +```shell +$ curl -s "http://localhost:8080/api" | jq . +{ + "file": { + "frontends": { + "frontend2": { + "routes": { + "test_2": { + "rule": "Path:/test" + } + }, + "backend": "backend1" + }, + "frontend1": { + "routes": { + "test_1": { + "rule": "Host:test.localhost" + } + }, + "backend": "backend2" + } + }, + "backends": { + "backend2": { + "loadBalancer": { + "method": "drr" + }, + "servers": { + "server2": { + "weight": 2, + "URL": "http://172.17.0.5:80" + }, + "server1": { + "weight": 1, + "url": "http://172.17.0.4:80" + } + } + }, + "backend1": { + "loadBalancer": { + "method": "wrr" + }, + "circuitBreaker": { + "expression": "NetworkErrorRatio() > 0.5" + }, + "servers": { + "server2": { + "weight": 1, + "url": "http://172.17.0.3:80" + }, + "server1": { + "weight": 10, + "url": "http://172.17.0.2:80" + } + } + } + } + } +} +``` diff --git a/docs/backends/boltdb.md b/docs/backends/boltdb.md new file mode 100644 index 000000000..1a872b4d3 --- /dev/null +++ b/docs/backends/boltdb.md @@ -0,0 +1,39 @@ +# BoltDB backend + +Træfik can be configured to use BoltDB as a backend configuration: + +```toml +################################################################ +# BoltDB configuration backend +################################################################ + +# Enable BoltDB configuration backend +# +# Optional +# +[boltdb] + +# BoltDB file +# +# Required +# +endpoint = "/my.db" + +# Enable watch BoltDB changes +# +# Optional +# +watch = true + +# Prefix used for KV store. +# +# Optional +# +prefix = "/traefik" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "boltdb.tmpl" +``` \ No newline at end of file diff --git a/docs/backends/consul.md b/docs/backends/consul.md new file mode 100644 index 000000000..8aac5cea4 --- /dev/null +++ b/docs/backends/consul.md @@ -0,0 +1,121 @@ +# Consul backend +## Consul Key-Value backend + +Træfik can be configured to use Consul as a backend configuration: + +```toml +################################################################ +# Consul KV configuration backend +################################################################ + +# Enable Consul KV configuration backend +# +# Optional +# +[consul] + +# Consul server endpoint +# +# Required +# +endpoint = "127.0.0.1:8500" + +# Enable watch Consul changes +# +# Optional +# +watch = true + +# Prefix used for KV store. +# +# Optional +# +prefix = "traefik" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "consul.tmpl" + +# Enable consul TLS connection +# +# Optional +# +# [consul.tls] +# ca = "/etc/ssl/ca.crt" +# cert = "/etc/ssl/consul.crt" +# key = "/etc/ssl/consul.key" +# insecureskipverify = true +``` + +Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. + +## Consul catalog backend + +Træfik can be configured to use service discovery catalog of Consul as a backend configuration: + +```toml +################################################################ +# Consul Catalog configuration backend +################################################################ + +# Enable Consul Catalog configuration backend +# +# Optional +# +[consulCatalog] + +# Consul server endpoint +# +# Required +# +endpoint = "127.0.0.1:8500" + +# Default domain used. +# +# Optional +# +domain = "consul.localhost" + +# Expose Consul catalog services by default in traefik +# +# Optional +# Default: true +# +exposedByDefault = false + +# Prefix for Consul catalog tags +# +# Optional +# +prefix = "traefik" + +# Default frontEnd Rule for Consul services +# The format is a Go Template with ".ServiceName", ".Domain" and ".Attributes" available +# "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available +# "getAttribute(...)" function uses prefixed tag names based on "prefix" value +# +# Optional +# +frontEndRule = "Host:{{.ServiceName}}.{{Domain}}" +``` + +This backend will create routes matching on hostname based on the service name +used in consul. + +Additional settings can be defined using Consul Catalog tags: + +| Tag | Description | +|---------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.enable=false` | Disable this container in Træfik | +| `traefik.protocol=https` | Override the default `http` protocol | +| `traefik.backend.weight=10` | Assign this weight to the container | +| `traefik.backend.circuitbreaker=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend, ex: `NetworkErrorRatio() > 0.` | +| `traefik.backend.loadbalancer=drr` | Override the default load balancing mode | +| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. | +| `traefik.frontend.rule=Host:test.traefik.io` | Override the default frontend rule (Default: `Host:{{.ServiceName}}.{{.Domain}}`). | +| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | +| `traefik.frontend.priority=10` | Override default frontend priority | +| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. | \ No newline at end of file diff --git a/docs/backends/docker.md b/docs/backends/docker.md new file mode 100644 index 000000000..cfc5d541d --- /dev/null +++ b/docs/backends/docker.md @@ -0,0 +1,110 @@ +# Docker backend + +Træfik can be configured to use Docker as a backend configuration: + +```toml +################################################################ +# Docker configuration backend +################################################################ + +# Enable Docker configuration backend +# +# Optional +# +[docker] + +# Docker server endpoint. Can be a tcp or a unix socket endpoint. +# +# Required +# +endpoint = "unix:///var/run/docker.sock" + +# Default domain used. +# Can be overridden by setting the "traefik.domain" label on a container. +# +# Required +# +domain = "docker.localhost" + +# Enable watch docker changes +# +# Optional +# +watch = true + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "docker.tmpl" + +# Expose containers by default in traefik +# If set to false, containers that don't have `traefik.enable=true` will be ignored +# +# Optional +# Default: true +# +exposedbydefault = true + +# Use the IP address from the binded port instead of the inner network one. For specific use-case :) + +# +# Optional +# Default: false +# +usebindportip = true +# Use Swarm Mode services as data provider +# +# Optional +# Default: false +# +swarmmode = false + + +# Enable docker TLS connection +# +# [docker.tls] +# ca = "/etc/ssl/ca.crt" +# cert = "/etc/ssl/docker.crt" +# key = "/etc/ssl/docker.key" +# insecureskipverify = true +``` + +### Labels can be used on containers to override default behaviour + +| Label | Description | +|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | +| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. | +| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. | +| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | +| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions | +| `traefik.backend.loadbalancer.swarm=true` | Use Swarm's inbuilt load balancer (only relevant under Swarm Mode). | +| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | +| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | +| `traefik.protocol=https` | Override the default `http` protocol | +| `traefik.weight=10` | Assign this weight to the container | +| `traefik.enable=false` | Disable this container in Træfik | +| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. | +| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | +| `traefik.frontend.priority=10` | Override default frontend priority | +| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` | +| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` | +| `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | +| `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with docker inspect ) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. | + +### Services labels can be used for overriding default behaviour + +| Label | Description | +|---------------------------------------------------|--------------------------------------------------------------------------------------------------| +| `traefik..port=PORT` | Overrides `traefik.port`. If several ports need to be exposed, the service labels could be used. | +| `traefik..protocol` | Overrides `traefik.protocol`. | +| `traefik..weight` | Assign this service weight. Overrides `traefik.weight`. | +| `traefik..frontend.backend=BACKEND` | Assign this service frontend to `BACKEND`. Default is to assign to the service backend. | +| `traefik..frontend.entryPoints` | Overrides `traefik.frontend.entrypoints` | +| `traefik..frontend.auth.basic` | Sets a Basic Auth for that frontend | +| `traefik..frontend.passHostHeader` | Overrides `traefik.frontend.passHostHeader`. | +| `traefik..frontend.priority` | Overrides `traefik.frontend.priority`. | +| `traefik..frontend.rule` | Overrides `traefik.frontend.rule`. | + +NB: when running inside a container, Træfik will need network access through `docker network connect ` \ No newline at end of file diff --git a/docs/backends/dynamodb.md b/docs/backends/dynamodb.md new file mode 100644 index 000000000..17d9a9d5a --- /dev/null +++ b/docs/backends/dynamodb.md @@ -0,0 +1,68 @@ +# DynamoDB backend + +Træfik can be configured to use Amazon DynamoDB as a backend configuration: + + +```toml +################################################################ +# DynamoDB configuration backend +################################################################ + +# Enable DynamoDB configuration backend +# +# Optional +# +[dynamodb] + +# DyanmoDB Table Name +# +# Optional +# +TableName = "traefik" + +# Enable watch DynamoDB changes +# +# Optional +# +Watch = true + +# Polling interval (in seconds) +# +# Optional +# +RefreshSeconds = 15 + +# Region to use when connecting to AWS +# +# Required +# +Region = "us-west-1" + +# AccessKeyID to use when connecting to AWS +# +# Optional +# +AccessKeyID = "abc" + +# SecretAccessKey to use when connecting to AWS +# +# Optional +# +SecretAccessKey = "123" + +# Endpoint of local dynamodb instance for testing +# +# Optional +# +Endpoint = "http://localhost:8080" + +``` + +Items in the `dynamodb` table must have three attributes: + +- `id` : string + - The id is the primary key. +- `name` : string + - The name is used as the name of the frontend or backend. +- `frontend` or `backend` : map + - This attribute's structure matches exactly the structure of a Frontend or Backend type in traefik. See `types/types.go` for details. The presence or absence of this attribute determines its type. So an item should never have both a `frontend` and a `backend` attribute. \ No newline at end of file diff --git a/docs/backends/ecs.md b/docs/backends/ecs.md new file mode 100644 index 000000000..0501ce0e8 --- /dev/null +++ b/docs/backends/ecs.md @@ -0,0 +1,120 @@ +# ECS backend + +Træfik can be configured to use Amazon ECS as a backend configuration: + + +```toml +################################################################ +# ECS configuration backend +################################################################ + +# Enable ECS configuration backend +# +# Optional +# +[ecs] + +# ECS Cluster Name +# +# Deprecated - Please use Clusters +# +Cluster = "default" + +# ECS Clusters Name +# +# Optional +# Default: ["default"] +# +Clusters = ["default"] + +# Enable watch ECS changes +# +# Optional +# Default: true +# +Watch = true + +# Enable auto discover ECS clusters +# +# Optional +# Default: false +# +AutoDiscoverClusters = false + +# Polling interval (in seconds) +# +# Optional +# Default: 15 +# +RefreshSeconds = 15 + +# Expose ECS services by default in traefik +# +# Optional +# Default: true +# +ExposedByDefault = false + +# Region to use when connecting to AWS +# +# Optional +# +Region = "us-east-1" + +# AccessKeyID to use when connecting to AWS +# +# Optional +# +AccessKeyID = "abc" + +# SecretAccessKey to use when connecting to AWS +# +# Optional +# +SecretAccessKey = "123" + +``` + +Labels can be used on task containers to override default behaviour: + +- `traefik.protocol=https`: override the default `http` protocol +- `traefik.weight=10`: assign this weight to the container +- `traefik.enable=false`: disable this container in Træfik +- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm +- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions +- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). +- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. +- `traefik.frontend.priority=10`: override default frontend priority +- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. + +If `AccessKeyID`/`SecretAccessKey` is not given credentials will be resolved in the following order: + +- From environment variables; `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`. +- Shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to `default` and `~/.aws/credentials`. +- EC2 instance role or ECS task role + +Træfik needs the following policy to read ECS information: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Traefik ECS read access", + "Effect": "Allow", + "Action": [ + "ecs:ListClusters", + "ecs:DescribeClusters", + "ecs:ListTasks", + "ecs:DescribeTasks", + "ecs:DescribeContainerInstances", + "ecs:DescribeTaskDefinition", + "ec2:DescribeInstances" + ], + "Resource": [ + "*" + ] + } + ] +} +``` diff --git a/docs/backends/etcd.md b/docs/backends/etcd.md new file mode 100644 index 000000000..e621739e4 --- /dev/null +++ b/docs/backends/etcd.md @@ -0,0 +1,58 @@ +# Etcd backend + +Træfik can be configured to use Etcd as a backend configuration: + +```toml +################################################################ +# Etcd configuration backend +################################################################ + +# Enable Etcd configuration backend +# +# Optional +# +[etcd] + +# Etcd server endpoint +# +# Required +# +endpoint = "127.0.0.1:2379" + +# Enable watch Etcd changes +# +# Optional +# +watch = true + +# Prefix used for KV store. +# +# Optional +# +prefix = "/traefik" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "etcd.tmpl" + +# Use etcd user/pass authentication +# +# Optional +# +# username = foo +# password = bar + +# Enable etcd TLS connection +# +# Optional +# +# [etcd.tls] +# ca = "/etc/ssl/ca.crt" +# cert = "/etc/ssl/etcd.crt" +# key = "/etc/ssl/etcd.key" +# insecureskipverify = true +``` + +Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. diff --git a/docs/backends/eureka.md b/docs/backends/eureka.md new file mode 100644 index 000000000..25e5053fc --- /dev/null +++ b/docs/backends/eureka.md @@ -0,0 +1,38 @@ +# Eureka backend + +Træfik can be configured to use Eureka as a backend configuration: + + +```toml +################################################################ +# Eureka configuration backend +################################################################ + +# Enable Eureka configuration backend +# +# Optional +# +[eureka] + +# Eureka server endpoint. +# endpoint := "http://my.eureka.server/eureka" +# +# Required +# +endpoint = "http://my.eureka.server/eureka" + +# Override default configuration time between refresh +# +# Optional +# default 30s +delay = "1m" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "eureka.tmpl" +``` + +Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. + diff --git a/docs/backends/file.md b/docs/backends/file.md new file mode 100644 index 000000000..06ad47dda --- /dev/null +++ b/docs/backends/file.md @@ -0,0 +1,173 @@ +# File backends + +Like any other reverse proxy, Træfik can be configured with a file. You have three choices: + +- simply add your configuration at the end of the global configuration file `traefik.toml`: + +```toml +# traefik.toml +logLevel = "DEBUG" +defaultEntryPoints = ["http", "https"] +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.com.cert" + KeyFile = "integration/fixtures/https/snitest.com.key" + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.org.cert" + KeyFile = "integration/fixtures/https/snitest.org.key" + +[file] + +# rules +[backends] + [backends.backend1] + [backends.backend1.circuitbreaker] + expression = "NetworkErrorRatio() > 0.5" + [backends.backend1.servers.server1] + url = "http://172.17.0.2:80" + weight = 10 + [backends.backend1.servers.server2] + url = "http://172.17.0.3:80" + weight = 1 + [backends.backend2] + [backends.backend2.maxconn] + amount = 10 + extractorfunc = "request.host" + [backends.backend2.LoadBalancer] + method = "drr" + [backends.backend2.servers.server1] + url = "http://172.17.0.4:80" + weight = 1 + [backends.backend2.servers.server2] + url = "http://172.17.0.5:80" + weight = 2 + +[frontends] + [frontends.frontend1] + backend = "backend2" + [frontends.frontend1.routes.test_1] + rule = "Host:test.localhost" + [frontends.frontend2] + backend = "backend1" + passHostHeader = true + priority = 10 + + # restrict access to this frontend to the specified list of IPv4/IPv6 CIDR Nets + # an unset or empty list allows all Source-IPs to access + # if one of the Net-Specifications are invalid, the whole list is invalid + # and allows all Source-IPs to access. + whitelistSourceRange = ["10.42.0.0/16", "152.89.1.33/32", "afed:be44::/16"] + + entrypoints = ["https"] # overrides defaultEntryPoints + [frontends.frontend2.routes.test_1] + rule = "Host:{subdomain:[a-z]+}.localhost" + [frontends.frontend3] + entrypoints = ["http", "https"] # overrides defaultEntryPoints + backend = "backend2" + rule = "Path:/test" +``` + +- or put your rules in a separate file, for example `rules.toml`: + +```toml +# traefik.toml +logLevel = "DEBUG" +[entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.com.cert" + KeyFile = "integration/fixtures/https/snitest.com.key" + [[entryPoints.https.tls.certificates]] + CertFile = "integration/fixtures/https/snitest.org.cert" + KeyFile = "integration/fixtures/https/snitest.org.key" + +[file] +filename = "rules.toml" +``` + +```toml +# rules.toml +[backends] + [backends.backend1] + [backends.backend1.circuitbreaker] + expression = "NetworkErrorRatio() > 0.5" + [backends.backend1.servers.server1] + url = "http://172.17.0.2:80" + weight = 10 + [backends.backend1.servers.server2] + url = "http://172.17.0.3:80" + weight = 1 + [backends.backend2] + [backends.backend2.maxconn] + amount = 10 + extractorfunc = "request.host" + [backends.backend2.LoadBalancer] + method = "drr" + [backends.backend2.servers.server1] + url = "http://172.17.0.4:80" + weight = 1 + [backends.backend2.servers.server2] + url = "http://172.17.0.5:80" + weight = 2 + +[frontends] + [frontends.frontend1] + backend = "backend2" + [frontends.frontend1.routes.test_1] + rule = "Host:test.localhost" + [frontends.frontend2] + backend = "backend1" + passHostHeader = true + priority = 10 + entrypoints = ["https"] # overrides defaultEntryPoints + [frontends.frontend2.routes.test_1] + rule = "Host:{subdomain:[a-z]+}.localhost" + [frontends.frontend3] + entrypoints = ["http", "https"] # overrides defaultEntryPoints + backend = "backend2" + rule = "Path:/test" +``` + +- or you could have multiple .toml files in a directory: + +```toml +[file] +directory = "/path/to/config/" +``` + +If you want Træfik to watch file changes automatically, just add: + +```toml +[file] +watch = true +``` + +The configuration files can be also templates written using functions provided by [go template](https://golang.org/pkg/text/template/) as well as functions provided by the [sprig library](http://masterminds.github.io/sprig/), like this: + +```tmpl +[backends] + [backends.backend1] + url = "http://firstserver" + [backends.backend2] + url = "http://secondserver" + +{{$frontends := dict "frontend1" "backend1" "frontend2" "backend2"}} +[frontends] +{{range $frontend, $backend := $frontends}} + [frontends.{{$frontend}}] + backend = "{{$backend}}" +{{end}} +``` \ No newline at end of file diff --git a/docs/backends/kubernetes.md b/docs/backends/kubernetes.md new file mode 100644 index 000000000..23392a242 --- /dev/null +++ b/docs/backends/kubernetes.md @@ -0,0 +1,104 @@ +# Kubernetes Ingress backend + + +Træfik can be configured to use Kubernetes Ingress as a backend configuration: + +```toml +################################################################ +# Kubernetes Ingress configuration backend +################################################################ +# Enable Kubernetes Ingress configuration backend +# +# Optional +# +[kubernetes] + +# Kubernetes server endpoint +# +# When deployed as a replication controller in Kubernetes, Traefik will use +# the environment variables KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT +# to construct the endpoint. +# Secure token will be found in /var/run/secrets/kubernetes.io/serviceaccount/token +# and SSL CA cert in /var/run/secrets/kubernetes.io/serviceaccount/ca.crt +# +# The endpoint may be given to override the environment variable values. +# +# When the environment variables are not found, Traefik will try to connect to +# the Kubernetes API server with an external-cluster client. In this case, the +# endpoint is required. Specifically, it may be set to the URL used by +# `kubectl proxy` to connect to a Kubernetes cluster from localhost. +# +# Optional for in-cluster configuration, required otherwise +# Default: empty +# +# endpoint = "http://localhost:8080" + +# Bearer token used for the Kubernetes client configuration. +# +# Optional +# Default: empty +# +# token = "my token" + +# Path to the certificate authority file used for the Kubernetes client +# configuration. +# +# Optional +# Default: empty +# +# certAuthFilePath = "/my/ca.crt" + +# Array of namespaces to watch. +# +# Optional +# Default: all namespaces (empty array). +# +# namespaces = ["default", "production"] + +# Ingress label selector to identify Ingress objects that should be processed. +# See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors for details. +# +# Optional +# Default: empty (process all Ingresses) +# +# labelselector = "A and not B" +``` + +Annotations can be used on containers to override default behaviour for the whole Ingress resource: + +- `traefik.frontend.rule.type: PathPrefixStrip`: override the default frontend rule type (Default: `PathPrefix`). +- `traefik.frontend.priority: 3`: override the default frontend rule priority (Default: `len(Path)`). + +Annotations can be used on the Kubernetes service to override default behaviour: + +- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm +- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions + +You can find here an example [ingress](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml) and [replication controller](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik.yaml). + +Additionally, an annotation can be used on Kubernetes services to set the [circuit breaker expression](https://docs.traefik.io/basics/#backends) for a backend. + +- `traefik.backend.circuitbreaker: `: set the circuit breaker expression for the backend (Default: nil). + +As known from nginx when used as Kubernetes Ingress Controller, a List of IP-Ranges which are allowed to access can be configured by using an ingress annotation: + +- `ingress.kubernetes.io/whitelist-source-range: "1.2.3.0/24, fe80::/16"` + +An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. + + +### Authentication + +Is possible to add additional authentication annotations in the Ingress rule. +The source of the authentication is a secret that contains usernames and passwords inside the the key auth. + +- `ingress.kubernetes.io/auth-type`: `basic` +- `ingress.kubernetes.io/auth-secret`: contains the usernames and passwords with access to the paths defined in the Ingress Rule. + +The secret must be created in the same namespace as the Ingress rule. + +Limitations: + +- Basic authentication only. +- Realm not configurable; only `traefik` default. +- Secret must contain only single file. diff --git a/docs/backends/marathon.md b/docs/backends/marathon.md new file mode 100644 index 000000000..9475b7d8b --- /dev/null +++ b/docs/backends/marathon.md @@ -0,0 +1,166 @@ +# Marathon backend + +Træfik can be configured to use Marathon as a backend configuration: + + +```toml +################################################################ +# Mesos/Marathon configuration backend +################################################################ + +# Enable Marathon configuration backend +# +# Optional +# +[marathon] + +# Marathon server endpoint. +# You can also specify multiple endpoint for Marathon: +# endpoint := "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" +# +# Required +# +endpoint = "http://127.0.0.1:8080" + +# Enable watch Marathon changes +# +# Optional +# +watch = true + +# Default domain used. +# +# Required +# +domain = "marathon.localhost" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "marathon.tmpl" + +# Expose Marathon apps by default in traefik +# +# Optional +# Default: true +# +# exposedByDefault = true + +# Convert Marathon groups to subdomains +# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain} +# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain} +# +# Optional +# Default: false +# +# groupsAsSubDomains = true + +# Enable compatibility with marathon-lb labels +# +# Optional +# Default: false +# +# marathonLBCompatibility = true + +# Enable Marathon basic authentication +# +# Optional +# +# [marathon.basic] +# httpBasicAuthUser = "foo" +# httpBasicPassword = "bar" + +# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config +# +# Optional +# +# [marathon.TLS] +# CA = "/etc/ssl/ca.crt" +# Cert = "/etc/ssl/marathon.cert" +# Key = "/etc/ssl/marathon.key" +# InsecureSkipVerify = true + +# DCOSToken for DCOS environment, This will override the Authorization header +# +# Optional +# +# dcosToken = "xxxxxx" + +# Override DialerTimeout +# Amount of time to allow the Marathon provider to wait to open a TCP connection +# to a Marathon master. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "60s" +# dialerTimeout = "60s" + +# Set the TCP Keep Alive interval for the Marathon HTTP Client. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "10s" +# +# keepAlive = "10s" + +# By default, a task's IP address (as returned by the Marathon API) is used as +# backend server if an IP-per-task configuration can be found; otherwise, the +# name of the host running the task is used. +# The latter behavior can be enforced by enabling this switch. +# +# Optional +# Default: false +# +# forceTaskHostname = false + +# Applications may define readiness checks which are probed by Marathon during +# deployments periodically and the results exposed via the API. Enabling the +# following parameter causes Traefik to filter out tasks whose readiness checks +# have not succeeded. +# Note that the checks are only valid at deployment times. See the Marathon +# guide for details. +# +# Optional +# Default: false +# +# respectReadinessChecks = false +``` + +Labels can be used on containers to override default behaviour: + +- `traefik.backend=foo`: assign the application to `foo` backend +- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. +- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. +- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm +- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions +- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend +- `traefik.backend.healthcheck.path=/health`: set the Traefik health check path [default: no health checks] +- `traefik.backend.healthcheck.interval=5s`: sets a custom health check interval in Go-parseable (`time.ParseDuration`) format [default: 30s] +- `traefik.portIndex=1`: register port by index in the application's ports array. Useful when the application exposes multiple ports. +- `traefik.port=80`: register the explicit application port value. Cannot be used alongside `traefik.portIndex`. +- `traefik.protocol=https`: override the default `http` protocol +- `traefik.weight=10`: assign this weight to the application +- `traefik.enable=false`: disable this application in Træfik +- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). +- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. +- `traefik.frontend.priority=10`: override default frontend priority +- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. +- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively + +If several ports need to be exposed from a container, the services labels can be used + +- `traefik..port=443`: create a service binding with frontend/backend using this port. Overrides `traefik.port`. +- `traefik..portIndex=1`: create a service binding with frontend/backend using this port index. Overrides `traefik.portIndex`. +- `traefik..protocol=https`: assign `https` protocol. Overrides `traefik.protocol`. +- `traefik..weight=10`: assign this service weight. Overrides `traefik.weight`. +- `traefik..frontend.backend=fooBackend`: assign this service frontend to `foobackend`. Default is to assign to the service backend. +- `traefik..frontend.entryPoints=http`: assign this service entrypoints. Overrides `traefik.frontend.entrypoints`. +- `traefik..frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` Sets a Basic Auth for that frontend with the users test:test and test2:test2. +- `traefik..frontend.passHostHeader=true`: Forward client `Host` header to the backend. Overrides `traefik.frontend.passHostHeader`. +- `traefik..frontend.priority=10`: assign the service frontend priority. Overrides `traefik.frontend.priority`. +- `traefik..frontend.rule=Path:/foo`: assign the service frontend rule. Overrides `traefik.frontend.rule`. \ No newline at end of file diff --git a/docs/backends/mesos.md b/docs/backends/mesos.md new file mode 100644 index 000000000..17aa1e7e1 --- /dev/null +++ b/docs/backends/mesos.md @@ -0,0 +1,85 @@ +# Mesos generic backend + +Træfik can be configured to use Mesos as a backend configuration: + + +```toml +################################################################ +# Mesos configuration backend +################################################################ + +# Enable Mesos configuration backend +# +# Optional +# +[mesos] + +# Mesos server endpoint. +# You can also specify multiple endpoint for Mesos: +# endpoint = "192.168.35.40:5050,192.168.35.41:5050,192.168.35.42:5050" +# endpoint = "zk://192.168.35.20:2181,192.168.35.21:2181,192.168.35.22:2181/mesos" +# +# Required +# +endpoint = "http://127.0.0.1:8080" + +# Enable watch Mesos changes +# +# Optional +# +watch = true + +# Default domain used. +# Can be overridden by setting the "traefik.domain" label on an application. +# +# Required +# +domain = "mesos.localhost" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "mesos.tmpl" + +# Expose Mesos apps by default in traefik +# +# Optional +# Default: false +# +# ExposedByDefault = true + +# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config +# +# Optional +# +# [mesos.TLS] +# InsecureSkipVerify = true + +# Zookeeper timeout (in seconds) +# +# Optional +# Default: 30 +# +# ZkDetectionTimeout = 30 + +# Polling interval (in seconds) +# +# Optional +# Default: 30 +# +# RefreshSeconds = 30 + +# IP sources (e.g. host, docker, mesos, rkt) +# +# Optional +# +# IPSources = "host" + +# HTTP Timeout (in seconds) +# +# Optional +# Default: 30 +# +# StateTimeoutSecond = "30" +``` diff --git a/docs/backends/rancher.md b/docs/backends/rancher.md new file mode 100644 index 000000000..8f34eca51 --- /dev/null +++ b/docs/backends/rancher.md @@ -0,0 +1,117 @@ +# Rancher backend + +Træfik can be configured to use Rancher as a backend configuration: + + +```toml +################################################################ +# Rancher configuration backend +################################################################ + +# Enable Rancher configuration backend +# +# Optional +# +[rancher] + +# Default domain used. +# Can be overridden by setting the "traefik.domain" label on an service. +# +# Required +# +domain = "rancher.localhost" + +# Enable watch Rancher changes +# +# Optional +# Default: true +# +Watch = true + +# Polling interval (in seconds) +# +# Optional +# +RefreshSeconds = 15 + +# Expose Rancher services by default in traefik +# +# Optional +# Default: true +# +ExposedByDefault = false + +# Filter services with unhealthy states and inactive states +# +# Optional +# Default: false +# +EnableServiceHealthFilter = true +``` + +```toml +# Enable Rancher metadata service configuration backend instead of the API +# configuration backend +# +# Optional +# Default: false +# +[rancher.metadata] + +# Poll the Rancher metadata service for changes every `rancher.RefreshSeconds` +# NOTE: this is less accurate than the default long polling technique which +# will provide near instantaneous updates to Traefik +# +# Optional +# Default: false +# +IntervalPoll = true + +# Prefix used for accessing the Rancher metadata service +# +# Optional +# Default: "/latest" +# +Prefix = "/2016-07-29" +``` + +```toml +# Enable Rancher API configuration backend +# +# Optional +# Default: true +# +[rancher.api] + +# Endpoint to use when connecting to the Rancher API +# +# Required +Endpoint = "http://rancherserver.example.com/v1" + +# AccessKey to use when connecting to the Rancher API +# +# Required +AccessKey = "XXXXXXXXXXXXXXXXXXXX" + +# SecretKey to use when connecting to the Rancher API +# +# Required +SecretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +``` + +If Traefik needs access to the Rancher API, you need to set the `endpoint`, `accesskey` and `secretkey` parameters. + +To enable traefik to fetch information about the Environment it's deployed in only, you need to create an `Environment API Key`. +This can be found within the API Key advanced options. + +Labels can be used on task containers to override default behaviour: + +- `traefik.protocol=https`: override the default `http` protocol +- `traefik.weight=10`: assign this weight to the container +- `traefik.enable=false`: disable this container in Træfik +- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). +- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. +- `traefik.frontend.priority=10`: override default frontend priority +- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. +- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively + diff --git a/docs/backends/zookeeper.md b/docs/backends/zookeeper.md new file mode 100644 index 000000000..51a6a698c --- /dev/null +++ b/docs/backends/zookeeper.md @@ -0,0 +1,41 @@ +# Zookeeper backend + +Træfik can be configured to use Zookeeper as a backend configuration: + +```toml +################################################################ +# Zookeeper configuration backend +################################################################ + +# Enable Zookeeperconfiguration backend +# +# Optional +# +[zookeeper] + +# Zookeeper server endpoint +# +# Required +# +endpoint = "127.0.0.1:2181" + +# Enable watch Zookeeper changes +# +# Optional +# +watch = true + +# Prefix used for KV store. +# +# Optional +# +prefix = "traefik" + +# Override default configuration template. For advanced users :) +# +# Optional +# +# filename = "zookeeper.tmpl" +``` + +Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. \ No newline at end of file diff --git a/docs/configuration/acme.md b/docs/configuration/acme.md new file mode 100644 index 000000000..41f9c21a9 --- /dev/null +++ b/docs/configuration/acme.md @@ -0,0 +1,125 @@ +## ACME (Let's Encrypt) configuration + +```toml +# Sample entrypoint configuration when using ACME +[entryPoints] + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + +# Enable ACME (Let's Encrypt): automatic SSL +# +# Optional +# +[acme] + +# Email address used for registration +# +# Required +# +email = "test@traefik.io" + +# File or key used for certificates storage. +# WARNING, if you use Traefik in Docker, you have 2 options: +# - create a file on your host and mount it as a volume +# storageFile = "acme.json" +# $ docker run -v "/my/host/acme.json:acme.json" traefik +# - mount the folder containing the file as a volume +# storageFile = "/etc/traefik/acme/acme.json" +# $ docker run -v "/my/host/acme:/etc/traefik/acme" traefik +# +# Required +# +storage = "acme.json" # or "traefik/acme/account" if using KV store + +# Entrypoint to proxy acme challenge/apply certificates to. +# WARNING, must point to an entrypoint on port 443 +# +# Required +# +entryPoint = "https" + +# Use a DNS based acme challenge rather than external HTTPS access, e.g. for a firewalled server +# Select the provider that matches the DNS domain that will host the challenge TXT record, +# and provide environment variables with access keys to enable setting it: +# - cloudflare: CLOUDFLARE_EMAIL, CLOUDFLARE_API_KEY +# - digitalocean: DO_AUTH_TOKEN +# - dnsimple: DNSIMPLE_EMAIL, DNSIMPLE_OAUTH_TOKEN +# - dnsmadeeasy: DNSMADEEASY_API_KEY, DNSMADEEASY_API_SECRET +# - exoscale: EXOSCALE_API_KEY, EXOSCALE_API_SECRET +# - gandi: GANDI_API_KEY +# - linode: LINODE_API_KEY +# - manual: none, but run traefik interactively & turn on acmeLogging to see instructions & press Enter +# - namecheap: NAMECHEAP_API_USER, NAMECHEAP_API_KEY +# - rfc2136: RFC2136_TSIG_KEY, RFC2136_TSIG_SECRET, RFC2136_TSIG_ALGORITHM, RFC2136_NAMESERVER +# - route53: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, or configured user/instance IAM profile +# - dyn: DYN_CUSTOMER_NAME, DYN_USER_NAME, DYN_PASSWORD +# - vultr: VULTR_API_KEY +# - ovh: OVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY +# - pdns: PDNS_API_KEY, PDNS_API_URL +# +# Optional +# +# dnsProvider = "digitalocean" + +# By default, the dnsProvider will verify the TXT DNS challenge record before letting ACME verify +# If delayDontCheckDNS is greater than zero, avoid this & instead just wait so many seconds. +# Useful if internal networks block external DNS queries +# +# Optional +# +# delayDontCheckDNS = 0 + +# If true, display debug log messages from the acme client library +# +# Optional +# +# acmeLogging = true + +# Enable on demand certificate. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate. +# WARNING, TLS handshakes will be slow when requesting a hostname certificate for the first time, this can leads to DoS attacks. +# WARNING, Take note that Let's Encrypt have rate limiting: https://letsencrypt.org/docs/rate-limits +# +# Optional +# +# onDemand = true + +# Enable certificate generation on frontends Host rules. This will request a certificate from Let's Encrypt for each frontend with a Host rule. +# For example, a rule Host:test1.traefik.io,test2.traefik.io will request a certificate with main domain test1.traefik.io and SAN test2.traefik.io. +# +# Optional +# +# OnHostRule = true + +# CA server to use +# Uncomment the line to run on the staging let's encrypt server +# Leave comment to go to prod +# +# Optional +# +# caServer = "https://acme-staging.api.letsencrypt.org/directory" + +# Domains list +# You can provide SANs (alternative domains) to each main domain +# All domains must have A/AAAA records pointing to Traefik +# WARNING, Take note that Let's Encrypt have rate limiting: https://letsencrypt.org/docs/rate-limits +# Each domain & SANs will lead to a certificate request. +# +# [[acme.domains]] +# main = "local1.com" +# sans = ["test1.local1.com", "test2.local1.com"] +# [[acme.domains]] +# main = "local2.com" +# sans = ["test1.local2.com", "test2x.local2.com"] +# [[acme.domains]] +# main = "local3.com" +# [[acme.domains]] +# main = "local4.com" +[[acme.domains]] + main = "local1.com" + sans = ["test1.local1.com", "test2.local1.com"] +[[acme.domains]] + main = "local3.com" +[[acme.domains]] + main = "local4.com" +``` diff --git a/docs/configuration/toml.md b/docs/configuration/toml.md new file mode 100644 index 000000000..af11da7ff --- /dev/null +++ b/docs/configuration/toml.md @@ -0,0 +1,412 @@ + +# Global configuration + +## Main section + +```toml +# traefik.toml +################################################################ +# Global configuration +################################################################ + +# Duration to give active requests a chance to finish before Traefik stops. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). +# If no units are provided, the value is parsed assuming seconds. +# Note: in this time frame no new requests are accepted. +# +# Optional +# Default: "10s" +# +# graceTimeOut = "10s" + +# Enable debug mode +# +# Optional +# Default: false +# +# debug = true + +# Periodically check if a new version has been released +# +# Optional +# Default: true +# +# checkNewVersion = false + +# Traefik logs file +# If not defined, logs to stdout +# +# Optional +# +# traefikLogsFile = "log/traefik.log" + +# Access logs file +# +# Deprecated - see [accessLog] lower down +# Optional +# +# accessLogsFile = "log/access.log" + +# Log level +# +# Optional +# Default: "ERROR" +# Accepted values, in order of severity: "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "PANIC" +# Messages at and above the selected level will be logged. +# +# logLevel = "ERROR" + +# Backends throttle duration: minimum duration in seconds between 2 events from providers +# before applying a new configuration. It avoids unnecessary reloads if multiples events +# are sent in a short amount of time. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "2s" +# +# ProvidersThrottleDuration = "2s" + +# IdleTimeout +# +# Deprecated - see [respondingTimeouts] section. In the case both settings are configured, the deprecated option will +# be overwritten. +# +# IdleTimeout is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. +# This is set to enforce closing of stale client connections. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming seconds. +# +# Optional +# Default: "180s" +# +# IdleTimeout = "360s" + +# Controls the maximum idle (keep-alive) connections to keep per-host. If zero, DefaultMaxIdleConnsPerHost +# from the Go standard library net/http module is used. +# If you encounter 'too many open files' errors, you can either increase this +# value or change the `ulimit`. +# +# Optional +# Default: 200 +# +# MaxIdleConnsPerHost = 200 + +# If set to true invalid SSL certificates are accepted for backends. +# Note: This disables detection of man-in-the-middle attacks so should only be used on secure backend networks. +# Optional +# Default: false +# +# InsecureSkipVerify = true + +# Register Certificates in the RootCA. This certificates will be use for backends calls. +# Note: You can use file path or cert content directly +# Optional +# Default: [] +# +# RootCAs = [ "/mycert.cert" ] + +# Entrypoints to be used by frontends that do not specify any entrypoint. +# Each frontend can specify its own entrypoints. +# +# Optional +# Default: ["http"] +# +# defaultEntryPoints = ["http", "https"] +``` + +### Constraints + +In a micro-service architecture, with a central service discovery, setting constraints limits Træfik scope to a smaller number of routes. + +Træfik filters services according to service attributes/tags set in your configuration backends. + +Supported backends: + +- Docker +- Consul K/V +- BoltDB +- Zookeeper +- Etcd +- Consul Catalog +- Rancher +- Marathon +- Kubernetes (using a provider-specific mechanism based on label selectors) + +Supported filters: + +- `tag` + +```toml +# Constraints definition +# +# Optional +# +# Simple matching constraint +# constraints = ["tag==api"] +# +# Simple mismatching constraint +# constraints = ["tag!=api"] +# +# Globbing +# constraints = ["tag==us-*"] +# +# Backend-specific constraint +# [consulCatalog] +# endpoint = 127.0.0.1:8500 +# constraints = ["tag==api"] +# +# Multiple constraints +# - "tag==" must match with at least one tag +# - "tag!=" must match with none of tags +# constraints = ["tag!=us-*", "tag!=asia-*"] +# [consulCatalog] +# endpoint = 127.0.0.1:8500 +# constraints = ["tag==api", "tag!=v*-beta"] +``` + +## Access log definition + +Access logs are written when `[accessLog]` is defined. +By default it will write to stdout and produce logs in the textual Common Log Format (CLF), extended with additional fields. + +To enable access logs using the default settings just add the `[accessLog]` entry. +```toml +[accessLog] +``` + +To write the logs into a logfile specify the `filePath`. +```toml +[accessLog] + filePath = "/path/to/access.log" +``` + +To write JSON format logs, specify `json` as the format: +```toml +[accessLog] + filePath = "/path/to/access.log" + format = "json" +``` + +## Entrypoints definition + +```toml +# Entrypoints definition +# +# Optional +# Default: +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# +# To redirect an http entrypoint to an https entrypoint (with SNI support): +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# [entryPoints.http.redirect] +# entryPoint = "https" +# [entryPoints.https] +# address = ":443" +# [entryPoints.https.tls] +# [[entryPoints.https.tls.certificates]] +# CertFile = "integration/fixtures/https/snitest.com.cert" +# KeyFile = "integration/fixtures/https/snitest.com.key" +# [[entryPoints.https.tls.certificates]] +# CertFile = "integration/fixtures/https/snitest.org.cert" +# KeyFile = "integration/fixtures/https/snitest.org.key" +# +# To redirect an entrypoint rewriting the URL: +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# [entryPoints.http.redirect] +# regex = "^http://localhost/(.*)" +# replacement = "http://mydomain/$1" +# +# Only accept clients that present a certificate signed by a specified +# Certificate Authority (CA) +# ClientCAFiles can be configured with multiple CA:s in the same file or +# use multiple files containing one or several CA:s. The CA:s has to be in PEM format. +# All clients will be required to present a valid cert. +# The requirement will apply to all server certs in the entrypoint +# In the example below both snitest.com and snitest.org will require client certs +# +# [entryPoints] +# [entryPoints.https] +# address = ":443" +# [entryPoints.https.tls] +# ClientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"] +# [[entryPoints.https.tls.certificates]] +# CertFile = "integration/fixtures/https/snitest.com.cert" +# KeyFile = "integration/fixtures/https/snitest.com.key" +# [[entryPoints.https.tls.certificates]] +# CertFile = "integration/fixtures/https/snitest.org.cert" +# KeyFile = "integration/fixtures/https/snitest.org.key" +# +# To enable basic auth on an entrypoint +# with 2 user/pass: test:test and test2:test2 +# Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones +# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# [entryPoints.http.auth.basic] +# users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] +# usersFile = "/path/to/.htpasswd" +# +# To enable digest auth on an entrypoint +# with 2 user/realm/pass: test:traefik:test and test2:traefik:test2 +# You can use htdigest to generate those ones +# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# [entryPoints.http.auth.basic] +# users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"] +# usersFile = "/path/to/.htdigest" +# +# To specify an https entrypoint with a minimum TLS version, and specifying an array of cipher suites (from crypto/tls): +# [entryPoints] +# [entryPoints.https] +# address = ":443" +# [entryPoints.https.tls] +# MinVersion = "VersionTLS12" +# CipherSuites = ["TLS_RSA_WITH_AES_256_GCM_SHA384"] +# [[entryPoints.https.tls.certificates]] +# CertFile = "integration/fixtures/https/snitest.com.cert" +# KeyFile = "integration/fixtures/https/snitest.com.key" +# [[entryPoints.https.tls.certificates]] +# CertFile = "integration/fixtures/https/snitest.org.cert" +# KeyFile = "integration/fixtures/https/snitest.org.key" + +# To enable compression support using gzip format: +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# compress = true + +# To enable IP whitelisting at the entrypoint level: +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# whiteListSourceRange = ["127.0.0.1/32"] + +# To enable ProxyProtocol support (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt): +# [entryPoints] +# [entryPoints.http] +# address = ":80" +# proxyprotocol = true + +[entryPoints] + [entryPoints.http] + address = ":80" +``` + +## Retry configuration + +```toml +# Enable retry sending request if network error +# +# Optional +# +[retry] + +# Number of attempts +# +# Optional +# Default: (number servers in backend) -1 +# +# attempts = 3 +``` + +## Health check configuration +```toml +# Enable custom health check options. +# +# Optional +# +[healthcheck] + +# Set the default health check interval. Will only be effective if health check +# paths are defined. Given provider-specific support, the value may be +# overridden on a per-backend basis. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming +# seconds. +# +# Optional +# Default: "30s" +# +# interval = "30s" +``` + +## Responding timeouts +``` +# respondingTimeouts are timeouts for incoming requests to the Traefik instance. +# +# Optional +# +[respondingTimeouts] + +# readTimeout is the maximum duration for reading the entire request, including the body. +# If zero, no timeout exists. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming seconds. +# +# Optional +# Default: "0s" +# +# readTimeout = "5s" + +# writeTimeout is the maximum duration before timing out writes of the response. It covers the time from the end of +# the request header read to the end of the response write. +# If zero, no timeout exists. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming seconds. +# +# Optional +# Default: "0s" +# +# writeTimeout = "5s" + +# idleTimeout is the maximum duration an idle (keep-alive) connection will remain idle before closing itself. +# If zero, no timeout exists. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming seconds. +# +# Optional +# Default: "180s" +# +# idleTimeout = "360s" + +``` + +## Forwarding timeouts +``` +# forwardingTimeouts are timeouts for requests forwarded to the backend servers. +# +# Optional +# +[forwardingTimeouts] + +# dialTimeout is the amount of time to wait until a connection to a backend server can be established. +# If zero, no timeout exists. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming seconds. +# +# Optional +# Default: "30s" +# +# dialTimeout = "30s" + +# responseHeaderTimeout is the amount of time to wait for a server's response headers after fully writing the request (including its body, if any). +# If zero, no timeout exists. +# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw +# values (digits). If no units are provided, the value is parsed assuming seconds. +# +# Optional +# Default: "0s" +# +# responseHeaderTimeout = "0s" +``` \ No newline at end of file diff --git a/docs/img/traefik-health.png b/docs/img/traefik-health.png index 608174ac713302eb6afbaa5cbb7f9a82993a9aee..bfcf2799f093dfa54371280dc3fcaf8d9ccafc8f 100644 GIT binary patch literal 102955 zcmZ^K19T=`@^>aSCZ0H%*mg3pZQHgzv2AN6wyh_&%_p|~&Aa>lwYy)R+voJHs^2a3 z>8^9TI$T~>3<35VEC>h)f`quRA_xdLGzbW&1vKOz3gHgO76=F|l!cIxyo8Vtp}eD= zsfD!(2#9!iaEhBc+9AeJclvpB)7_?5HJtdRj3;`s$?=5AZ(@wNJkSVYV$g`Zd@3v$ z)`&0)3h*xwH0D17{T(MXkW*FP$#a4|xtBJ8pe0vz~#moFH-9$I_;_<6u9$ z1)0XidNsKS8N|P_gH8K`KY@G^pT?Gurba?i^B*9%zr6MZ{c(DqGt{=^xA~ddi-VCf z00MIJBW*~(E&+uvtVT|g$tk-O8E8f%Lo}{?I9v^1xWwrk6x>~PeO)J@jt9b%E^8(N z`lE=b&6$ei>opN1VMR7FMz;S|TQ?_31b)aBNZ$#H1LZMvx0W6%K{wcp#0@lc=*J-Q zjonAS-^<)_yq}}DHtgQxqb5I!qkCXAyP`-u8WhS8)PVrBIK-kas5L!^!r`Jx_WNg_ zuY9XZK5WC1WXs`aVUY2Ju-{2u&p&q$-WMpbi@tExk>M(6$B&u5bK9!dUHZBN3%hq) zXuN<}kM7!YWN)!F3xjCtl3X%9$tW#;@qc9i0lSYvQ#}c3^1TBA3-iah0z)B$+4pCf z25IX-P6L(Fhsp}zzWNfNkE2icK18BZ93UMB;V8hz0W0gzBo8wgz-5o34SBu|+k$8t zAiw}R)N90m0PK-_Sa=bdMVsgf7L)ZxI3e6FypV4DLi{cPP zFbZ_&1J@^Jv`EvIhADxZi)anU28{qj1G& zkLuqMwzuS9&f<=Vks3PKmEED+uG$&0cWOa$|EddH9oYJAMHjvB~K6jhTbFU}!%M7&Nqj-ndgAxv6;Jrjy0G)|oIH8YGoTxp>B`&Wq+W9ggk zB8d<2k`k%nU`5!oVoU@Y$<{)MWTkPjaaJR|`=R^IXs{yjh7vFZ-<4wIPbk?bmDu z?Yiy8?o1ta5A%;tVQiyLV_u<(V^UzYP%+SkeN{$t{u+f!gVsUALG∾̳uYnp?wr5 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 literal 53776 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 E09o}Rp8x;= diff --git a/docs/toml.md b/docs/toml.md deleted file mode 100644 index fb55fca88..000000000 --- a/docs/toml.md +++ /dev/null @@ -1,2017 +0,0 @@ - -# Global configuration - -## Main section - -```toml -# traefik.toml -################################################################ -# Global configuration -################################################################ - -# Duration to give active requests a chance to finish before Traefik stops. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits). -# If no units are provided, the value is parsed assuming seconds. -# Note: in this time frame no new requests are accepted. -# -# Optional -# Default: "10s" -# -# graceTimeOut = "10s" - -# Enable debug mode -# -# Optional -# Default: false -# -# debug = true - -# Periodically check if a new version has been released -# -# Optional -# Default: true -# -# checkNewVersion = false - -# Traefik logs file -# If not defined, logs to stdout -# -# Optional -# -# traefikLogsFile = "log/traefik.log" - -# Access logs file -# -# Deprecated - see [accessLog] lower down -# Optional -# -# accessLogsFile = "log/access.log" - -# Log level -# -# Optional -# Default: "ERROR" -# Accepted values, in order of severity: "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "PANIC" -# Messages at and above the selected level will be logged. -# -# logLevel = "ERROR" - -# Backends throttle duration: minimum duration in seconds between 2 events from providers -# before applying a new configuration. It avoids unnecessary reloads if multiples events -# are sent in a short amount of time. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming -# seconds. -# -# Optional -# Default: "2s" -# -# ProvidersThrottleDuration = "2s" - -# IdleTimeout -# -# Deprecated - see [respondingTimeouts] section. In the case both settings are configured, the deprecated option will -# be overwritten. -# -# IdleTimeout is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. -# This is set to enforce closing of stale client connections. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "180s" -# -# IdleTimeout = "360s" - -# Controls the maximum idle (keep-alive) connections to keep per-host. If zero, DefaultMaxIdleConnsPerHost -# from the Go standard library net/http module is used. -# If you encounter 'too many open files' errors, you can either increase this -# value or change the `ulimit`. -# -# Optional -# Default: 200 -# -# MaxIdleConnsPerHost = 200 - -# If set to true invalid SSL certificates are accepted for backends. -# Note: This disables detection of man-in-the-middle attacks so should only be used on secure backend networks. -# Optional -# Default: false -# -# InsecureSkipVerify = true - -# Register Certificates in the RootCA. This certificates will be use for backends calls. -# Note: You can use file path or cert content directly -# Optional -# Default: [] -# -# RootCAs = [ "/mycert.cert" ] - -# Entrypoints to be used by frontends that do not specify any entrypoint. -# Each frontend can specify its own entrypoints. -# -# Optional -# Default: ["http"] -# -# defaultEntryPoints = ["http", "https"] -``` - -### Constraints - -In a micro-service architecture, with a central service discovery, setting constraints limits Træfik scope to a smaller number of routes. - -Træfik filters services according to service attributes/tags set in your configuration backends. - -Supported backends: - -- Docker -- Consul K/V -- BoltDB -- Zookeeper -- Etcd -- Consul Catalog -- Rancher -- Marathon -- Kubernetes (using a provider-specific mechanism based on label selectors) - -Supported filters: - -- `tag` - -```toml -# Constraints definition -# -# Optional -# -# Simple matching constraint -# constraints = ["tag==api"] -# -# Simple mismatching constraint -# constraints = ["tag!=api"] -# -# Globbing -# constraints = ["tag==us-*"] -# -# Backend-specific constraint -# [consulCatalog] -# endpoint = 127.0.0.1:8500 -# constraints = ["tag==api"] -# -# Multiple constraints -# - "tag==" must match with at least one tag -# - "tag!=" must match with none of tags -# constraints = ["tag!=us-*", "tag!=asia-*"] -# [consulCatalog] -# endpoint = 127.0.0.1:8500 -# constraints = ["tag==api", "tag!=v*-beta"] -``` - -## Access log definition - -Access logs are written when `[accessLog]` is defined. -By default it will write to stdout and produce logs in the textual Common Log Format (CLF), extended with additional fields. - -To enable access logs using the default settings just add the `[accessLog]` entry. -```toml -[accessLog] -``` - -To write the logs into a logfile specify the `filePath`. -```toml -[accessLog] - filePath = "/path/to/access.log" -``` - -To write JSON format logs, specify `json` as the format: -```toml -[accessLog] - filePath = "/path/to/access.log" - format = "json" -``` - -## Entrypoints definition - -```toml -# Entrypoints definition -# -# Optional -# Default: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# -# To redirect an http entrypoint to an https entrypoint (with SNI support): -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.redirect] -# entryPoint = "https" -# [entryPoints.https] -# address = ":443" -# [entryPoints.https.tls] -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.com.cert" -# KeyFile = "integration/fixtures/https/snitest.com.key" -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.org.cert" -# KeyFile = "integration/fixtures/https/snitest.org.key" -# -# To redirect an entrypoint rewriting the URL: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.redirect] -# regex = "^http://localhost/(.*)" -# replacement = "http://mydomain/$1" -# -# Only accept clients that present a certificate signed by a specified -# Certificate Authority (CA) -# ClientCAFiles can be configured with multiple CA:s in the same file or -# use multiple files containing one or several CA:s. The CA:s has to be in PEM format. -# All clients will be required to present a valid cert. -# The requirement will apply to all server certs in the entrypoint -# In the example below both snitest.com and snitest.org will require client certs -# -# [entryPoints] -# [entryPoints.https] -# address = ":443" -# [entryPoints.https.tls] -# ClientCAFiles = ["tests/clientca1.crt", "tests/clientca2.crt"] -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.com.cert" -# KeyFile = "integration/fixtures/https/snitest.com.key" -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.org.cert" -# KeyFile = "integration/fixtures/https/snitest.org.key" -# -# To enable basic auth on an entrypoint -# with 2 user/pass: test:test and test2:test2 -# Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones -# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.auth.basic] -# users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] -# usersFile = "/path/to/.htpasswd" -# -# To enable digest auth on an entrypoint -# with 2 user/realm/pass: test:traefik:test and test2:traefik:test2 -# You can use htdigest to generate those ones -# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# [entryPoints.http.auth.basic] -# users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"] -# usersFile = "/path/to/.htdigest" -# -# To specify an https entrypoint with a minimum TLS version, and specifying an array of cipher suites (from crypto/tls): -# [entryPoints] -# [entryPoints.https] -# address = ":443" -# [entryPoints.https.tls] -# MinVersion = "VersionTLS12" -# CipherSuites = ["TLS_RSA_WITH_AES_256_GCM_SHA384"] -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.com.cert" -# KeyFile = "integration/fixtures/https/snitest.com.key" -# [[entryPoints.https.tls.certificates]] -# CertFile = "integration/fixtures/https/snitest.org.cert" -# KeyFile = "integration/fixtures/https/snitest.org.key" - -# To enable compression support using gzip format: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# compress = true - -# To enable IP whitelisting at the entrypoint level: -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# whiteListSourceRange = ["127.0.0.1/32"] - -# To enable ProxyProtocol support (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt): -# [entryPoints] -# [entryPoints.http] -# address = ":80" -# proxyprotocol = true - -[entryPoints] - [entryPoints.http] - address = ":80" -``` - -## Retry configuration - -```toml -# Enable retry sending request if network error -# -# Optional -# -[retry] - -# Number of attempts -# -# Optional -# Default: (number servers in backend) -1 -# -# attempts = 3 -``` - -## Health check configuration -```toml -# Enable custom health check options. -# -# Optional -# -[healthcheck] - -# Set the default health check interval. Will only be effective if health check -# paths are defined. Given provider-specific support, the value may be -# overridden on a per-backend basis. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming -# seconds. -# -# Optional -# Default: "30s" -# -# interval = "30s" -``` - -## Responding timeouts -``` -# respondingTimeouts are timeouts for incoming requests to the Traefik instance. -# -# Optional -# -[respondingTimeouts] - -# readTimeout is the maximum duration for reading the entire request, including the body. -# If zero, no timeout exists. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "0s" -# -# readTimeout = "5s" - -# writeTimeout is the maximum duration before timing out writes of the response. It covers the time from the end of -# the request header read to the end of the response write. -# If zero, no timeout exists. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "0s" -# -# writeTimeout = "5s" - -# idleTimeout is the maximum duration an idle (keep-alive) connection will remain idle before closing itself. -# If zero, no timeout exists. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "180s" -# -# idleTimeout = "360s" - -``` - -## Forwarding timeouts -``` -# forwardingTimeouts are timeouts for requests forwarded to the backend servers. -# -# Optional -# -[forwardingTimeouts] - -# dialTimeout is the amount of time to wait until a connection to a backend server can be established. -# If zero, no timeout exists. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "30s" -# -# dialTimeout = "30s" - -# responseHeaderTimeout is the amount of time to wait for a server's response headers after fully writing the request (including its body, if any). -# If zero, no timeout exists. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming seconds. -# -# Optional -# Default: "0s" -# -# responseHeaderTimeout = "0s" -``` - -## ACME (Let's Encrypt) configuration - -```toml -# Sample entrypoint configuration when using ACME -[entryPoints] - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - -# Enable ACME (Let's Encrypt): automatic SSL -# -# Optional -# -[acme] - -# Email address used for registration -# -# Required -# -email = "test@traefik.io" - -# File or key used for certificates storage. -# WARNING, if you use Traefik in Docker, you have 2 options: -# - create a file on your host and mount it as a volume -# storageFile = "acme.json" -# $ docker run -v "/my/host/acme.json:acme.json" traefik -# - mount the folder containing the file as a volume -# storageFile = "/etc/traefik/acme/acme.json" -# $ docker run -v "/my/host/acme:/etc/traefik/acme" traefik -# -# Required -# -storage = "acme.json" # or "traefik/acme/account" if using KV store - -# Entrypoint to proxy acme challenge/apply certificates to. -# WARNING, must point to an entrypoint on port 443 -# -# Required -# -entryPoint = "https" - -# Use a DNS based acme challenge rather than external HTTPS access, e.g. for a firewalled server -# Select the provider that matches the DNS domain that will host the challenge TXT record, -# and provide environment variables with access keys to enable setting it: -# - cloudflare: CLOUDFLARE_EMAIL, CLOUDFLARE_API_KEY -# - digitalocean: DO_AUTH_TOKEN -# - dnsimple: DNSIMPLE_EMAIL, DNSIMPLE_OAUTH_TOKEN -# - dnsmadeeasy: DNSMADEEASY_API_KEY, DNSMADEEASY_API_SECRET -# - exoscale: EXOSCALE_API_KEY, EXOSCALE_API_SECRET -# - gandi: GANDI_API_KEY -# - linode: LINODE_API_KEY -# - manual: none, but run traefik interactively & turn on acmeLogging to see instructions & press Enter -# - namecheap: NAMECHEAP_API_USER, NAMECHEAP_API_KEY -# - rfc2136: RFC2136_TSIG_KEY, RFC2136_TSIG_SECRET, RFC2136_TSIG_ALGORITHM, RFC2136_NAMESERVER -# - route53: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, or configured user/instance IAM profile -# - dyn: DYN_CUSTOMER_NAME, DYN_USER_NAME, DYN_PASSWORD -# - vultr: VULTR_API_KEY -# - ovh: OVH_ENDPOINT, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY -# - pdns: PDNS_API_KEY, PDNS_API_URL -# -# Optional -# -# dnsProvider = "digitalocean" - -# By default, the dnsProvider will verify the TXT DNS challenge record before letting ACME verify -# If delayDontCheckDNS is greater than zero, avoid this & instead just wait so many seconds. -# Useful if internal networks block external DNS queries -# -# Optional -# -# delayDontCheckDNS = 0 - -# If true, display debug log messages from the acme client library -# -# Optional -# -# acmeLogging = true - -# Enable on demand certificate. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate. -# WARNING, TLS handshakes will be slow when requesting a hostname certificate for the first time, this can leads to DoS attacks. -# WARNING, Take note that Let's Encrypt have rate limiting: https://letsencrypt.org/docs/rate-limits -# -# Optional -# -# onDemand = true - -# Enable certificate generation on frontends Host rules. This will request a certificate from Let's Encrypt for each frontend with a Host rule. -# For example, a rule Host:test1.traefik.io,test2.traefik.io will request a certificate with main domain test1.traefik.io and SAN test2.traefik.io. -# -# Optional -# -# OnHostRule = true - -# CA server to use -# Uncomment the line to run on the staging let's encrypt server -# Leave comment to go to prod -# -# Optional -# -# caServer = "https://acme-staging.api.letsencrypt.org/directory" - -# Domains list -# You can provide SANs (alternative domains) to each main domain -# All domains must have A/AAAA records pointing to Traefik -# WARNING, Take note that Let's Encrypt have rate limiting: https://letsencrypt.org/docs/rate-limits -# Each domain & SANs will lead to a certificate request. -# -# [[acme.domains]] -# main = "local1.com" -# sans = ["test1.local1.com", "test2.local1.com"] -# [[acme.domains]] -# main = "local2.com" -# sans = ["test1.local2.com", "test2x.local2.com"] -# [[acme.domains]] -# main = "local3.com" -# [[acme.domains]] -# main = "local4.com" -[[acme.domains]] - main = "local1.com" - sans = ["test1.local1.com", "test2.local1.com"] -[[acme.domains]] - main = "local3.com" -[[acme.domains]] - main = "local4.com" -``` - -# Configuration backends - -## File backend - -Like any other reverse proxy, Træfik can be configured with a file. You have three choices: - -- simply add your configuration at the end of the global configuration file `traefik.toml`: - -```toml -# traefik.toml -logLevel = "DEBUG" -defaultEntryPoints = ["http", "https"] -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.http.redirect] - entryPoint = "https" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - CertFile = "integration/fixtures/https/snitest.com.cert" - KeyFile = "integration/fixtures/https/snitest.com.key" - [[entryPoints.https.tls.certificates]] - CertFile = "integration/fixtures/https/snitest.org.cert" - KeyFile = "integration/fixtures/https/snitest.org.key" - -[file] - -# rules -[backends] - [backends.backend1] - [backends.backend1.circuitbreaker] - expression = "NetworkErrorRatio() > 0.5" - [backends.backend1.servers.server1] - url = "http://172.17.0.2:80" - weight = 10 - [backends.backend1.servers.server2] - url = "http://172.17.0.3:80" - weight = 1 - [backends.backend2] - [backends.backend2.maxconn] - amount = 10 - extractorfunc = "request.host" - [backends.backend2.LoadBalancer] - method = "drr" - [backends.backend2.servers.server1] - url = "http://172.17.0.4:80" - weight = 1 - [backends.backend2.servers.server2] - url = "http://172.17.0.5:80" - weight = 2 - -[frontends] - [frontends.frontend1] - backend = "backend2" - [frontends.frontend1.routes.test_1] - rule = "Host:test.localhost" - [frontends.frontend2] - backend = "backend1" - passHostHeader = true - priority = 10 - - # restrict access to this frontend to the specified list of IPv4/IPv6 CIDR Nets - # an unset or empty list allows all Source-IPs to access - # if one of the Net-Specifications are invalid, the whole list is invalid - # and allows all Source-IPs to access. - whitelistSourceRange = ["10.42.0.0/16", "152.89.1.33/32", "afed:be44::/16"] - - entrypoints = ["https"] # overrides defaultEntryPoints - [frontends.frontend2.routes.test_1] - rule = "Host:{subdomain:[a-z]+}.localhost" - [frontends.frontend3] - entrypoints = ["http", "https"] # overrides defaultEntryPoints - backend = "backend2" - rule = "Path:/test" -``` - -- or put your rules in a separate file, for example `rules.toml`: - -```toml -# traefik.toml -logLevel = "DEBUG" -[entryPoints] - [entryPoints.http] - address = ":80" - [entryPoints.http.redirect] - entryPoint = "https" - [entryPoints.https] - address = ":443" - [entryPoints.https.tls] - [[entryPoints.https.tls.certificates]] - CertFile = "integration/fixtures/https/snitest.com.cert" - KeyFile = "integration/fixtures/https/snitest.com.key" - [[entryPoints.https.tls.certificates]] - CertFile = "integration/fixtures/https/snitest.org.cert" - KeyFile = "integration/fixtures/https/snitest.org.key" - -[file] -filename = "rules.toml" -``` - -```toml -# rules.toml -[backends] - [backends.backend1] - [backends.backend1.circuitbreaker] - expression = "NetworkErrorRatio() > 0.5" - [backends.backend1.servers.server1] - url = "http://172.17.0.2:80" - weight = 10 - [backends.backend1.servers.server2] - url = "http://172.17.0.3:80" - weight = 1 - [backends.backend2] - [backends.backend2.maxconn] - amount = 10 - extractorfunc = "request.host" - [backends.backend2.LoadBalancer] - method = "drr" - [backends.backend2.servers.server1] - url = "http://172.17.0.4:80" - weight = 1 - [backends.backend2.servers.server2] - url = "http://172.17.0.5:80" - weight = 2 - -[frontends] - [frontends.frontend1] - backend = "backend2" - [frontends.frontend1.routes.test_1] - rule = "Host:test.localhost" - [frontends.frontend2] - backend = "backend1" - passHostHeader = true - priority = 10 - entrypoints = ["https"] # overrides defaultEntryPoints - [frontends.frontend2.routes.test_1] - rule = "Host:{subdomain:[a-z]+}.localhost" - [frontends.frontend3] - entrypoints = ["http", "https"] # overrides defaultEntryPoints - backend = "backend2" - rule = "Path:/test" -``` - -- or you could have multiple .toml files in a directory: - -```toml -[file] -directory = "/path/to/config/" -``` - -If you want Træfik to watch file changes automatically, just add: - -```toml -[file] -watch = true -``` - -The configuration files can be also templates written using functions provided by [go template](https://golang.org/pkg/text/template/) as well as functions provided by the [sprig library](http://masterminds.github.io/sprig/), like this: - -```tmpl -[backends] - [backends.backend1] - url = "http://firstserver" - [backends.backend2] - url = "http://secondserver" - -{{$frontends := dict "frontend1" "backend1" "frontend2" "backend2"}} -[frontends] -{{range $frontend, $backend := $frontends}} - [frontends.{{$frontend}}] - backend = "{{$backend}}" -{{end}} -``` - - -## API backend - -Træfik can be configured using a RESTful api. -To enable it: - -```toml -[web] -address = ":8080" - -# Set the root path for webui and API -# -# Optional -# -# path = "/mypath" -# -# SSL certificate and key used -# -# Optional -# -# CertFile = "traefik.crt" -# KeyFile = "traefik.key" -# -# Set REST API to read-only mode -# -# Optional -# ReadOnly = false -# -# To enable more detailed statistics -# [web.statistics] -# RecentErrors = 10 -# -# To enable Traefik to export internal metrics to Prometheus -# [web.metrics.prometheus] -# Buckets=[0.1,0.3,1.2,5.0] -# -# To enable Traefik to export internal metics to DataDog -# [web.metrics.datadog] -# Address = localhost:8125 -# PushInterval = "10s" -# -# To enable Traefik to export internal metics to StatsD -# [web.metrics.statsd] -# Address = localhost:8125 -# PushInterval = "10s" -# -# To enable basic auth on the webui -# with 2 user/pass: test:test and test2:test2 -# Passwords can be encoded in MD5, SHA1 and BCrypt: you can use htpasswd to generate those ones -# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence -# [web.auth.basic] -# users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"] -# usersFile = "/path/to/.htpasswd" -# To enable digest auth on the webui -# with 2 user/realm/pass: test:traefik:test and test2:traefik:test2 -# You can use htdigest to generate those ones -# Users can be specified directly in the toml file, or indirectly by referencing an external file; if both are provided, the two are merged, with external file contents having precedence -# [web.auth.digest] -# users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"] -# usersFile = "/path/to/.htdigest" -``` - -- `/`: provides a simple HTML frontend of Træfik - -![Web UI Providers](img/web.frontend.png) -![Web UI Health](img/traefik-health.png) - -- `/ping`: A simple endpoint to check for Træfik process liveness. Supports HTTP `GET` and `HEAD` requests. - -```shell -$ curl -sv "http://localhost:8080/ping" -* Trying ::1... -* Connected to localhost (::1) port 8080 (#0) -> GET /ping HTTP/1.1 -> Host: localhost:8080 -> User-Agent: curl/7.43.0 -> Accept: */* -> -< HTTP/1.1 200 OK -< Date: Thu, 25 Aug 2016 01:35:36 GMT -< Content-Length: 2 -< Content-Type: text/plain; charset=utf-8 -< -* Connection #0 to host localhost left intact -OK -``` - -- `/health`: `GET` json metrics - -```shell -$ curl -s "http://localhost:8080/health" | jq . -{ - // Træfik PID - "pid": 2458, - // Træfik server uptime (formated time) - "uptime": "39m6.885931127s", - // Træfik server uptime in seconds - "uptime_sec": 2346.885931127, - // current server date - "time": "2015-10-07 18:32:24.362238909 +0200 CEST", - // current server date in seconds - "unixtime": 1444235544, - // count HTTP response status code in realtime - "status_code_count": { - "502": 1 - }, - // count HTTP response status code since Træfik started - "total_status_code_count": { - "200": 7, - "404": 21, - "502": 13 - }, - // count HTTP response - "count": 1, - // count HTTP response - "total_count": 41, - // sum of all response time (formated time) - "total_response_time": "35.456865605s", - // sum of all response time in seconds - "total_response_time_sec": 35.456865605, - // average response time (formated time) - "average_response_time": "864.8016ms", - // average response time in seconds - "average_response_time_sec": 0.8648016000000001, - - // request statistics [requires --web.statistics to be set] - // ten most recent requests with 4xx and 5xx status codes - "recent_errors": [ - { - // status code - "status_code": 500, - // description of status code - "status": "Internal Server Error", - // request HTTP method - "method": "GET", - // request hostname - "host": "localhost", - // request path - "path": "/path", - // RFC 3339 formatted date/time - "time": "2016-10-21T16:59:15.418495872-07:00" - } - ] -} -``` - -- `/api`: `GET` configuration for all providers - -```shell -$ curl -s "http://localhost:8080/api" | jq . -{ - "file": { - "frontends": { - "frontend2": { - "routes": { - "test_2": { - "rule": "Path:/test" - } - }, - "backend": "backend1" - }, - "frontend1": { - "routes": { - "test_1": { - "rule": "Host:test.localhost" - } - }, - "backend": "backend2" - } - }, - "backends": { - "backend2": { - "loadBalancer": { - "method": "drr" - }, - "servers": { - "server2": { - "weight": 2, - "URL": "http://172.17.0.5:80" - }, - "server1": { - "weight": 1, - "url": "http://172.17.0.4:80" - } - } - }, - "backend1": { - "loadBalancer": { - "method": "wrr" - }, - "circuitBreaker": { - "expression": "NetworkErrorRatio() > 0.5" - }, - "servers": { - "server2": { - "weight": 1, - "url": "http://172.17.0.3:80" - }, - "server1": { - "weight": 10, - "url": "http://172.17.0.2:80" - } - } - } - } - } -} -``` - -- `/api/providers`: `GET` providers -- `/api/providers/{provider}`: `GET` or `PUT` provider -- `/api/providers/{provider}/backends`: `GET` backends -- `/api/providers/{provider}/backends/{backend}`: `GET` a backend -- `/api/providers/{provider}/backends/{backend}/servers`: `GET` servers in a backend -- `/api/providers/{provider}/backends/{backend}/servers/{server}`: `GET` a server in a backend -- `/api/providers/{provider}/frontends`: `GET` frontends -- `/api/providers/{provider}/frontends/{frontend}`: `GET` a frontend -- `/api/providers/{provider}/frontends/{frontend}/routes`: `GET` routes in a frontend -- `/api/providers/{provider}/frontends/{frontend}/routes/{route}`: `GET` a route in a frontend - -- `/metrics`: You can enable Traefik to export internal metrics to different monitoring systems (Only Prometheus is supported at the moment). - -```bash -$ traefik --web.metrics.prometheus --web.metrics.prometheus.buckets="0.1,0.3,1.2,5.0" -``` - -## Docker backend - -Træfik can be configured to use Docker as a backend configuration: - -```toml -################################################################ -# Docker configuration backend -################################################################ - -# Enable Docker configuration backend -# -# Optional -# -[docker] - -# Docker server endpoint. Can be a tcp or a unix socket endpoint. -# -# Required -# -endpoint = "unix:///var/run/docker.sock" - -# Default domain used. -# Can be overridden by setting the "traefik.domain" label on a container. -# -# Required -# -domain = "docker.localhost" - -# Enable watch docker changes -# -# Optional -# -watch = true - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "docker.tmpl" - -# Expose containers by default in traefik -# If set to false, containers that don't have `traefik.enable=true` will be ignored -# -# Optional -# Default: true -# -exposedbydefault = true - -# Use the IP address from the binded port instead of the inner network one. For specific use-case :) - -# -# Optional -# Default: false -# -usebindportip = true -# Use Swarm Mode services as data provider -# -# Optional -# Default: false -# -swarmmode = false - - -# Enable docker TLS connection -# -# [docker.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/docker.crt" -# key = "/etc/ssl/docker.key" -# insecureskipverify = true -``` - -### Labels can be used on containers to override default behaviour - -| Label | Description | -|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. | -| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. | -| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. | -| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm | -| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions | -| `traefik.backend.loadbalancer.swarm=true` | Use Swarm's inbuilt load balancer (only relevant under Swarm Mode). | -| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend | -| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. | -| `traefik.protocol=https` | Override the default `http` protocol | -| `traefik.weight=10` | Assign this weight to the container | -| `traefik.enable=false` | Disable this container in Træfik | -| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. | -| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. | -| `traefik.frontend.priority=10` | Override default frontend priority | -| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` | -| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` | -| `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. | -| `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with docker inspect ) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. | - -### Services labels can be used for overriding default behaviour - -| Label | Description | -|---------------------------------------------------|--------------------------------------------------------------------------------------------------| -| `traefik..port=PORT` | Overrides `traefik.port`. If several ports need to be exposed, the service labels could be used. | -| `traefik..protocol` | Overrides `traefik.protocol`. | -| `traefik..weight` | Assign this service weight. Overrides `traefik.weight`. | -| `traefik..frontend.backend=BACKEND` | Assign this service frontend to `BACKEND`. Default is to assign to the service backend. | -| `traefik..frontend.entryPoints` | Overrides `traefik.frontend.entrypoints` | -| `traefik..frontend.auth.basic` | Sets a Basic Auth for that frontend | -| `traefik..frontend.passHostHeader` | Overrides `traefik.frontend.passHostHeader`. | -| `traefik..frontend.priority` | Overrides `traefik.frontend.priority`. | -| `traefik..frontend.rule` | Overrides `traefik.frontend.rule`. | - -NB: when running inside a container, Træfik will need network access through `docker network connect ` - -## Marathon backend - -Træfik can be configured to use Marathon as a backend configuration: - - -```toml -################################################################ -# Mesos/Marathon configuration backend -################################################################ - -# Enable Marathon configuration backend -# -# Optional -# -[marathon] - -# Marathon server endpoint. -# You can also specify multiple endpoint for Marathon: -# endpoint := "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" -# -# Required -# -endpoint = "http://127.0.0.1:8080" - -# Enable watch Marathon changes -# -# Optional -# -watch = true - -# Default domain used. -# -# Required -# -domain = "marathon.localhost" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "marathon.tmpl" - -# Expose Marathon apps by default in traefik -# -# Optional -# Default: true -# -# exposedByDefault = true - -# Convert Marathon groups to subdomains -# Default behavior: /foo/bar/myapp => foo-bar-myapp.{defaultDomain} -# with groupsAsSubDomains enabled: /foo/bar/myapp => myapp.bar.foo.{defaultDomain} -# -# Optional -# Default: false -# -# groupsAsSubDomains = true - -# Enable compatibility with marathon-lb labels -# -# Optional -# Default: false -# -# marathonLBCompatibility = true - -# Enable Marathon basic authentication -# -# Optional -# -# [marathon.basic] -# httpBasicAuthUser = "foo" -# httpBasicPassword = "bar" - -# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config -# -# Optional -# -# [marathon.TLS] -# CA = "/etc/ssl/ca.crt" -# Cert = "/etc/ssl/marathon.cert" -# Key = "/etc/ssl/marathon.key" -# InsecureSkipVerify = true - -# DCOSToken for DCOS environment, This will override the Authorization header -# -# Optional -# -# dcosToken = "xxxxxx" - -# Override DialerTimeout -# Amount of time to allow the Marathon provider to wait to open a TCP connection -# to a Marathon master. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming -# seconds. -# -# Optional -# Default: "60s" -# dialerTimeout = "60s" - -# Set the TCP Keep Alive interval for the Marathon HTTP Client. -# Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw -# values (digits). If no units are provided, the value is parsed assuming -# seconds. -# -# Optional -# Default: "10s" -# -# keepAlive = "10s" - -# By default, a task's IP address (as returned by the Marathon API) is used as -# backend server if an IP-per-task configuration can be found; otherwise, the -# name of the host running the task is used. -# The latter behavior can be enforced by enabling this switch. -# -# Optional -# Default: false -# -# forceTaskHostname = false - -# Applications may define readiness checks which are probed by Marathon during -# deployments periodically and the results exposed via the API. Enabling the -# following parameter causes Traefik to filter out tasks whose readiness checks -# have not succeeded. -# Note that the checks are only valid at deployment times. See the Marathon -# guide for details. -# -# Optional -# Default: false -# -# respectReadinessChecks = false -``` - -Labels can be used on containers to override default behaviour: - -- `traefik.backend=foo`: assign the application to `foo` backend -- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. -- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. -- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm -- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions -- `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5`: create a [circuit breaker](/basics/#backends) to be used against the backend -- `traefik.backend.healthcheck.path=/health`: set the Traefik health check path [default: no health checks] -- `traefik.backend.healthcheck.interval=5s`: sets a custom health check interval in Go-parseable (`time.ParseDuration`) format [default: 30s] -- `traefik.portIndex=1`: register port by index in the application's ports array. Useful when the application exposes multiple ports. -- `traefik.port=80`: register the explicit application port value. Cannot be used alongside `traefik.portIndex`. -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.weight=10`: assign this weight to the application -- `traefik.enable=false`: disable this application in Træfik -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. -- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively - -If several ports need to be exposed from a container, the services labels can be used - -- `traefik..port=443`: create a service binding with frontend/backend using this port. Overrides `traefik.port`. -- `traefik..portIndex=1`: create a service binding with frontend/backend using this port index. Overrides `traefik.portIndex`. -- `traefik..protocol=https`: assign `https` protocol. Overrides `traefik.protocol`. -- `traefik..weight=10`: assign this service weight. Overrides `traefik.weight`. -- `traefik..frontend.backend=fooBackend`: assign this service frontend to `foobackend`. Default is to assign to the service backend. -- `traefik..frontend.entryPoints=http`: assign this service entrypoints. Overrides `traefik.frontend.entrypoints`. -- `traefik..frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0` Sets a Basic Auth for that frontend with the users test:test and test2:test2. -- `traefik..frontend.passHostHeader=true`: Forward client `Host` header to the backend. Overrides `traefik.frontend.passHostHeader`. -- `traefik..frontend.priority=10`: assign the service frontend priority. Overrides `traefik.frontend.priority`. -- `traefik..frontend.rule=Path:/foo`: assign the service frontend rule. Overrides `traefik.frontend.rule`. - -## Mesos generic backend - -Træfik can be configured to use Mesos as a backend configuration: - - -```toml -################################################################ -# Mesos configuration backend -################################################################ - -# Enable Mesos configuration backend -# -# Optional -# -[mesos] - -# Mesos server endpoint. -# You can also specify multiple endpoint for Mesos: -# endpoint = "192.168.35.40:5050,192.168.35.41:5050,192.168.35.42:5050" -# endpoint = "zk://192.168.35.20:2181,192.168.35.21:2181,192.168.35.22:2181/mesos" -# -# Required -# -endpoint = "http://127.0.0.1:8080" - -# Enable watch Mesos changes -# -# Optional -# -watch = true - -# Default domain used. -# Can be overridden by setting the "traefik.domain" label on an application. -# -# Required -# -domain = "mesos.localhost" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "mesos.tmpl" - -# Expose Mesos apps by default in traefik -# -# Optional -# Default: false -# -# ExposedByDefault = true - -# TLS client configuration. https://golang.org/pkg/crypto/tls/#Config -# -# Optional -# -# [mesos.TLS] -# InsecureSkipVerify = true - -# Zookeeper timeout (in seconds) -# -# Optional -# Default: 30 -# -# ZkDetectionTimeout = 30 - -# Polling interval (in seconds) -# -# Optional -# Default: 30 -# -# RefreshSeconds = 30 - -# IP sources (e.g. host, docker, mesos, rkt) -# -# Optional -# -# IPSources = "host" - -# HTTP Timeout (in seconds) -# -# Optional -# Default: 30 -# -# StateTimeoutSecond = "30" -``` - -## Kubernetes Ingress backend - - -Træfik can be configured to use Kubernetes Ingress as a backend configuration: - -```toml -################################################################ -# Kubernetes Ingress configuration backend -################################################################ -# Enable Kubernetes Ingress configuration backend -# -# Optional -# -[kubernetes] - -# Kubernetes server endpoint -# -# When deployed as a replication controller in Kubernetes, Traefik will use -# the environment variables KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT -# to construct the endpoint. -# Secure token will be found in /var/run/secrets/kubernetes.io/serviceaccount/token -# and SSL CA cert in /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -# -# The endpoint may be given to override the environment variable values. -# -# When the environment variables are not found, Traefik will try to connect to -# the Kubernetes API server with an external-cluster client. In this case, the -# endpoint is required. Specifically, it may be set to the URL used by -# `kubectl proxy` to connect to a Kubernetes cluster from localhost. -# -# Optional for in-cluster configuration, required otherwise -# Default: empty -# -# endpoint = "http://localhost:8080" - -# Bearer token used for the Kubernetes client configuration. -# -# Optional -# Default: empty -# -# token = "my token" - -# Path to the certificate authority file used for the Kubernetes client -# configuration. -# -# Optional -# Default: empty -# -# certAuthFilePath = "/my/ca.crt" - -# Array of namespaces to watch. -# -# Optional -# Default: all namespaces (empty array). -# -# namespaces = ["default", "production"] - -# Ingress label selector to identify Ingress objects that should be processed. -# See https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors for details. -# -# Optional -# Default: empty (process all Ingresses) -# -# labelselector = "A and not B" -``` - -Annotations can be used on containers to override default behaviour for the whole Ingress resource: - -- `traefik.frontend.rule.type: PathPrefixStrip`: override the default frontend rule type (Default: `PathPrefix`). -- `traefik.frontend.priority: 3`: override the default frontend rule priority (Default: `len(Path)`). - -Annotations can be used on the Kubernetes service to override default behaviour: - -- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm -- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions - -You can find here an example [ingress](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml) and [replication controller](https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik.yaml). - -Additionally, an annotation can be used on Kubernetes services to set the [circuit breaker expression](https://docs.traefik.io/basics/#backends) for a backend. - -- `traefik.backend.circuitbreaker: `: set the circuit breaker expression for the backend (Default: nil). - -As known from nginx when used as Kubernetes Ingress Controller, a List of IP-Ranges which are allowed to access can be configured by using an ingress annotation: - -- `ingress.kubernetes.io/whitelist-source-range: "1.2.3.0/24, fe80::/16"` - -An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. - - -### Authentication - -Is possible to add additional authentication annotations in the Ingress rule. -The source of the authentication is a secret that contains usernames and passwords inside the the key auth. - -- `ingress.kubernetes.io/auth-type`: `basic` -- `ingress.kubernetes.io/auth-secret`: contains the usernames and passwords with access to the paths defined in the Ingress Rule. - -The secret must be created in the same namespace as the Ingress rule. - -Limitations: - -- Basic authentication only. -- Realm not configurable; only `traefik` default. -- Secret must contain only single file. - -## Consul backend - -Træfik can be configured to use Consul as a backend configuration: - -```toml -################################################################ -# Consul KV configuration backend -################################################################ - -# Enable Consul KV configuration backend -# -# Optional -# -[consul] - -# Consul server endpoint -# -# Required -# -endpoint = "127.0.0.1:8500" - -# Enable watch Consul changes -# -# Optional -# -watch = true - -# Prefix used for KV store. -# -# Optional -# -prefix = "traefik" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "consul.tmpl" - -# Enable consul TLS connection -# -# Optional -# -# [consul.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/consul.crt" -# key = "/etc/ssl/consul.key" -# insecureskipverify = true -``` - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. - -## Consul catalog backend - -Træfik can be configured to use service discovery catalog of Consul as a backend configuration: - -```toml -################################################################ -# Consul Catalog configuration backend -################################################################ - -# Enable Consul Catalog configuration backend -# -# Optional -# -[consulCatalog] - -# Consul server endpoint -# -# Required -# -endpoint = "127.0.0.1:8500" - -# Default domain used. -# -# Optional -# -domain = "consul.localhost" - -# Expose Consul catalog services by default in traefik -# -# Optional -# Default: true -# -exposedByDefault = false - -# Prefix for Consul catalog tags -# -# Optional -# -prefix = "traefik" - -# Default frontEnd Rule for Consul services -# The format is a Go Template with ".ServiceName", ".Domain" and ".Attributes" available -# "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available -# "getAttribute(...)" function uses prefixed tag names based on "prefix" value -# -# Optional -# -frontEndRule = "Host:{{.ServiceName}}.{{Domain}}" -``` - -This backend will create routes matching on hostname based on the service name -used in consul. - -Additional settings can be defined using Consul Catalog tags: - -- `traefik.enable=false`: disable this container in Træfik -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.backend.weight=10`: assign this weight to the container -- `traefik.backend.circuitbreaker=NetworkErrorRatio() > 0.5` -- `traefik.backend.loadbalancer=drr`: override the default load balancing mode -- `traefik.backend.maxconn.amount=10`: set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. -- `traefik.backend.maxconn.extractorfunc=client.ip`: set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{{.ServiceName}}.{{.Domain}}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. - -## Etcd backend - -Træfik can be configured to use Etcd as a backend configuration: - -```toml -################################################################ -# Etcd configuration backend -################################################################ - -# Enable Etcd configuration backend -# -# Optional -# -[etcd] - -# Etcd server endpoint -# -# Required -# -endpoint = "127.0.0.1:2379" - -# Enable watch Etcd changes -# -# Optional -# -watch = true - -# Prefix used for KV store. -# -# Optional -# -prefix = "/traefik" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "etcd.tmpl" - -# Use etcd user/pass authentication -# -# Optional -# -# username = foo -# password = bar - -# Enable etcd TLS connection -# -# Optional -# -# [etcd.tls] -# ca = "/etc/ssl/ca.crt" -# cert = "/etc/ssl/etcd.crt" -# key = "/etc/ssl/etcd.key" -# insecureskipverify = true -``` - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. - - -## Zookeeper backend - -Træfik can be configured to use Zookeeper as a backend configuration: - -```toml -################################################################ -# Zookeeper configuration backend -################################################################ - -# Enable Zookeeperconfiguration backend -# -# Optional -# -[zookeeper] - -# Zookeeper server endpoint -# -# Required -# -endpoint = "127.0.0.1:2181" - -# Enable watch Zookeeper changes -# -# Optional -# -watch = true - -# Prefix used for KV store. -# -# Optional -# -prefix = "traefik" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "zookeeper.tmpl" -``` - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. - -## BoltDB backend - -Træfik can be configured to use BoltDB as a backend configuration: - -```toml -################################################################ -# BoltDB configuration backend -################################################################ - -# Enable BoltDB configuration backend -# -# Optional -# -[boltdb] - -# BoltDB file -# -# Required -# -endpoint = "/my.db" - -# Enable watch BoltDB changes -# -# Optional -# -watch = true - -# Prefix used for KV store. -# -# Optional -# -prefix = "/traefik" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "boltdb.tmpl" -``` - -## Eureka backend - -Træfik can be configured to use Eureka as a backend configuration: - - -```toml -################################################################ -# Eureka configuration backend -################################################################ - -# Enable Eureka configuration backend -# -# Optional -# -[eureka] - -# Eureka server endpoint. -# endpoint := "http://my.eureka.server/eureka" -# -# Required -# -endpoint = "http://my.eureka.server/eureka" - -# Override default configuration time between refresh -# -# Optional -# default 30s -delay = "1m" - -# Override default configuration template. For advanced users :) -# -# Optional -# -# filename = "eureka.tmpl" -``` - -Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure. - - -## ECS backend - -Træfik can be configured to use Amazon ECS as a backend configuration: - - -```toml -################################################################ -# ECS configuration backend -################################################################ - -# Enable ECS configuration backend -# -# Optional -# -[ecs] - -# ECS Cluster Name -# -# Deprecated - Please use Clusters -# -# Cluster = "default" - -# ECS Clusters Name -# -# Optional -# Default: ["default"] -# -Clusters = ["default"] - -# Enable watch ECS changes -# -# Optional -# Default: true -# -Watch = true - -# Enable auto discover ECS clusters -# -# Optional -# Default: false -# -AutoDiscoverClusters = false - -# Polling interval (in seconds) -# -# Optional -# Default: 15 -# -RefreshSeconds = 15 - -# Expose ECS services by default in traefik -# -# Optional -# Default: true -# -ExposedByDefault = false - -# Region to use when connecting to AWS -# -# Optional -# -# Region = "us-east-1" - -# AccessKeyID to use when connecting to AWS -# -# Optional -# -# AccessKeyID = "abc" - -# SecretAccessKey to use when connecting to AWS -# -# Optional -# -# SecretAccessKey = "123" - -``` - -Labels can be used on task containers to override default behaviour: - -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.weight=10`: assign this weight to the container -- `traefik.enable=false`: disable this container in Træfik -- `traefik.backend.loadbalancer.method=drr`: override the default `wrr` load balancer algorithm -- `traefik.backend.loadbalancer.sticky=true`: enable backend sticky sessions -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. - -If `AccessKeyID`/`SecretAccessKey` is not given credentials will be resolved in the following order: - -- From environment variables; `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`. -- Shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to `default` and `~/.aws/credentials`. -- EC2 instance role or ECS task role - -Træfik needs the following policy to read ECS information: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Traefik ECS read access", - "Effect": "Allow", - "Action": [ - "ecs:ListClusters", - "ecs:DescribeClusters", - "ecs:ListTasks", - "ecs:DescribeTasks", - "ecs:DescribeContainerInstances", - "ecs:DescribeTaskDefinition", - "ec2:DescribeInstances" - ], - "Resource": [ - "*" - ] - } - ] -} -``` - -# Rancher backend - -Træfik can be configured to use Rancher as a backend configuration: - - -```toml -################################################################ -# Rancher configuration backend -################################################################ - -# Enable Rancher configuration backend -# -# Optional -# -[rancher] - -# Default domain used. -# Can be overridden by setting the "traefik.domain" label on an service. -# -# Required -# -domain = "rancher.localhost" - -# Enable watch Rancher changes -# -# Optional -# Default: true -# -Watch = true - -# Polling interval (in seconds) -# -# Optional -# -RefreshSeconds = 15 - -# Expose Rancher services by default in traefik -# -# Optional -# Default: true -# -ExposedByDefault = false - -# Filter services with unhealthy states and inactive states -# -# Optional -# Default: false -# -EnableServiceHealthFilter = true -``` - -```toml -# Enable Rancher metadata service configuration backend instead of the API -# configuration backend -# -# Optional -# Default: false -# -[rancher.metadata] - -# Poll the Rancher metadata service for changes every `rancher.RefreshSeconds` -# NOTE: this is less accurate than the default long polling technique which -# will provide near instantaneous updates to Traefik -# -# Optional -# Default: false -# -IntervalPoll = true - -# Prefix used for accessing the Rancher metadata service -# -# Optional -# Default: "/latest" -# -Prefix = "/2016-07-29" -``` - -```toml -# Enable Rancher API configuration backend -# -# Optional -# Default: true -# -[rancher.api] - -# Endpoint to use when connecting to the Rancher API -# -# Required -Endpoint = "http://rancherserver.example.com/v1" - -# AccessKey to use when connecting to the Rancher API -# -# Required -AccessKey = "XXXXXXXXXXXXXXXXXXXX" - -# SecretKey to use when connecting to the Rancher API -# -# Required -SecretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -``` - -If Traefik needs access to the Rancher API, you need to set the `endpoint`, `accesskey` and `secretkey` parameters. - -To enable traefik to fetch information about the Environment it's deployed in only, you need to create an `Environment API Key`. -This can be found within the API Key advanced options. - -Labels can be used on task containers to override default behaviour: - -- `traefik.protocol=https`: override the default `http` protocol -- `traefik.weight=10`: assign this weight to the container -- `traefik.enable=false`: disable this container in Træfik -- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). -- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend. -- `traefik.frontend.priority=10`: override default frontend priority -- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. -- `traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0`: Sets basic authentication for that frontend with the usernames and passwords test:test and test2:test2, respectively - - -## DynamoDB backend - -Træfik can be configured to use Amazon DynamoDB as a backend configuration: - - -```toml -################################################################ -# DynamoDB configuration backend -################################################################ - -# Enable DynamoDB configuration backend -# -# Optional -# -[dynamodb] - -# DyanmoDB Table Name -# -# Optional -# -TableName = "traefik" - -# Enable watch DynamoDB changes -# -# Optional -# -Watch = true - -# Polling interval (in seconds) -# -# Optional -# -RefreshSeconds = 15 - -# Region to use when connecting to AWS -# -# Required -# -# Region = "us-west-1" - -# AccessKeyID to use when connecting to AWS -# -# Optional -# -# AccessKeyID = "abc" - -# SecretAccessKey to use when connecting to AWS -# -# Optional -# -# SecretAccessKey = "123" - -# Endpoint of local dynamodb instance for testing -# -# Optional -# -# Endpoint = "http://localhost:8080" - -``` - -Items in the `dynamodb` table must have three attributes: - -- `id` : string - - The id is the primary key. -- `name` : string - - The name is used as the name of the frontend or backend. -- `frontend` or `backend` : map - - This attribute's structure matches exactly the structure of a Frontend or Backend type in traefik. See `types/types.go` for details. The presence or absence of this attribute determines its type. So an item should never have both a `frontend` and a `backend` attribute. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index ddf118f0b..766ec38a0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,7 +45,23 @@ extra_css: pages: - Getting Started: index.md - Basics: basics.md - - traefik.toml: toml.md + - Configration: + - 'traefik.toml': 'configuration/toml.md' + - 'Let''s Encrypt': 'configuration/acme.md' + - Backends: + - 'API backend': 'backends/api.md' + - 'BoltDB backend': 'backends/boltdb.md' + - 'Consul backend': 'backends/consul.md' + - 'Docker backend': 'backends/docker.md' + - 'DynamoDB backend': 'backends/dynamodb.md' + - 'ECS backend': 'backends/ecs.md' + - 'Etcd backend': 'backends/etcd.md' + - 'Eureka backend': 'backends/eureka.md' + - 'File backend': 'backends/file.md' + - 'Kubernetes Ingress backend': 'backends/kubernetes.md' + - 'Marathon backend': 'backends/marathon.md' + - 'Rancher backend': 'backends/rancher.md' + - 'Zookeeper backend': 'backends/zookeeper.md' - User Guide: - 'Configuration examples': 'user-guide/examples.md' - 'Swarm cluster': 'user-guide/swarm.md'