description: "Learn how to achieve configuration discovery in Traefik through Docker. Read the technical documentation."
---
# Traefik & Docker
!!! tip "The Quick Start Uses Docker"
If you have not already read it, maybe you would like to go through the [quick start guide](../../../getting-started/quick-start.md) that uses the Docker provider.
## Configuration Example
You can enable the Docker provider as detailed below:
```yaml tab="File (YAML)"
providers:
docker: {}
```
```toml tab="File (TOML)"
[providers.docker]
```
```bash tab="CLI"
--providers.docker=true
```
Attach labels to containers (in your Docker compose file)
| <aid="providers-providersThrottleDuration"href="#providers-providersThrottleDuration"title="#providers-providersThrottleDuration">`providers.providersThrottleDuration`</a> | Minimum amount of time to wait for, after a configuration reload, before taking into account any new configuration refresh event.<br/>If multiple events occur within this time, only the most recent one is taken into account, and all others are discarded.<br/>**This option cannot be set per provider, but the throttling algorithm applies to each of them independently.** | 2s | No |
| <aid="providers-docker-endpoint"href="#providers-docker-endpoint"title="#providers-docker-endpoint">`providers.docker.endpoint`</a> | Specifies the Docker API endpoint. See [here](#endpoint) for more information| "unix:///var/run/docker.sock" | Yes |
| <aid="providers-docker-username"href="#providers-docker-username"title="#providers-docker-username">`providers.docker.username`</a> | Defines the username for Basic HTTP authentication. This should be used when the Docker daemon socket is exposed through an HTTP proxy that requires Basic HTTP authentication.| "" | No |
| <aid="providers-docker-password"href="#providers-docker-password"title="#providers-docker-password">`providers.docker.password`</a> | Defines the password for Basic HTTP authentication. This should be used when the Docker daemon socket is exposed through an HTTP proxy that requires Basic HTTP authentication.| "" | No |
| <aid="providers-docker-useBindPortIP"href="#providers-docker-useBindPortIP"title="#providers-docker-useBindPortIP">`providers.docker.useBindPortIP`</a> | Instructs Traefik to use the IP/Port attached to the container's binding instead of its inner network IP/Port. See [here](#usebindportip) for more information | false | No |
| <aid="providers-docker-exposedByDefault"href="#providers-docker-exposedByDefault"title="#providers-docker-exposedByDefault">`providers.docker.exposedByDefault`</a> | Expose containers by default through Traefik. See [here](./overview.md#restrict-the-scope-of-service-discovery) for additional information | true | No |
| <aid="providers-docker-network"href="#providers-docker-network"title="#providers-docker-network">`providers.docker.network`</a> | Defines a default docker network to use for connections to all containers. This option can be overridden on a per-container basis with the `traefik.docker.network` label.| "" | No |
| <aid="providers-docker-defaultRule"href="#providers-docker-defaultRule"title="#providers-docker-defaultRule">`providers.docker.defaultRule`</a> | Defines what routing rule to apply to a container if no rule is defined by a label. See [here](#defaultrule) for more information. | ```"Host(`{{ normalize .Name }}`)"``` | No |
| <aid="providers-docker-httpClientTimeout"href="#providers-docker-httpClientTimeout"title="#providers-docker-httpClientTimeout">`providers.docker.httpClientTimeout`</a> | Defines the client timeout (in seconds) for HTTP connections. If its value is 0, no timeout is set. | 0 | No |
| <aid="providers-docker-watch"href="#providers-docker-watch"title="#providers-docker-watch">`providers.docker.watch`</a> | Instructs Traefik to watch Docker events or not. | True | No |
| <aid="providers-docker-constraints"href="#providers-docker-constraints"title="#providers-docker-constraints">`providers.docker.constraints`</a> | Defines an expression that Traefik matches against the container labels to determine whether to create any route for that container. See [here](#constraints) for more information. | "" | No |
| <aid="providers-docker-allowEmptyServices"href="#providers-docker-allowEmptyServices"title="#providers-docker-allowEmptyServices">`providers.docker.allowEmptyServices`</a> | Instructs the provider to create any [servers load balancer](../../../routing/services/index.md#servers-load-balancer) defined for Docker containers regardless of the [healthiness](https://docs.docker.com/engine/reference/builder/#healthcheck) of the corresponding containers. | false | No |
| <aid="providers-docker-tls-ca"href="#providers-docker-tls-ca"title="#providers-docker-tls-ca">`providers.docker.tls.ca`</a> | Defines the path to the certificate authority used for the secure connection to Docker, it defaults to the system bundle. | "" | No |
| <aid="providers-docker-tls-cert"href="#providers-docker-tls-cert"title="#providers-docker-tls-cert">`providers.docker.tls.cert`</a> | Defines the path to the public certificate used for the secure connection to Docker. When using this option, setting the `key` option is required. | "" | Yes |
| <aid="providers-docker-tls-key"href="#providers-docker-tls-key"title="#providers-docker-tls-key">`providers.docker.tls.key`</a> | Defines the path to the private key used for the secure connection to Docker. When using this option, setting the `cert` option is required. | "" | Yes |
| <aid="providers-docker-tls-insecureSkipVerify"href="#providers-docker-tls-insecureSkipVerify"title="#providers-docker-tls-insecureSkipVerify">`providers.docker.tls.insecureSkipVerify`</a> | Instructs the provider to accept any certificate presented by the Docker server when establishing a TLS connection, regardless of the hostnames the certificate covers. | false | No |
Traefik routes requests to the IP/port of the matching container.
When setting `useBindPortIP=true`, you tell Traefik to use the IP/Port attached to the container's _binding_ instead of its inner network IP/Port.
When used in conjunction with the `traefik.http.services.<name>.loadbalancer.server.port` label (that tells Traefik to route requests to a specific port),
Traefik tries to find a binding on port `traefik.http.services.<name>.loadbalancer.server.port`.
If it cannot find such a binding, Traefik falls back on the internal network IP of the container,
but still uses the `traefik.http.services.<name>.loadbalancer.server.port` that is set in the label.
??? example "Examples of `usebindportip` in different situations."
Please note that any tool like Nomad, Terraform, Ansible, etc.
that is able to define a Docker container with labels can work
with Traefik and the Docker provider.
### Port Detection
Traefik retrieves the private IP and port of containers from the Docker API.
Port detection for private communication works as follows:
- If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) a single port,
then Traefik uses this port.
- If a container [exposes](https://docs.docker.com/engine/reference/builder/#expose) multiple ports,
then Traefik uses the lowest port. E.g. if `80` and `8080` are exposed, Traefik will use `80`.
- If a container does not expose any port, or the selection from multiple ports does not fit,
then you must manually specify which port Traefik should use for communication
by using the label `traefik.http.services.<service_name>.loadbalancer.server.port`
(Read more on this label in the dedicated section in [routing](../../../routing/providers/docker.md#services)).
### Host networking
When exposing containers that are configured with [host networking](https://docs.docker.com/network/host/),
the IP address of the host is resolved as follows:
- try a lookup of `host.docker.internal`
- if the lookup was unsuccessful, try a lookup of `host.containers.internal`, ([Podman](https://docs.podman.io/en/latest/) equivalent of `host.docker.internal`)
- if that lookup was also unsuccessful, fall back to `127.0.0.1`
On Linux, for versions of Docker older than 20.10.0, for `host.docker.internal` to be defined, it should be provided
as an `extra_host` to the Traefik container, using the `--add-host` flag. For example, to set it to the IP address of
the bridge interface (`docker0` by default): `--add-host=host.docker.internal:172.17.0.1`.
### IPv4 & IPv6
When using a docker stack that uses IPv6,
Traefik will use the IPv4 container IP before its IPv6 counterpart.
Therefore, on an IPv6 Docker stack,
Traefik will use the IPv6 container IP.
### Docker API Access
Traefik requires access to the docker socket to get its dynamic configuration.
You can specify which Docker API Endpoint to use with the directive [`endpoint`](#endpoint).
!!! warning "Security Note"
Accessing the Docker API without any restriction is a security concern:
If Traefik is attacked, then the attacker might get access to the underlying host.
{: #security-note }
As explained in the [Docker Daemon Attack Surface documentation](https://docs.docker.com/engine/security/#docker-daemon-attack-surface):
!!! quote
[...] only **trusted** users should be allowed to control your Docker daemon [...]
??? success "Solutions"
Expose the Docker socket over TCP or SSH, instead of the default Unix socket file.
It allows different implementation levels of the [AAA (Authentication, Authorization, Accounting) concepts](https://en.wikipedia.org/wiki/AAA_(computer_security)), depending on your security assessment:
- Authentication with Client Certificates as described in ["Protect the Docker daemon socket."](https://docs.docker.com/engine/security/protect-access/)
- Authorize and filter requests to restrict possible actions with [the TecnativaDocker Socket Proxy](https://github.com/Tecnativa/docker-socket-proxy).
- Authorization with the [Docker Authorization Plugin Mechanism](https://web.archive.org/web/20190920092526/https://docs.docker.com/engine/extend/plugins_authorization/)
- Accounting at networking level, by exposing the socket only inside a Docker private network, only available for Traefik.
- Accounting at container level, by exposing the socket on a another container than Traefik's.
- Accounting at kernel level, by enforcing kernel calls with mechanisms like [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux), to only allows an identified set of actions for Traefik's process (or the "socket exposer" process).
- SSH public key authentication (SSH is supported with Docker > 18.09)
- Authentication using HTTP Basic authentication through an HTTP proxy that exposes the Docker daemon socket.
??? info "More Resources and Examples"
- ["Paranoid about mounting /var/run/docker.sock?"](https://medium.com/@containeroo/traefik-2-0-paranoid-about-mounting-var-run-docker-sock-22da9cb3e78c)
- [Traefik and Docker: A Discussion with Docker Captain, Bret Fisher](https://blog.traefik.io/traefik-and-docker-a-discussion-with-docker-captain-bret-fisher-7f0b9a54ff88)
- [KubeCon EU 2018 Keynote, Running with Scissors, from Liz Rice](https://www.youtube.com/watch?v=ltrV-Qmh3oY)
- [Don't expose the Docker socket (not even to a container)](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/)
- [A thread on Stack Overflow about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623)
- [To DinD or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html)
- [Traefik issue GH-4174 about security with Docker socket](https://github.com/traefik/traefik/issues/4174)
- [Inspecting Docker Activity with Socat](https://developers.redhat.com/blog/2015/02/25/inspecting-docker-activity-with-socat/)
- [Letting Traefik run on Worker Nodes](https://blog.mikesir87.io/2018/07/letting-traefik-run-on-worker-nodes/)
- [Docker Socket Proxy from Tecnativa](https://github.com/Tecnativa/docker-socket-proxy)