2016-07-11 15:32:28 +00:00
# Key-value store configuration
Both [static global configuration ](/user-guide/kv-config/#static-configuration-in-key-value-store ) and [dynamic ](/user-guide/kv-config/#dynamic-configuration-in-key-value-store ) configuration can be sorted in a Key-value store.
2017-03-31 04:29:03 +00:00
This section explains how to launch Træfik using a configuration loaded from a Key-value store.
2016-07-11 15:32:28 +00:00
2017-03-31 04:29:03 +00:00
Træfik supports several Key-value stores:
2016-07-11 15:32:28 +00:00
- [Consul ](https://consul.io )
- [etcd ](https://coreos.com/etcd/ )
2017-06-08 19:04:50 +00:00
- [ZooKeeper ](https://zookeeper.apache.org/ )
2016-07-11 15:32:28 +00:00
- [boltdb ](https://github.com/boltdb/bolt )
2017-08-26 10:12:44 +00:00
## Static configuration in Key-value store
2016-07-11 15:32:28 +00:00
2017-06-08 19:04:50 +00:00
We will see the steps to set it up with an easy example.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
We could do the same with any other Key-value Store.
### docker-compose file for Consul
2016-07-11 15:32:28 +00:00
2017-10-02 12:58:04 +00:00
The Træfik global configuration will be retrieved from a [Consul ](https://consul.io ) store.
2016-07-11 15:32:28 +00:00
2017-06-08 19:04:50 +00:00
First we have to launch Consul in a container.
2017-09-11 17:10:04 +00:00
2017-06-08 19:04:50 +00:00
The [docker-compose file ](https://docs.docker.com/compose/compose-file/ ) allows us to launch Consul and four instances of the trivial app [emilevauge/whoamI ](https://github.com/emilevauge/whoamI ) :
2016-07-11 15:32:28 +00:00
2017-04-30 18:17:57 +00:00
```yaml
2016-07-11 15:32:28 +00:00
consul:
image: progrium/consul
command: -server -bootstrap -log-level debug -ui-dir /ui
ports:
- "8400:8400"
- "8500:8500"
- "8600:53/udp"
expose:
- "8300"
- "8301"
- "8301/udp"
- "8302"
2017-09-07 10:02:03 +00:00
- "8302/udp"
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami1:
image: emilevauge/whoami
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami2:
image: emilevauge/whoami
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami3:
image: emilevauge/whoami
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
whoami4:
image: emilevauge/whoami
```
2017-09-11 17:10:04 +00:00
### Upload the configuration in the Key-value store
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
We should now fill the store with the Træfik global configuration, as we do with a [TOML file configuration ](/toml ).
2016-07-20 09:48:39 +00:00
To do that, we can send the Key-value pairs via [curl commands ](https://www.consul.io/intro/getting-started/kv.html ) or via the [Web UI ](https://www.consul.io/intro/getting-started/ui.html ).
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
Fortunately, Træfik allows automation of this process using the `storeconfig` subcommand.
2017-03-31 04:29:03 +00:00
Please refer to the [store Træfik configuration ](/user-guide/kv-config/#store-configuration-in-key-value-store ) section to get documentation on it.
2016-07-20 09:48:39 +00:00
Here is the toml configuration we would like to store in the Key-value Store :
2016-07-11 15:32:28 +00:00
```toml
logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
2017-11-09 11:16:03 +00:00
certFile = "integration/fixtures/https/snitest.com.cert"
keyFile = "integration/fixtures/https/snitest.com.key"
2016-07-11 15:32:28 +00:00
[[entryPoints.https.tls.certificates]]
2017-11-09 11:16:03 +00:00
certFile = """-----BEGIN CERTIFICATE-----
2016-07-11 15:32:28 +00:00
< cert file content >
-----END CERTIFICATE-----"""
2017-11-09 11:16:03 +00:00
keyFile = """-----BEGIN CERTIFICATE-----
2016-07-11 15:32:28 +00:00
< key file content >
-----END CERTIFICATE-----"""
[consul]
endpoint = "127.0.0.1:8500"
watch = true
prefix = "traefik"
2017-06-08 19:04:50 +00:00
2016-07-11 15:32:28 +00:00
[web]
address = ":8081"
```
2017-06-08 19:04:50 +00:00
And there, the same global configuration in the Key-value Store (using `prefix = "traefik"` ):
2016-07-11 15:32:28 +00:00
| Key | Value |
|-----------------------------------------------------------|---------------------------------------------------------------|
| `/traefik/loglevel` | `DEBUG` |
| `/traefik/defaultentrypoints/0` | `http` |
| `/traefik/defaultentrypoints/1` | `https` |
| `/traefik/entrypoints/http/address` | `:80` |
| `/traefik/entrypoints/https/address` | `:443` |
| `/traefik/entrypoints/https/tls/certificates/0/certfile` | `integration/fixtures/https/snitest.com.cert` |
| `/traefik/entrypoints/https/tls/certificates/0/keyfile` | `integration/fixtures/https/snitest.com.key` |
| `/traefik/entrypoints/https/tls/certificates/1/certfile` | `--BEGIN CERTIFICATE--<cert file content>--END CERTIFICATE--` |
| `/traefik/entrypoints/https/tls/certificates/1/keyfile` | `--BEGIN CERTIFICATE--<key file content>--END CERTIFICATE--` |
| `/traefik/consul/endpoint` | `127.0.0.1:8500` |
| `/traefik/consul/watch` | `true` |
| `/traefik/consul/prefix` | `traefik` |
| `/traefik/web/address` | `:8081` |
2017-04-30 18:17:57 +00:00
In case you are setting key values manually:
2017-09-05 13:58:03 +00:00
2017-04-30 18:17:57 +00:00
- Remember to specify the indexes (`0`,`1`, `2` , ... ) under prefixes `/traefik/defaultentrypoints/` and `/traefik/entrypoints/https/tls/certificates/` in order to match the global configuration structure.
- Be careful to give the correct IP address and port on the key `/traefik/consul/endpoint` .
2016-07-11 15:32:28 +00:00
Note that we can either give path to certificate file or directly the file content itself.
2017-09-11 17:10:04 +00:00
### Launch Træfik
2016-07-11 15:32:28 +00:00
2017-03-31 04:29:03 +00:00
We will now launch Træfik in a container.
2017-09-11 17:10:04 +00:00
2017-03-31 04:29:03 +00:00
We use CLI flags to setup the connection between Træfik and Consul.
2016-07-11 15:32:28 +00:00
All the rest of the global configuration is stored in Consul.
2016-07-20 09:48:39 +00:00
Here is the [docker-compose file ](https://docs.docker.com/compose/compose-file/ ) :
2016-07-11 15:32:28 +00:00
2017-04-30 18:17:57 +00:00
```yaml
2016-07-11 15:32:28 +00:00
traefik:
image: traefik
command: --consul --consul.endpoint=127.0.0.1:8500
ports:
- "80:80"
- "8080:8080"
```
2017-08-28 12:33:07 +00:00
!!! warning
Be careful to give the correct IP address and port in the flag `--consul.endpoint` .
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
### Consul ACL Token support
2017-06-08 19:04:50 +00:00
2017-09-11 17:10:04 +00:00
To specify a Consul ACL token for Traefik, we have to set a System Environment variable named `CONSUL_HTTP_TOKEN` prior to starting Traefik.
This variable must be initialized with the ACL token value.
2017-06-08 19:04:50 +00:00
If Traefik is launched into a Docker container, the variable `CONSUL_HTTP_TOKEN` can be initialized with the `-e` Docker option : `-e "CONSUL_HTTP_TOKEN=[consul-acl-token-value]"`
2017-11-14 15:48:03 +00:00
If a Consul ACL is used to restrict Træfik read/write access, one of the following configurations is needed.
- HCL format :
```
key "traefik" {
policy = "write"
},
session "" {
policy = "write"
}
```
- JSON format :
```json
{
"key": {
"traefik": {
"policy": "write"
}
},
"session": {
"": {
"policy": "write"
}
}
}
```
2017-09-11 17:10:04 +00:00
### TLS support
2016-07-11 15:32:28 +00:00
2017-07-18 15:22:08 +00:00
To connect to a Consul endpoint using SSL, simply specify `https://` in the `consul.endpoint` property
- `--consul.endpoint=https://[consul-host]:[consul-ssl-port]`
2017-09-11 17:10:04 +00:00
### TLS support with client certificates
2017-07-18 15:22:08 +00:00
So far, only [Consul ](https://consul.io ) and [etcd ](https://coreos.com/etcd/ ) support TLS connections with client certificates.
2017-09-11 17:10:04 +00:00
2016-07-11 15:32:28 +00:00
To set it up, we should enable [consul security ](https://www.consul.io/docs/internals/security.html ) (or [etcd security ](https://coreos.com/etcd/docs/latest/security.html )).
2017-03-31 04:29:03 +00:00
Then, we have to provide CA, Cert and Key to Træfik using `consul` flags :
2016-07-11 15:32:28 +00:00
- `--consul.tls`
- `--consul.tls.ca=path/to/the/file`
- `--consul.tls.cert=path/to/the/file`
2017-06-08 19:04:50 +00:00
- `--consul.tls.key=path/to/the/file`
2016-07-11 15:32:28 +00:00
Or etcd flags :
- `--etcd.tls`
- `--etcd.tls.ca=path/to/the/file`
- `--etcd.tls.cert=path/to/the/file`
- `--etcd.tls.key=path/to/the/file`
2017-09-11 17:10:04 +00:00
!! note
We can either give directly directly the file content itself (instead of the path to certificate) in a TOML file configuration.
2016-07-11 15:32:28 +00:00
Remember the command `traefik --help` to display the updated list of flags.
2017-09-11 17:10:04 +00:00
## Dynamic configuration in Key-value store
2017-06-08 19:04:50 +00:00
2017-03-31 04:29:03 +00:00
Following our example, we will provide backends/frontends rules to Træfik.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
This section is independent of the way Træfik got its static configuration.
It means that the static configuration can either come from the same Key-value store or from any other sources.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
### Key-value storage structure
2017-06-08 19:04:50 +00:00
2016-07-20 09:48:39 +00:00
Here is the toml configuration we would like to store in the store :
2016-07-11 15:32:28 +00:00
```toml
[file]
# rules
[backends]
[backends.backend1]
[backends.backend1.circuitbreaker]
2017-09-05 13:58:03 +00:00
expression = "NetworkErrorRatio() > 0.5"
2016-07-11 15:32:28 +00:00
[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.backend1.maxconn]
2017-09-05 13:58:03 +00:00
amount = 10
extractorfunc = "request.host"
2016-07-11 15:32:28 +00:00
[backends.backend2.LoadBalancer]
2017-09-05 13:58:03 +00:00
method = "drr"
2016-07-11 15:32:28 +00:00
[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"
2017-09-05 13:58:03 +00:00
rule = "Path:/test"
2016-07-11 15:32:28 +00:00
```
2017-06-08 19:04:50 +00:00
And there, the same dynamic configuration in a KV Store (using `prefix = "traefik"` ):
2016-07-11 15:32:28 +00:00
- backend 1
| Key | Value |
|--------------------------------------------------------|-----------------------------|
| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` |
| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik/backends/backend1/servers/server1/weight` | `10` |
| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
| `/traefik/backends/backend1/servers/server2/weight` | `1` |
2016-06-20 23:00:52 +00:00
| `/traefik/backends/backend1/servers/server2/tags` | `api,helloworld` |
2016-07-11 15:32:28 +00:00
- backend 2
| Key | Value |
|-----------------------------------------------------|------------------------|
| `/traefik/backends/backend2/maxconn/amount` | `10` |
| `/traefik/backends/backend2/maxconn/extractorfunc` | `request.host` |
| `/traefik/backends/backend2/loadbalancer/method` | `drr` |
| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` |
| `/traefik/backends/backend2/servers/server1/weight` | `1` |
| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
| `/traefik/backends/backend2/servers/server2/weight` | `2` |
2016-06-20 23:00:52 +00:00
| `/traefik/backends/backend2/servers/server2/tags` | `web` |
2016-07-11 15:32:28 +00:00
- frontend 1
| Key | Value |
|---------------------------------------------------|-----------------------|
| `/traefik/frontends/frontend1/backend` | `backend2` |
| `/traefik/frontends/frontend1/routes/test_1/rule` | `Host:test.localhost` |
- frontend 2
| Key | Value |
|----------------------------------------------------|--------------------|
| `/traefik/frontends/frontend2/backend` | `backend1` |
| `/traefik/frontends/frontend2/passHostHeader` | `true` |
| `/traefik/frontends/frontend2/priority` | `10` |
| `/traefik/frontends/frontend2/entrypoints` | `http,https` |
| `/traefik/frontends/frontend2/routes/test_2/rule` | `PathPrefix:/test` |
2017-09-11 17:10:04 +00:00
### Atomic configuration changes
2016-07-11 15:32:28 +00:00
2017-06-08 19:04:50 +00:00
Træfik can watch the backends/frontends configuration changes and generate its configuration automatically.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
!!! note
Only backends/frontends rules are dynamic, the rest of the Træfik configuration stay static.
2016-07-11 15:32:28 +00:00
2017-09-11 17:10:04 +00:00
The [Etcd ](https://github.com/coreos/etcd/issues/860 ) and [Consul ](https://github.com/hashicorp/consul/issues/886 ) backends do not support updating multiple keys atomically.
As a result, it may be possible for Træfik to read an intermediate configuration state despite judicious use of the `--providersThrottleDuration` flag.
2017-09-05 13:58:03 +00:00
To solve this problem, Træfik supports a special key called `/traefik/alias` .
If set, Træfik use the value as an alternative key prefix.
2016-07-11 15:32:28 +00:00
2017-03-31 04:29:03 +00:00
Given the key structure below, Træfik will use the `http://172.17.0.2:80` as its only backend (frontend keys have been omitted for brevity).
2016-07-11 15:32:28 +00:00
| Key | Value |
|-------------------------------------------------------------------------|-----------------------------|
| `/traefik/alias` | `/traefik_configurations/1` |
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
2017-09-05 13:58:03 +00:00
When an atomic configuration change is required, you may write a new configuration at an alternative prefix.
2017-09-11 17:10:04 +00:00
2017-09-05 13:58:03 +00:00
Here, although the `/traefik_configurations/2/...` keys have been set, the old configuration is still active because the `/traefik/alias` key still points to `/traefik_configurations/1` :
2016-07-11 15:32:28 +00:00
| Key | Value |
|-------------------------------------------------------------------------|-----------------------------|
| `/traefik/alias` | `/traefik_configurations/1` |
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
2017-09-05 13:58:03 +00:00
Once the `/traefik/alias` key is updated, the new `/traefik_configurations/2` configuration becomes active atomically.
2017-09-11 17:10:04 +00:00
2017-09-05 13:58:03 +00:00
Here, we have a 50% balance between the `http://172.17.0.3:80` and the `http://172.17.0.4:80` hosts while no traffic is sent to the `172.17.0.2:80` host:
2016-07-11 15:32:28 +00:00
| Key | Value |
|-------------------------------------------------------------------------|-----------------------------|
| `/traefik/alias` | `/traefik_configurations/2` |
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.3:80` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.4:80` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
2017-09-11 17:10:04 +00:00
!!! note
Træfik *will not watch for key changes in the `/traefik_configurations` prefix* . It will only watch for changes in the `/traefik/alias` .
Further, if the `/traefik/alias` key is set, all other configuration with `/traefik/backends` or `/traefik/frontends` prefix are ignored.
## Store configuration in Key-value store
2016-07-20 09:48:39 +00:00
2017-09-11 17:10:04 +00:00
!!! note
Don't forget to [setup the connection between Træfik and Key-value store ](/user-guide/kv-config/#launch-trfk ).
2016-07-20 09:48:39 +00:00
2017-03-31 04:29:03 +00:00
The static Træfik configuration in a key-value store can be automatically created and updated, using the [`storeconfig` subcommand ](/basics/#commands ).
2016-07-20 09:48:39 +00:00
```bash
2017-09-05 13:58:03 +00:00
traefik storeconfig [flags] ...
2016-07-20 09:48:39 +00:00
```
This command is here only to automate the [process which upload the configuration into the Key-value store ](/user-guide/kv-config/#upload-the-configuration-in-the-key-value-store ).
2017-09-11 17:10:04 +00:00
Træfik will not start but the [static configuration ](/basics/#static-trfk-configuration ) will be uploaded into the Key-value store.
2016-09-29 11:49:12 +00:00
If you configured ACME (Let's Encrypt), your registration account and your certificates will also be uploaded.
2017-09-11 17:10:04 +00:00
To upload your ACME certificates to the KV store, get your Traefik TOML file and add the new `storage` option in the `acme` section:
2016-09-29 11:49:12 +00:00
2017-04-30 18:17:57 +00:00
```toml
2016-09-29 11:49:12 +00:00
[acme]
email = "test@traefik.io"
storage = "traefik/acme/account" # the key where to store your certificates in the KV store
storageFile = "acme.json" # your old certificates store
```
Call `traefik storeconfig` to upload your config in the KV store.
Then remove the line `storageFile = "acme.json"` from your TOML config file.
2016-07-20 09:48:39 +00:00
2017-04-30 18:17:57 +00:00
That's it!
2016-07-20 09:48:39 +00:00
2017-09-01 17:44:03 +00:00
![](https://i.giphy.com/ujUdrdpX7Ok5W.gif)