# Trouble understanding how traefik picks up a custom SSL certificate for a domain

**URL:** <https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867>\
**Category:** Traefik v2\
**Tags:** docker-swarm, docker\
**Created:** [September 25, 2019, 10:54am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867 "2019-09-25T10:54:41Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [September 25, 2019, 10:54am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/1 "2019-09-25T10:54:41Z")

</div>

I am having trouble understanding the relation between the router and the provided SSL ceritifcate files. How traefik knows which certificate to choose for a particular domain.

I have got following configuration but traefik is providing a default SSL certificate. The traefik docs have largly described how to use ACME but it does not specify clearly how to use your own SSL certificates for multiple domains.

Here is my traefik.toml

```auto
[entrypoints]
  [entrypoints.http]
    address = ":80"

  [entrypoints.https]
    address = ":443"

[providers]
  [providers.docker]

[tls]

  [tlsOptions]
    [tlsOptions.default]
      minVersion = "VersionTLS12"
      sniStrict = true

  [[tls.certificates]]
    certFile = "/data/traefik/domain.io.cert"
    keyFile = "/data/traefik/domain.io.key"

```

and here is my YAML for docker stack.

```auto
version: '3'

services:
  reverse-proxy:
    image: traefik:v2.0
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /data/traefik/traefik.toml:/etc/traefik/traefik.toml

  whoami:
    image: containous/whoami
    labels:
      - "traefik.http.routers.route1.rule=Host(`domain.io`)"
      - "traefik.http.routers.route1.entrypoints=https"
      - "traefik.http.routers.route1.tls=true"

```

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [September 25, 2019, 11:31am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/2 "2019-09-25T11:31:05Z")

</div>

Hello,

In the v2 the static configuration and the dynamic configuration cannot be mixed, so:

```auto
# static configuration
# traefik.toml

[entrypoints]
  [entrypoints.http]
    address = ":80"

  [entrypoints.https]
    address = ":443"

[providers]
  [providers.docker]
  
  [providers.file]
    filename = "/etc/traefik/dyn.toml"

```

```auto
# dynamic configuration
# dyn.toml

[tls.options]

  [tls.options.default]
    minVersion = "VersionTLS12"
    sniStrict = true

[[tls.certificates]]
  certFile = "/data/traefik/domain.io.cert"
  keyFile = "/data/traefik/domain.io.key"

```

Check the TLS options syntax: [https://docs.traefik.io/v2.0/https/tls/#tls-options](https://docs.traefik.io/v2.0/https/tls/#tls-options)

and [https://docs.traefik.io//v2.0/https/tls/#certificates-definition](https://docs.traefik.io//v2.0/https/tls/#certificates-definition)

```auto
version: '3'

services:
  reverse-proxy:
    image: traefik:v2.0
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /data/traefik/traefik.toml:/etc/traefik/traefik.toml
      - /data/traefik/dyn.toml:/etc/traefik/dyn.toml

  whoami:
    image: containous/whoami
    labels:
      - "traefik.http.routers.route1.rule=Host(`domain.io`)"
      - "traefik.http.routers.route1.entrypoints=https"
      - "traefik.http.routers.route1.tls=true"

```

dynamic configuration:

- routers
- middlewares
- services
- tls

documentation:

- [https://docs.traefik.io/v2.0/getting-started/configuration-overview/#the-dynamic-configuration](https://docs.traefik.io/v2.0/getting-started/configuration-overview/#the-dynamic-configuration)
- [https://docs.traefik.io/v2.0/reference/dynamic-configuration/file/](https://docs.traefik.io/v2.0/reference/dynamic-configuration/file/)

static configuration:

- information about the providers to used
- logger definition
- ...

documentation:

- [https://docs.traefik.io/v2.0/getting-started/configuration-overview/#the-static-configuration](https://docs.traefik.io/v2.0/getting-started/configuration-overview/#the-static-configuration)
- [https://docs.traefik.io/v2.0/reference/static-configuration/file/](https://docs.traefik.io/v2.0/reference/static-configuration/file/)

---

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [September 25, 2019, 11:58am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/3 "2019-09-25T11:58:39Z")

</div>

Hi @Idez

Thank you so much for responding so quickly. I have got your point that static and dynamic config can't be mixed.

I have gone through the documentation. But there seems to be something still missing for my slow mind.

Let's say we have following two certificate files for two different domains.

```auto
# Dynamic configuration

[[tls.certificates]]
  certFile = "/path/to/domain.io.cert"
  keyFile = "/path/to/domain.io.key"

[[tls.certificates]]
  certFile = "/path/to/other.io.cert"
  keyFile = "/path/to/other.io.key"

```

If the first certificate is valid for wildcard `*.domain.io` and second one is for `*.other.io`. Does it mean that traefik will pickup both of these certificates at the start time. Then Traefik magically knows that it has to apply the file `/path/to/domain.io.cert` for any routers like `Host('dev.domain.io')` or `Host('www.domain.io')` ?

Similarly it knows that it has to apply the file `/path/to/other.io.cert` for any routers like `Host('dev.other.io')` or `Host('www.other.io')`?

This is the part where things get confusing. For example, I can see in the documentation that we can set `tls.options` in routers. But not sure what's the point of having stores of certificates and how do we tell a router, which certificate or store to use?

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [September 25, 2019, 12:16pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/4 "2019-09-25T12:16:02Z")

</div>

> [@traefiker1](#):
>
> If the first certificate is valid for wildcard `*.domain.io` and second one is for `*.other.io` . Does it mean that traefik will pickup both of these certificates at the start time. Then Traefik magically knows that it has to apply the file `/path/to/domain.io.cert` for any routers like `Host('dev.domain.io')` or `Host('www.domain.io')` ?

Traefik will use main and sans from the certificate to know which certificate to use.

> [@traefiker1](#):
>
> This is the part where things get confusing. For example, I can see in the documentation that we can set `tls.options` in routers.

- [Routers | Traefik | v2.0](https://docs.traefik.io/v2.0/routing/routers/#options)

---

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [September 25, 2019, 12:47pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/5 "2019-09-25T12:47:01Z")

</div>

Is it possible for me to add certFile and keyFile paths via docker labels?

```auto
- "traefik.http.routers.route1.tls.certificates.certFile=/data/traefik/domain.io.cert"
- "traefik.http.routers.route1.tls.certificates.keyFile=/data/traefik/domain.io.key"

```

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [September 25, 2019, 12:56pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/6 "2019-09-25T12:56:01Z")

</div>

> Restriction
> 
> In the above example, we've used the [file provider](https://docs.traefik.io/providers/file/) to handle these definitions. It is the only available method to configure the certificates (as well as the options and the stores).

> **[Traefik TLS Documentation - Traefik](https://doc.traefik.io/traefik/v2.0/https/tls/)**
>
> Learn how to configure the transport layer security (TLS) connection in Traefik Proxy. Read the technical documentation.

---

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [September 25, 2019, 1:21pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/7 "2019-09-25T13:21:55Z")

</div>

Thank you so much for the great help.

I am stuck so far. Here are my files but still getting the "DEFAULT TRAEFIK CERTIFICATE". Not the actual certificate.

Any idea what I am doing wrong?

```auto
# traefik.toml
[entrypoints]
  [entrypoints.http]
    address = ":80"

  [entrypoints.https]
    address = ":443"

[providers]
  [providers.docker]
  
  [providers.file]
    filename = "/etc/traefik/dyn.toml"

```

```auto
#dyn.toml
[tls]

  [tls.stores]
    [tls.stores.default]
      [tls.stores.default.defaultCertificate]
        certFile = "/volumes/traefik2/my.cert"
        keyFile = "/volumes/traefik2/my.key"

  [[tls.certificates]]
    certFile = "/volumes/traefik2/my.cert"
    keyFile = "/volumes/traefik2/my.key"

```

Docker stack file:

```auto
# stack.yml
version: '3'

services:
  reverse-proxy:
    image: traefik:v2.0
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /volumes/traefik2/traefik.toml:/etc/traefik/traefik.toml
      - /volumes/traefik2/dyn.toml:/etc/traefik/dyn.toml

  whoami:
    image: containous/whoami
    labels:
      - "traefik.http.routers.route1.rule=Host(`dev.my.io`)"
      - "traefik.http.routers.route1.entrypoints=https"
      - "traefik.http.routers.route1.tls=true"
      - "traefik.http.routers.route1.tls.domains[0].main=my.io"
      - "traefik.http.routers.route1.tls.domains[0].sans=*.my.io"

```

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [September 25, 2019, 1:23pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/8 "2019-09-25T13:23:09Z")

</div>

> [@traefiker1](#):
>
> ```auto
> - "traefik.http.routers.route1.tls.domains[0].main=my.io"
> - "traefik.http.routers.route1.tls.domains[0].sans=*.my.io"
> 
> ```

`domains` are used for acme.

---

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [September 26, 2019, 1:03am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/10 "2019-09-26T01:03:28Z")

</div>

Thanks, it fixed the other issues I had. Currently, getting an SSL error. Any help will be greatly appreciated.

```auto
t_reverse-proxy.1.j725zfl87hft@my.io | time="2019-09-26T00:49:40Z" level=error msg="Error while creating certificate store: failed to load X509 key pair: tls: failed to find any PEM data in certificate input" tlsStoreName=default
t_reverse-proxy.1.j725zfl87hft@my.io | time="2019-09-26T00:49:40Z" level=error msg="Unable to append certificate /volumes/traefik2/fullchain.crt to store: unable to generate TLS certificate : tls: failed to find any PEM data in certificate input" tlsStoreName=default

```

Although I can verify from openssl command that my certFile is a valid file.

```auto
root@my:/volumes/traefik2# openssl crl2pkcs7 -nocrl -certfile fullchain.crt | openssl pkcs7 -print_certs -noout
subject=OU = Domain Control Validated, CN = *.my.io
issuer=C = BE, O = GlobalSign nv-sa, CN = AlphaSSL CA - SHA256 - G2

subject=C = BE, O = GlobalSign nv-sa, CN = AlphaSSL CA - SHA256 - G2
issuer=C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA

subject=C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
issuer=C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA

```

Below is the format of the contents of my fullchain.crt

```auto
-----BEGIN CERTIFICATE-----
(Primary SSL certificate: domain_name.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Intermediate certificate: DigiCertCA.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Root certificate: TrustedRoot.crt)
-----END CERTIFICATE-----

```

---

<div class="post-metadata">

**Author:** ![zespri](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/zespri/32/310_2.png) [@zespri](https://community.traefik.io/u/zespri)\
**Post date:** [September 26, 2019, 2:05am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/11 "2019-09-26T02:05:27Z")

</div>

If your cert is valid and traefik complains that it's not, then chances are that you are not giving traefik the same file you think you are giving. I suggest, using alpine traefik container, and exec'ing into it to prove that.

---

<div class="post-metadata">

**Author:** ![ldez](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/ldez/32/5_2.png) [@ldez](https://community.traefik.io/u/ldez)\
**Post date:** [September 26, 2019, 2:11am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/12 "2019-09-26T02:11:13Z")

</div>

@zespri the v2 is only available as an alpine flavor.

Note don't use tags like `v2.0-alpine`, `v2.0.0-alpine` ,`alpine`, ...

---

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [September 26, 2019, 2:17am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/13 "2019-09-26T02:17:34Z")

</div>

Thank you both of you..👍👍 These tips have helped me resolving the issue. The SSL issue was in the volume path.

---

<div class="post-metadata">

**Author:** ![eddyready20](https://avatars.discourse-cdn.com/v4/letter/e/6bbea6/32.png) [@eddyready20](https://community.traefik.io/u/eddyready20)\
**Post date:** [January 8, 2020, 8:33am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/14 "2020-01-08T08:33:24Z")

</div>

Hi, Can I ask what you set the volume path? I am getting the same error.

Edward

---

<div class="post-metadata">

**Author:** ![climacs-net](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/climacs-net/32/3040_2.png) [@climacs-net](https://community.traefik.io/u/climacs-net)\
**Post date:** [December 10, 2020, 6:40pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/15 "2020-12-10T18:40:36Z")

</div>

Hi just want to get info how did you resolve this when you say volume path?

---

<div class="post-metadata">

**Author:** ![traefiker1](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@traefiker1](https://community.traefik.io/u/traefiker1)\
**Post date:** [December 11, 2020, 12:24am UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/16 "2020-12-11T00:24:31Z")

</div>

These are my file paths in Linux:

```auto
/volumes/traefik/traefik.toml
/volumes/traefik/dyn.toml

```

Here is how dyn.toml path looks like inside my traefik.toml

```auto
  [providers.file]
    filename = "/etc/traefik/dyn.toml"
    watch = true

```

So, I guess if we keep the SSL files where traefik.toml is, then we can write paths in traefik.toml like:

```auto
[[tls.certificates]]
  certFile = "/etc/traefik/domain.io.cert"
  keyFile = "/etc/traefik/domain.io.key"

```

---

<div class="post-metadata">

**Author:** ![cakiwi](https://sea2.discourse-cdn.com/flex020/user_avatar/community.traefik.io/cakiwi/32/3205_2.png) [@cakiwi](https://community.traefik.io/u/cakiwi)\
**Post date:** [December 14, 2020, 5:24pm UTC](https://community.traefik.io/t/trouble-understanding-how-traefik-picks-up-a-custom-ssl-certificate-for-a-domain/1867/17 "2020-12-14T17:24:56Z")

</div>


