diff --git a/docs/toml.md b/docs/toml.md index a4886d054..ebc02bc48 100644 --- a/docs/toml.md +++ b/docs/toml.md @@ -203,6 +203,7 @@ Træfɪk filters services according to service attributes/tags set in your confi Supported backends: +- Docker - Consul Catalog Supported filters: @@ -574,6 +575,14 @@ watch = true # cert = "/etc/ssl/docker.crt" # key = "/etc/ssl/docker.key" # insecureskipverify = true + +# Constraint on Docker tags +# +# Optional +# +# constraints = ["tag==api", "tag==he*ld"] +# Matching with containers having the label "traefik.tags" set to "api,helloworld" +# ex: $ docker run -d -P --label traefik.tags=api,helloworld emilevauge/whoami ``` Labels can be used on containers to override default behaviour: diff --git a/provider/docker.go b/provider/docker.go index 8f2dcfb87..2afeb37c4 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -177,11 +177,12 @@ func (provider *Docker) loadDockerConfig(containersInspected []dockertypes.Conta } // filter containers - filteredContainers := fun.Filter(containerFilter, containersInspected).([]dockertypes.ContainerJSON) + filteredContainers := fun.Filter(provider.ContainerFilter, containersInspected).([]dockertypes.ContainerJSON) frontends := map[string][]dockertypes.ContainerJSON{} for _, container := range filteredContainers { - frontends[provider.getFrontendName(container)] = append(frontends[provider.getFrontendName(container)], container) + frontendName := provider.getFrontendName(container) + frontends[frontendName] = append(frontends[frontendName], container) } templateObjects := struct { @@ -201,7 +202,8 @@ func (provider *Docker) loadDockerConfig(containersInspected []dockertypes.Conta return configuration } -func containerFilter(container dockertypes.ContainerJSON) bool { +// ContainerFilter checks if container have to be exposed +func (provider *Docker) ContainerFilter(container dockertypes.ContainerJSON) bool { _, err := strconv.Atoi(container.Config.Labels["traefik.port"]) if len(container.NetworkSettings.Ports) == 0 && err != nil { log.Debugf("Filtering container without port and no traefik.port label %s", container.Name) @@ -217,6 +219,15 @@ func containerFilter(container dockertypes.ContainerJSON) bool { return false } + constraintTags := strings.Split(container.Config.Labels["traefik.tags"], ",") + ok, failingConstraint := provider.MatchConstraints(constraintTags) + if ok == false { + if failingConstraint != nil { + log.Debugf("Container %v pruned by '%v' constraint", container.Name, failingConstraint.String()) + } + return false + } + return true } diff --git a/provider/docker_test.go b/provider/docker_test.go index 3605d280a..364f0e885 100644 --- a/provider/docker_test.go +++ b/provider/docker_test.go @@ -621,6 +621,7 @@ func TestDockerGetLabels(t *testing.T) { } func TestDockerTraefikFilter(t *testing.T) { + provider := Docker{} containers := []struct { container docker.ContainerJSON expected bool @@ -792,7 +793,7 @@ func TestDockerTraefikFilter(t *testing.T) { } for _, e := range containers { - actual := containerFilter(e.container) + actual := provider.ContainerFilter(e.container) if actual != e.expected { t.Fatalf("expected %v for %+v, got %+v", e.expected, e, actual) }