diff --git a/docs/content/reference/install-configuration/configuration-options.md b/docs/content/reference/install-configuration/configuration-options.md
index cd418ec7b..596c69283 100644
--- a/docs/content/reference/install-configuration/configuration-options.md
+++ b/docs/content/reference/install-configuration/configuration-options.md
@@ -273,6 +273,10 @@ THIS FILE MUST NOT BE EDITED BY HAND
| providers.docker.endpoint | Docker server endpoint. Can be a TCP or a Unix socket endpoint. | unix:///var/run/docker.sock |
| providers.docker.exposedbydefault | Expose containers by default. | true |
| providers.docker.httpclienttimeout | Client timeout for HTTP connections. | 0 |
+| providers.docker.labelmap | Label shorthands. | |
+| providers.docker.labelmap[0].from | Shorthand label. | |
+| providers.docker.labelmap[0].to | Full label with templates. | |
+| providers.docker.labelmap[0].value | Optional override; used instead of user input if set. | |
| providers.docker.network | Default Docker network used. | |
| providers.docker.password | Password for Basic HTTP authentication. | |
| providers.docker.tls.ca | TLS CA | |
@@ -422,6 +426,10 @@ THIS FILE MUST NOT BE EDITED BY HAND
| providers.swarm.endpoint | Docker server endpoint. Can be a TCP or a Unix socket endpoint. | unix:///var/run/docker.sock |
| providers.swarm.exposedbydefault | Expose containers by default. | true |
| providers.swarm.httpclienttimeout | Client timeout for HTTP connections. | 0 |
+| providers.swarm.labelmap | Label shorthands. | |
+| providers.swarm.labelmap[0].from | Shorthand label. | |
+| providers.swarm.labelmap[0].to | Full label with templates. | |
+| providers.swarm.labelmap[0].value | Optional override; used instead of user input if set. | |
| providers.swarm.network | Default Docker network used. | |
| providers.swarm.password | Password for Basic HTTP authentication. | |
| providers.swarm.refreshseconds | Polling interval for swarm mode. | 15 |
diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md
index 8a0f0b6ba..b06e80721 100644
--- a/docs/content/reference/static-configuration/cli-ref.md
+++ b/docs/content/reference/static-configuration/cli-ref.md
@@ -798,6 +798,18 @@ Expose containers by default. (Default: ```true```)
`--providers.docker.httpclienttimeout`:
Client timeout for HTTP connections. (Default: ```0```)
+`--providers.docker.labelmap`:
+Label shorthands.
+
+`--providers.docker.labelmap[n].from`:
+Shorthand label.
+
+`--providers.docker.labelmap[n].to`:
+Full label with templates.
+
+`--providers.docker.labelmap[n].value`:
+Optional override; used instead of user input if set.
+
`--providers.docker.network`:
Default Docker network used.
@@ -1245,6 +1257,18 @@ Expose containers by default. (Default: ```true```)
`--providers.swarm.httpclienttimeout`:
Client timeout for HTTP connections. (Default: ```0```)
+`--providers.swarm.labelmap`:
+Label shorthands.
+
+`--providers.swarm.labelmap[n].from`:
+Shorthand label.
+
+`--providers.swarm.labelmap[n].to`:
+Full label with templates.
+
+`--providers.swarm.labelmap[n].value`:
+Optional override; used instead of user input if set.
+
`--providers.swarm.network`:
Default Docker network used.
diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md
index f3aed7b39..65c009454 100644
--- a/docs/content/reference/static-configuration/env-ref.md
+++ b/docs/content/reference/static-configuration/env-ref.md
@@ -798,6 +798,18 @@ Expose containers by default. (Default: ```true```)
`TRAEFIK_PROVIDERS_DOCKER_HTTPCLIENTTIMEOUT`:
Client timeout for HTTP connections. (Default: ```0```)
+`TRAEFIK_PROVIDERS_DOCKER_LABELMAP`:
+Label shorthands.
+
+`TRAEFIK_PROVIDERS_DOCKER_LABELMAP_n_FROM`:
+Shorthand label.
+
+`TRAEFIK_PROVIDERS_DOCKER_LABELMAP_n_TO`:
+Full label with templates.
+
+`TRAEFIK_PROVIDERS_DOCKER_LABELMAP_n_VALUE`:
+Optional override; used instead of user input if set.
+
`TRAEFIK_PROVIDERS_DOCKER_NETWORK`:
Default Docker network used.
@@ -1245,6 +1257,18 @@ Expose containers by default. (Default: ```true```)
`TRAEFIK_PROVIDERS_SWARM_HTTPCLIENTTIMEOUT`:
Client timeout for HTTP connections. (Default: ```0```)
+`TRAEFIK_PROVIDERS_SWARM_LABELMAP`:
+Label shorthands.
+
+`TRAEFIK_PROVIDERS_SWARM_LABELMAP_n_FROM`:
+Shorthand label.
+
+`TRAEFIK_PROVIDERS_SWARM_LABELMAP_n_TO`:
+Full label with templates.
+
+`TRAEFIK_PROVIDERS_SWARM_LABELMAP_n_VALUE`:
+Optional override; used instead of user input if set.
+
`TRAEFIK_PROVIDERS_SWARM_NETWORK`:
Default Docker network used.
diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml
index 63c01b352..7d22522e1 100644
--- a/docs/content/reference/static-configuration/file.toml
+++ b/docs/content/reference/static-configuration/file.toml
@@ -99,6 +99,16 @@
password = "foobar"
endpoint = "foobar"
httpClientTimeout = "42s"
+
+ [[providers.docker.labelMap]]
+ from = "foobar"
+ to = "foobar"
+ value = "foobar"
+
+ [[providers.docker.labelMap]]
+ from = "foobar"
+ to = "foobar"
+ value = "foobar"
[providers.docker.tls]
ca = "foobar"
cert = "foobar"
@@ -117,6 +127,16 @@
endpoint = "foobar"
httpClientTimeout = "42s"
refreshSeconds = "42s"
+
+ [[providers.swarm.labelMap]]
+ from = "foobar"
+ to = "foobar"
+ value = "foobar"
+
+ [[providers.swarm.labelMap]]
+ from = "foobar"
+ to = "foobar"
+ value = "foobar"
[providers.swarm.tls]
ca = "foobar"
cert = "foobar"
diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml
index 5021f0032..64aae401b 100644
--- a/docs/content/reference/static-configuration/file.yaml
+++ b/docs/content/reference/static-configuration/file.yaml
@@ -110,6 +110,13 @@ providers:
useBindPortIP: true
watch: true
defaultRule: foobar
+ labelMap:
+ - from: foobar
+ to: foobar
+ value: foobar
+ - from: foobar
+ to: foobar
+ value: foobar
username: foobar
password: foobar
endpoint: foobar
@@ -127,6 +134,13 @@ providers:
useBindPortIP: true
watch: true
defaultRule: foobar
+ labelMap:
+ - from: foobar
+ to: foobar
+ value: foobar
+ - from: foobar
+ to: foobar
+ value: foobar
username: foobar
password: foobar
endpoint: foobar
diff --git a/pkg/provider/configuration.go b/pkg/provider/configuration.go
index 2872ed7e3..be18de7ce 100644
--- a/pkg/provider/configuration.go
+++ b/pkg/provider/configuration.go
@@ -396,8 +396,8 @@ func AddStore(configuration *dynamic.TLSConfiguration, storeName string, store t
return reflect.DeepEqual(configuration.Stores[storeName], store)
}
-// MakeDefaultRuleTemplate creates the default rule template.
-func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*template.Template, error) {
+// MakeAnyTemplate creates a template with any name
+func MakeAnyTemplate(name string, value string, funcMap template.FuncMap) (*template.Template, error) {
defaultFuncMap := sprig.TxtFuncMap()
defaultFuncMap["normalize"] = Normalize
@@ -405,7 +405,12 @@ func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*tem
defaultFuncMap[k] = fn
}
- return template.New("defaultRule").Funcs(defaultFuncMap).Parse(defaultRule)
+ return template.New(name).Funcs(defaultFuncMap).Parse(value)
+}
+
+// MakeDefaultRuleTemplate creates the default rule template.
+func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*template.Template, error) {
+ return MakeAnyTemplate("defaultRule", defaultRule, funcMap)
}
// BuildTCPRouterConfiguration builds a router configuration.
diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go
index 713586295..0b322715a 100644
--- a/pkg/provider/docker/config.go
+++ b/pkg/provider/docker/config.go
@@ -1,6 +1,7 @@
package docker
import (
+ "bytes"
"context"
"errors"
"fmt"
@@ -28,15 +29,50 @@ func NewDynConfBuilder(configuration Shared, apiClient client.APIClient, swarm b
return &DynConfBuilder{Shared: configuration, apiClient: apiClient, swarm: swarm}
}
+func (p *DynConfBuilder) applyLabels(container *dockerData, model interface{}) {
+ for _, item := range p.LabelMap {
+ value, ok := container.Labels[item.From]
+ if !ok { // label doesn't exist
+ continue
+ }
+
+ writer := &bytes.Buffer{}
+ if err := item.toTpl.Execute(writer, model); err != nil {
+ continue // should never happen?
+ }
+
+ to := writer.String()
+ if item.Value != nil {
+ container.Labels[to] = *item.Value
+ } else {
+ container.Labels[to] = value
+ }
+ }
+}
+
func (p *DynConfBuilder) build(ctx context.Context, containersInspected []dockerData) *dynamic.Configuration {
configurations := make(map[string]*dynamic.Configuration)
for _, container := range containersInspected {
+ serviceName := getServiceName(container)
+
+ model := struct {
+ Name string
+ ContainerName string
+ Labels *map[string]string
+ }{
+ Name: serviceName,
+ ContainerName: strings.TrimPrefix(container.Name, "/"),
+ Labels: &container.Labels,
+ }
+
containerName := getServiceName(container) + "-" + container.ID
logger := log.Ctx(ctx).With().Str("container", containerName).Logger()
ctxContainer := logger.WithContext(ctx)
+ p.applyLabels(&container, model)
+
if !p.keepContainer(ctxContainer, container) {
continue
}
@@ -83,18 +119,6 @@ func (p *DynConfBuilder) build(ctx context.Context, containersInspected []docker
continue
}
- serviceName := getServiceName(container)
-
- model := struct {
- Name string
- ContainerName string
- Labels map[string]string
- }{
- Name: serviceName,
- ContainerName: strings.TrimPrefix(container.Name, "/"),
- Labels: container.Labels,
- }
-
provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model)
configurations[containerName] = confFromLabel
diff --git a/pkg/provider/docker/pdocker.go b/pkg/provider/docker/pdocker.go
index 0720746a3..5e88be51b 100644
--- a/pkg/provider/docker/pdocker.go
+++ b/pkg/provider/docker/pdocker.go
@@ -48,8 +48,15 @@ func (p *Provider) Init() error {
if err != nil {
return fmt.Errorf("error while parsing default rule: %w", err)
}
-
p.defaultRuleTpl = defaultRuleTpl
+
+ for _, item := range p.LabelMap {
+ toTpl, err := provider.MakeAnyTemplate(item.From, item.To, nil)
+ if err != nil {
+ return fmt.Errorf("error while parsing label %v: %w", item.To, err)
+ }
+ item.toTpl = toTpl
+ }
return nil
}
diff --git a/pkg/provider/docker/shared.go b/pkg/provider/docker/shared.go
index 8d2ef4001..931c61905 100644
--- a/pkg/provider/docker/shared.go
+++ b/pkg/provider/docker/shared.go
@@ -33,9 +33,19 @@ type Shared struct {
Watch bool `description:"Watch Docker events." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"`
DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"`
+ LabelMap []*LabelMapItem `description:"Label shorthands." json:"labelMap,omitempty" toml:"labelMap,omitempty" yaml:"labelMap,omitempty"`
+
defaultRuleTpl *template.Template
}
+type LabelMapItem struct {
+ From string `description:"Shorthand label." json:"from,omitempty" toml:"from,omitempty" yaml:"from,omitempty"`
+ To string `description:"Full label with templates." json:"to,omitempty" toml:"to,omitempty" yaml:"to,omitempty"`
+ Value *string `description:"Optional override; used instead of user input if set." json:"value,omitempty" toml:"value,omitempty" yaml:"value,omitempty"`
+ toTpl *template.Template
+}
+
+
func inspectContainers(ctx context.Context, dockerClient client.ContainerAPIClient, containerID string) dockerData {
containerInspected, err := dockerClient.ContainerInspect(ctx, containerID)
if err != nil {