diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index 5202dfe32..2a11a2e7c 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -21,7 +21,7 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/). ## Configuration Examples -??? example "Configuring Docker & Deploying / Exposing Services" +??? example "Configuring Docker & Deploying / Exposing one Service" Enabling the docker provider @@ -49,7 +49,7 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/). - traefik.http.routers.my-container.rule=Host(`example.com`) ``` -??? example "Configuring Docker Swarm & Deploying / Exposing Services" +??? example "Configuring Docker Swarm & Deploying / Exposing one Service" Enabling the docker provider (Swarm Mode) @@ -80,7 +80,9 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/). --providers.docker.swarmMode=true ``` - Attach labels to services (not to containers) while in Swarm mode (in your docker compose file) + Attach labels to a single service (not containers) while in Swarm mode (in your Docker compose file). + When there is only one service, and the router does not specify a service, + then that service is automatically assigned to the router. ```yaml version: "3" diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 1c30f7824..e03e93dce 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -22,7 +22,7 @@ With Docker, Traefik can leverage labels attached to a container to generate rou ## Configuration Examples -??? example "Configuring Docker & Deploying / Exposing Services" +??? example "Configuring Docker & Deploying / Exposing one Service" Enabling the docker provider @@ -50,6 +50,56 @@ With Docker, Traefik can leverage labels attached to a container to generate rou - traefik.http.routers.my-container.rule=Host(`example.com`) ``` +??? example "Configuring Docker Swarm & Deploying / Exposing one Service" + + Enabling the docker provider (Swarm Mode) + + ```yaml tab="File (YAML)" + providers: + docker: + # swarm classic (1.12-) + # endpoint: "tcp://127.0.0.1:2375" + # docker swarm mode (1.12+) + endpoint: "tcp://127.0.0.1:2377" + swarmMode: true + ``` + + ```toml tab="File (TOML)" + [providers.docker] + # swarm classic (1.12-) + # endpoint = "tcp://127.0.0.1:2375" + # docker swarm mode (1.12+) + endpoint = "tcp://127.0.0.1:2377" + swarmMode = true + ``` + + ```bash tab="CLI" + # swarm classic (1.12-) + # --providers.docker.endpoint=tcp://127.0.0.1:2375 + # docker swarm mode (1.12+) + --providers.docker.endpoint=tcp://127.0.0.1:2377 + --providers.docker.swarmMode=true + ``` + + Attach labels to services (not containers) while in Swarm mode (in your Docker compose file). + When there is only one service, and the router does not specify a service, + then that service is automatically assigned to the router. + + ```yaml + version: "3" + services: + my-container: + deploy: + labels: + - traefik.http.routers.my-container.rule=Host(`example.com`) + - traefik.http.services.my-container-service.loadbalancer.server.port=8080 + ``` + + !!! important "Labels in Docker Swarm Mode" + While in Swarm Mode, Traefik uses labels found on services, not on individual containers. + Therefore, if you use a compose file with Swarm Mode, labels should be defined in the `deploy` part of your service. + This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1)). + ??? example "Specify a Custom Port for the Container" Forward requests for `http://example.com` to `http://:12345`: @@ -61,6 +111,7 @@ With Docker, Traefik can leverage labels attached to a container to generate rou # ... labels: - traefik.http.routers.my-container.rule=Host(`example.com`) + - traefik.http.routers.my-container.service=my-service" # Tell Traefik to use the port 12345 to connect to `my-container` - traefik.http.services.my-service.loadbalancer.server.port=12345 ``` @@ -92,54 +143,6 @@ With Docker, Traefik can leverage labels attached to a container to generate rou - traefik.http.services.admin-service.loadbalancer.server.port=9000 ``` -??? example "Configuring Docker Swarm & Deploying / Exposing Services" - - Enabling the docker provider (Swarm Mode) - - ```yaml tab="File (YAML)" - providers: - docker: - # swarm classic (1.12-) - # endpoint: "tcp://127.0.0.1:2375" - # docker swarm mode (1.12+) - endpoint: "tcp://127.0.0.1:2377" - swarmMode: true - ``` - - ```toml tab="File (TOML)" - [providers.docker] - # swarm classic (1.12-) - # endpoint = "tcp://127.0.0.1:2375" - # docker swarm mode (1.12+) - endpoint = "tcp://127.0.0.1:2377" - swarmMode = true - ``` - - ```bash tab="CLI" - # swarm classic (1.12-) - # --providers.docker.endpoint=tcp://127.0.0.1:2375 - # docker swarm mode (1.12+) - --providers.docker.endpoint=tcp://127.0.0.1:2377 - --providers.docker.swarmMode=true - ``` - - Attach labels to services (not to containers) while in Swarm mode (in your docker compose file) - - ```yaml - version: "3" - services: - my-container: - deploy: - labels: - - traefik.http.routers.my-container.rule=Host(`example.com`) - - traefik.http.services.my-container-service.loadbalancer.server.port=8080 - ``` - - !!! important "Labels in Docker Swarm Mode" - While in Swarm Mode, Traefik uses labels found on services, not on individual containers. - Therefore, if you use a compose file with Swarm Mode, labels should be defined in the `deploy` part of your service. - This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1)). - ## Routing Configuration !!! info "Labels" @@ -158,7 +161,7 @@ and the router automatically gets a rule defined by `defaultRule` (if no rule fo --8<-- "content/routing/providers/service-by-label.md" -??? example "Automatic service assignment with labels" +??? example "Automatic assignment with one Service" With labels in a compose file @@ -169,7 +172,7 @@ and the router automatically gets a rule defined by `defaultRule` (if no rule fo - "traefik.http.services.myservice.loadbalancer.server.port=80" ``` -??? example "Automatic service creation and assignment with labels" +??? example "Automatic service creation with one Router" With labels in a compose file @@ -180,6 +183,18 @@ and the router automatically gets a rule defined by `defaultRule` (if no rule fo - "traefik.http.routers.myproxy.rule=Host(`example.net`)" ``` +??? example "Explicit definition with one Service" + + With labels in a compose file + + ```yaml + labels: + - traefik.http.routers.www-router.rule=Host(`example-a.com`) + # Explicit link between the router and the service + - traefik.http.routers.www-router.service=www-service + - traefik.http.services.www-service.loadbalancer.server.port=8000 + ``` + ### Routers To update the configuration of the Router automatically attached to the container, @@ -469,7 +484,7 @@ More information about available middlewares in the dedicated [middlewares secti You can declare TCP Routers and/or Services using labels. -??? example "Declaring TCP Routers and Services" +??? example "Declaring TCP Routers with one Service" ```yaml services: @@ -598,7 +613,7 @@ You can declare TCP Routers and/or Services using labels. You can declare UDP Routers and/or Services using labels. -??? example "Declaring UDP Routers and Services" +??? example "Declaring UDP Routers with one Service" ```yaml services: diff --git a/go.mod b/go.mod index 1289bbcf7..88a3eb3f6 100644 --- a/go.mod +++ b/go.mod @@ -67,6 +67,7 @@ require ( github.com/vulcand/predicate v1.2.0 go.elastic.co/apm/module/apmot/v2 v2.4.8 go.elastic.co/apm/v2 v2.4.8 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // No tag on the repo. golang.org/x/mod v0.18.0 golang.org/x/net v0.26.0 golang.org/x/text v0.16.0 @@ -326,7 +327,6 @@ require ( go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect diff --git a/pkg/provider/configuration.go b/pkg/provider/configuration.go index ac1e4b54a..47a65c410 100644 --- a/pkg/provider/configuration.go +++ b/pkg/provider/configuration.go @@ -13,6 +13,7 @@ import ( "github.com/traefik/traefik/v2/pkg/config/dynamic" "github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/tls" + "golang.org/x/exp/maps" ) // Merge merges multiple configurations. @@ -383,7 +384,7 @@ func BuildTCPRouterConfiguration(ctx context.Context, configuration *dynamic.TCP if len(configuration.Services) > 1 { delete(configuration.Routers, routerName) loggerRouter. - Error("Could not define the service name for the router: too many services") + Errorf("Router %s cannot be linked automatically with multiple Services: %q", routerName, maps.Keys(configuration.Services)) continue } @@ -405,7 +406,7 @@ func BuildUDPRouterConfiguration(ctx context.Context, configuration *dynamic.UDP if len(configuration.Services) > 1 { delete(configuration.Routers, routerName) loggerRouter. - Error("Could not define the service name for the router: too many services") + Errorf("Router %s cannot be linked automatically with multiple Services: %q", routerName, maps.Keys(configuration.Services)) continue } @@ -452,7 +453,7 @@ func BuildRouterConfiguration(ctx context.Context, configuration *dynamic.HTTPCo if len(configuration.Services) > 1 { delete(configuration.Routers, routerName) loggerRouter. - Error("Could not define the service name for the router: too many services") + Errorf("Router %s cannot be linked automatically with multiple Services: %q", routerName, maps.Keys(configuration.Services)) continue }