diff --git a/configuration.go b/configuration.go index cb4b17f9a..2aa4fe920 100644 --- a/configuration.go +++ b/configuration.go @@ -218,6 +218,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration { //default Docker var defaultDocker provider.Docker defaultDocker.Watch = true + defaultDocker.ExposedByDefault = true defaultDocker.Endpoint = "unix:///var/run/docker.sock" // default File diff --git a/docs/toml.md b/docs/toml.md index 2f12347b4..f6be08a66 100644 --- a/docs/toml.md +++ b/docs/toml.md @@ -521,6 +521,13 @@ watch = true # # filename = "docker.tmpl" +# Expose containers by default in traefik +# +# Optional +# Default: true +# +exposedbydefault = true + # Enable docker TLS connection # # [docker.tls] diff --git a/integration/fixtures/docker/simple.toml b/integration/fixtures/docker/simple.toml index fa0b3481e..d3c3052ab 100644 --- a/integration/fixtures/docker/simple.toml +++ b/integration/fixtures/docker/simple.toml @@ -12,3 +12,4 @@ logLevel = "DEBUG" endpoint = "{{.DockerHost}}" domain = "docker.localhost" +exposedbydefault = true \ No newline at end of file diff --git a/provider/docker.go b/provider/docker.go index 472b9f7b6..f71aa8892 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -30,9 +30,10 @@ const DockerAPIVersion string = "1.21" // Docker holds configurations of the Docker provider. type Docker struct { BaseProvider - Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` - Domain string `description:"Default domain used"` - TLS *DockerTLS `description:"Enable Docker TLS support"` + Endpoint string `description:"Docker server endpoint. Can be a tcp or a unix socket endpoint"` + Domain string `description:"Default domain used"` + TLS *DockerTLS `description:"Enable Docker TLS support"` + ExposedByDefault bool `description:"Expose containers by default"` } // DockerTLS holds TLS specific configurations @@ -177,7 +178,9 @@ func (provider *Docker) loadDockerConfig(containersInspected []dockertypes.Conta } // filter containers - filteredContainers := fun.Filter(provider.ContainerFilter, containersInspected).([]dockertypes.ContainerJSON) + filteredContainers := fun.Filter(func(container dockertypes.ContainerJSON) bool { + return provider.containerFilter(container, provider.ExposedByDefault) + }, containersInspected).([]dockertypes.ContainerJSON) frontends := map[string][]dockertypes.ContainerJSON{} for _, container := range filteredContainers { @@ -202,8 +205,7 @@ func (provider *Docker) loadDockerConfig(containersInspected []dockertypes.Conta return configuration } -// ContainerFilter checks if container have to be exposed -func (provider *Docker) ContainerFilter(container dockertypes.ContainerJSON) bool { +func (provider *Docker) containerFilter(container dockertypes.ContainerJSON, exposedByDefaultFlag bool) 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) @@ -214,7 +216,7 @@ func (provider *Docker) ContainerFilter(container dockertypes.ContainerJSON) boo return false } - if container.Config.Labels["traefik.enable"] == "false" { + if !isContainerEnabled(container, exposedByDefaultFlag) { log.Debugf("Filtering disabled container %s", container.Name) return false } @@ -326,6 +328,10 @@ func (provider *Docker) getEntryPoints(container dockertypes.ContainerJSON) []st return []string{} } +func isContainerEnabled(container dockertypes.ContainerJSON, exposedByDefault bool) bool { + return exposedByDefault && container.Config.Labels["traefik.enable"] != "false" || container.Config.Labels["traefik.enable"] == "true" +} + func getLabel(container dockertypes.ContainerJSON, label string) (string, error) { for key, value := range container.Config.Labels { if key == label { diff --git a/provider/docker_test.go b/provider/docker_test.go index 5dad8e030..80e9b8375 100644 --- a/provider/docker_test.go +++ b/provider/docker_test.go @@ -647,8 +647,9 @@ func TestDockerGetLabels(t *testing.T) { func TestDockerTraefikFilter(t *testing.T) { provider := Docker{} containers := []struct { - container docker.ContainerJSON - expected bool + container docker.ContainerJSON + exposedByDefault bool + expected bool }{ { container: docker.ContainerJSON{ @@ -658,7 +659,8 @@ func TestDockerTraefikFilter(t *testing.T) { Config: &container.Config{}, NetworkSettings: &docker.NetworkSettings{}, }, - expected: false, + exposedByDefault: true, + expected: false, }, { container: docker.ContainerJSON{ @@ -678,7 +680,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: false, + exposedByDefault: true, + expected: false, }, { container: docker.ContainerJSON{ @@ -698,7 +701,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: true, + exposedByDefault: true, + expected: true, }, { container: docker.ContainerJSON{ @@ -715,7 +719,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: false, + exposedByDefault: true, + expected: false, }, { container: docker.ContainerJSON{ @@ -731,7 +736,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: true, + exposedByDefault: true, + expected: true, }, { container: docker.ContainerJSON{ @@ -752,7 +758,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: true, + exposedByDefault: true, + expected: true, }, { container: docker.ContainerJSON{ @@ -772,7 +779,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: true, + exposedByDefault: true, + expected: true, }, { container: docker.ContainerJSON{ @@ -792,7 +800,8 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: true, + exposedByDefault: true, + expected: true, }, { container: docker.ContainerJSON{ @@ -812,12 +821,51 @@ func TestDockerTraefikFilter(t *testing.T) { }, }, }, - expected: true, + exposedByDefault: true, + expected: true, + }, + { + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{}, + NetworkSettings: &docker.NetworkSettings{ + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, + }, + }, + }, + exposedByDefault: false, + expected: false, + }, + { + container: docker.ContainerJSON{ + ContainerJSONBase: &docker.ContainerJSONBase{ + Name: "container", + }, + Config: &container.Config{ + Labels: map[string]string{ + "traefik.enable": "true", + }, + }, + NetworkSettings: &docker.NetworkSettings{ + NetworkSettingsBase: docker.NetworkSettingsBase{ + Ports: nat.PortMap{ + "80/tcp": {}, + }, + }, + }, + }, + exposedByDefault: false, + expected: true, }, } for _, e := range containers { - actual := provider.ContainerFilter(e.container) + actual := provider.containerFilter(e.container, e.exposedByDefault) if actual != e.expected { t.Fatalf("expected %v for %+v, got %+v", e.expected, e, actual) } @@ -971,7 +1019,8 @@ func TestDockerLoadDockerConfig(t *testing.T) { } provider := &Docker{ - Domain: "docker.localhost", + Domain: "docker.localhost", + ExposedByDefault: true, } for _, c := range cases { diff --git a/traefik.sample.toml b/traefik.sample.toml index 38803498c..74474bc0c 100644 --- a/traefik.sample.toml +++ b/traefik.sample.toml @@ -246,6 +246,13 @@ # # filename = "docker.tmpl" +# Expose containers by default in traefik +# +# Optional +# Default: true +# +# exposedbydefault = true + # Enable docker TLS connection # # Optional