Custom SSL (TLS) configuration with docker

docker-compose

services:

  traefik:
    image: "traefik:v2.11"
    container_name: "traefik"
    restart: always
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.file.directory=/etc/traefik/dynamic"
      - "--providers.file.watch=true"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
      - "--accesslog=true"
      - "--accesslog.filepath=/access.log"
      - "--entrypoints.websecure.http.tls.certResolver=leresolver"
      - "--entrypoints.websecure.http.tls.domains[0].main=example.dev"
      - "--entrypoints.websecure.http.tls.domains[0].sans=traefik.example.dev,*.example.dev"

    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./tls.toml:/etc/traefik/dynamic/tls.toml"
      - "/etc/nginx/cert/:/etc/certs/"
      - "./access.log:/access.log"

    networks:
      - proxynet
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`traefik.example.dev`) || Host(`example.dev`)"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.tls=true"
      - "traefik.http.routers.api.entrypoints=https"
  whoami:
    image: "traefik/whoami"
    container_name: "whoami"
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.dev`)"
      - "traefik.http.routers.whoami.entrypoints=https"
      - "traefik.http.routers.whoami.tls=true"
    networks:
      - proxynet

networks:

  proxynet:
    external: true

tls.toml

[[tls.certificates]]
        certFile = "/etc/certs/example_dev_chain.crt"
        keyFile  = "/etc/certs/example_dev.pem"
        stores = ["default"]

Why i can access to example.dev, but have HSTS error on traefik.example.dev and DNS PROBE finished NXdomain on whoami.example.dev?

You have to register sub-domains with your DNS provider to point to your Traefik IP. It’s not enough to create a router in Traefik.

TLS key file is usually not named .pem. The file content has "key" in it. The cert has the chain and usually consists of 3 sections. This is used for custom (paid for) TLS certificates. On entrypoint or router enabled via tls=true.

If you use certResolver=leresolver for Traefik LetsEncrypt, then it needs to be defined and assigned. Check simple Traefik example.

And usually we try to stick to one format for consistency, not mix yaml with toml.

Thanks for reply,

  1. I have dns record with dynamic subdomain. (A record with * pointing to traefik server IP)
  2. in my case i have two file one is chain.crt and other domain_name.pem, and u are right it is paid certificate and it was working fine with NGINX.

All I want is store cert and key in somewhere and use it to all possible routes

If you just want your custom TLS, then enable TLS on entrypoint once, not needed again on routers. No certresolver needed.

Load certs from dynamic config file via providers.file in static config. That looks ok.

"Nxdomain" clearly indicates to me, that the sub-domain can not be resolved by DNS provider. Did you try a simple ping?

Thanks for your time,

version: "3.8"

services:

  traefik:
    image: "traefik:v2.11"
    container_name: "traefik"
    restart: always
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.file.directory=/etc/traefik/dynamic"
      - "--providers.file.watch=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--accesslog=true"
      - "--accesslog.filepath=/access.log"
      - "--entrypoints.websecure.http.tls=true"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./tls.toml:/etc/traefik/dynamic/tls.toml"
      - "/etc/nginx/cert/:/etc/certs/"

    networks:
      - proxynet
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`traefik.example.dev`) || Host(`example.dev`)"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.entrypoints=websecure"
  whoami:
    image: "traefik/whoami"
    container_name: "whoami"
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`work.example.pro`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"
     
    networks:
      - proxynet

networks:

  proxynet:
    external: true

with above configs,
i can access example.dev
but im getting page not secured on traefik.example.dev (because .dev needs SSL) (more correctly NET::ERR_CERT_AUTHORITY_INVALID)
and 404 not found - default page from traefik at work.example.pro

For sub-domains to work with custom TLS, you need multiple certs, one for every (sub-)domain or a wildcard cert. Traefik will automatically match requests with the domains of the certs.

Or you enable Traefik LetsEncrypt and it will create a LE TLS cert for you, based on Host(). Make sure to persist acme.json to bind mount or volume. Limit is 50 domains per week.

With more complicated dnsChallenge you can even create wildcard certs with LE, using main and sans.

Okay,
after changing tls.yaml file to

tls:
  stores:
    default:
      defaultCertificate:
        certFile: /etc/certs/example_dev_chain.crt
        keyFile: /etc/certs/example_dev.pem

now it shows
ERR_CERT_COMMON_NAME_INVALID

Do you knowthat is it possible to manually tell to all subdomains to use default certificate?
in NGINX it was possible

Yes, you can declare a custom TLS cert as default, see doc.

I am sorry but lets encrypt certifications not working, I dont get what is wrong

services:

  traefik:
    image: "traefik:v3.0"
    container_name: "traefik"
    restart: always
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=proxynet"
      
      - "--providers.file.watch=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--accesslog=true"
      - "--accesslog.filepath=/access.log"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entryPoints.web.http.redirections.entrypoint.scheme=https"
     
      - "--entrypoints.websecure.http.tls.certresolver=myresolver"
      - "--certificatesresolvers.myresolver.acme.email=mq.hamdam@gmail.com"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      

    networks:
      - proxynet
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`traefik.example.dev`) || Host(`example.dev`)"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.tls.certresolver=myresolver"
      - "traefik.http.routers.api.tls=true"
      - "traefik.http.routers.api.entrypoints=websecure"

  whoami:
    image: "traefik/whoami"
    container_name: "whoami"
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.tls.certresolver=myresolver"
      - "traefik.http.routers.whoami.rule=Host(`work.example.pro`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"
      - "traefik.http.routers.whoami.tls=true"
    networks:
      - proxynet

networks:

  proxynet:
    external: true

could please take look at this?
i see that letsencrypt folder is created and i see acme.json file

Now Im getting NET::ERR_CERT_AUTHORITY_INVALID for all 3 pages

NET::ERR_CERT_AUTHORITY_INVALID
Subject: TRAEFIK DEFAULT CERT

Issuer: TRAEFIK DEFAULT CERT

Expires on: 2025. 3. 11.

Current date: 2024. 3. 11.

My bad forgot to mount letsencrypt folder. It is working now, all 3pages are visible

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