Combine ACME let's encrypt https entrypoint with custom certificate entrypoint

Hi, I have a setup consisting of several docker containers that are accessed via traefik using https with let's encrypt. This setup is working perfectly. Here's the traefik.yml i'm using

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  mariadb:
    address: ":3306"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

certificatesResolvers:
  http:
    acme:
      email: mail
      storage: acme.json
      httpChallenge:
        entryPoint: http

Now I want to mantain the current setup but I want to add a service that has to be routed via an https using a private certificate (I have already created and it is saved in /certs folder). But I don't know how to configure the trefik.yml to add the certificate and select it for a specific something.mydomain.net

I have put up this:

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  mariadb:
    address: ":3306"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

tls:
  certificates:
    - certFile: /certs/key.crt
      keyFile: /certs/key.key

https:
  routers:
    https_custom_cert:
      rule: "Host(`domain.net`)"
      tls:
          certResolver: "?????"

tls:
  stores:
    default:
      defaultGeneratedCert:
        resolver: acme
        domain:
          main: domain.net
          sans: "*.domain.net"
      defaultCertificate:
         certFile: /certs/key.crt
         keyFile: /certs/key.key

certificatesResolvers:
  http:
    acme:
      email: mail
      storage: acme.json
      httpChallenge:
        entryPoint: http

But I can't find a complete tutorial on how to make it work. Can you provide some guidance or a more complete tutorial?

To use custom TLS/SSL certs, you can load them in the static config via provider.file from a dynamic config file. You don't need to add any host information in the tls section.

tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
    - certFile: /traefik/example.com.crt
      keyFile: /traefik/example.com.key

Then simply enable TLS on the router (dynamic config):

- traefik.http.routers.myrouter.tls=true

On the router for LetsEncrypt just enable TLS with the resolver (dynamic config):

- traefik.http.routers.myrouter2.tls.certresolver=myresolver

Don't forget to define myresolver in the static config.

PS: Prefer tlschallenge over httpchallenge (I was told)

1 Like

Hi @bluepuma77 and thank you for your guidance.

I have updated the traefik.yml file as follows:

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  mariadb:
    address: ":3306"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
    - certFile: /certs/cert.crt
      keyFile: /certs/cert.key
      
certificatesResolvers:
  http:
    acme:
      email: email
      storage: acme.json
      httpChallenge:
        entryPoint: http

The docker container in which I want my custom certificate is configured with the following labels:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mockdb2.entrypoints=http"
      - "traefik.http.routers.mockdb2.rule=Host(`mockdb2.domain.net`)"
      - "traefik.http.middlewares.mockdb2-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.mockdb2.middlewares=mockdb2-https-redirect"
      - "traefik.http.routers.mockdb2-secure.entrypoints=https"
      - "traefik.http.routers.mockdb2-secure.rule=Host(`mockdb2.domain.net`)"
      - "traefik.http.routers.mockdb2-secure.tls=true"
      - "traefik.http.routers.mockdb2-secure.service=mockdb2"
      - "traefik.http.services.mockdb2.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"

The previous labels are the ones I use with all the other services that run TLS with let's encrypt except for this line: - "traefik.http.routers.influxdb2-secure.tls.certresolver=http"
Which as I have understood from your message is the one that links the tls to the let's encrypt cert resolver.

If I spin up this and navigate to mocdb2.domain.net I'm warned that the certificate is not valid (which is good, because it means it is not using the let's encrypt one). However, when I look into the certificate details I see this:
image
Which means that traefik is using its default certificate and not the one I have set on the config.

What am I doing wrong? The other services that are suposed to be running with let's encrypt are working fine. So at least I have not broken something that previously worked :slight_smile:

Redirect to https

Place you redirect centrally in entrypoints, that cleans things up a bit (static traefik.yml):

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https

  websecure:
    address: :443

Custom (paid for) TLS certificates
Those need to go into a dynamic config, loaded by provider.file in static config.

#traefik.yml
providers:
  file:
    filename: /traefik-dynamic.yml
    watch: true

Create an additional dynamic configuration file

#traefik-dynamic.yml
tls:
  options:
    default:
      minVersion: VersionTLS12
  certificates:
    - certFile: /certs/cert.crt
      keyFile: /certs/cert.key

Enable on service with label. Router rule Host must match your certificate

- traefik.http.routers.myrouter.tls=true

LetsEncrypt
Your give your resolver a name (in traefik.yml):

certificatesResolvers:
  myresolver: # <-- name of your resolver
    acme:
      ...

Use that name in the (dynamic) assignment:

- traefik.http.routers.influxdb2-secure.tls.certresolver=myresolver

Wow, I didn't know that this could be done. When everything is working I will definetly try to do this.

Do you have an example docker-compose.yml file with the traefik labels necessary for it to work? Since the redirection to https is done on traefik.yml I supose there a lot less lines needed.

Ok, I have created the traefik-dinamic.yml file with the config you said. The traefik.yml is:

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
  mariadb:
    address: ":3306"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: /traefik-dynamic.yml
    watch: true
      
certificatesResolvers:
  http:
    acme:
      email: mail
      storage: acme.json
      httpChallenge:
        entryPoint: http

the labels in the docker-compose.yml that I want to use with the private certificate is:

labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mockdb2.entrypoints=http"
      - "traefik.http.routers.mockdb2.rule=Host(`mockdb2.domain.net`)"
      - "traefik.http.middlewares.mockdb2-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.mockdb2.middlewares=mockdb2-https-redirect"
      - "traefik.http.routers.mockdb2-secure.entrypoints=https"
      - "traefik.http.routers.mockdb2-secure.rule=Host(`mockdb2.domain.net`)"
      - "traefik.http.routers.mockdb2-secure.tls=true"
      - "traefik.http.routers.mockdb2-secure.service=mockdb2"
      - "traefik.http.services.mockdb2.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"

Note the - "traefik.http.routers.mockdb2-secure.tls=true"

However, when I look at the certificate on chrome it stills shows the traefik default certificate....

I know I'm not doing everything you proposed. But I'm worried that if I try to do so I will break something that is working now.

You can remove those, use redirect in entrypoints.

Check your Traefik log for error, if traefik-dynamic.yml and /certs/cert.crt are loaded correctly. Your cert.crt needs to include mockdb2.domain.net or be a wildcard cert.

Note: you should place acme.json on a fixed path and Docker-mount that as folder or volume. LE only allows 5 certificate re-creations per week for a domain name. So if you reset/restart you service often you might loose LE certs after 5 times.

PS: Why do you even want to use a custom cert? Just use a LE cert for this one, too.

1 Like

Well, I didn't correctly configure the domain of the certificate. Now it is working.

And I needed to use a private certificate because I want to be the one on control of when it expires. This is because it will be used on an embedded device with limited connectivity.

Now I will try to tidy up my config using your recomendation of redirecting centrally in entrypoints. Thank you very much for everything, it has been very useful!! :slight_smile:

That makes sense :slight_smile:

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.