What exactly are the requirements?

I'm using:
-- docker-compose (v3.7)
-- traefik 2.1.4
-- 6 custom services in the same docker-compose.yml

I'm replacing nginx-proxy, which lacked some needed features. I've been reading your docs for a while and they do not seem intuitive or complete. Often the docs have choice between YAML, TOML, and CLI - and when they leave out CLI, it isn't obvious if CLI (docker-compose practically) is supported or not.

I'm trying to keep all config in my ~/.env & docker-compose.yml. I cannot tell if a traefik-specific TOML is required or not. I think I've all required config in my docker-compose.yml - and I would like to keep it this way.

I'm getting 404s on the client side & msg="http: TLS handshake error from IP:random-port: remote error: tls: unknown certificate," on the server side.

I'm also trying to better differentiate between these two:
"traefik.http.routers.docker-service.entrypoints=https"
and
"traefik.frontend.entryPoints=https"

One more question:
When reading your documentation, how do you quickly differentiate between config that it is proposing to go under the "label" of each docker-compose service - and config that it is proposing go under the "command" section of the traefik service (in docker)?

Thanks for your help! :slight_smile:

P.S. One more thing: in your docs it talks about each docker service being auto-detected if it only has one "expose." Each of my services has one port via "ports:" - but I don't use expose. Is it safe to assume this is equivalent functionality?

P.P.S. Don't waste your time answering this if you don't have much time - but if this is all so programmatic, then I think it would be incredibly useful if traefik could print out an ascii diagram of the networking model it is assuming based on your setup. It doesn't have to be a diagram even - just a list of connections it is making through the front and back ends.

What is ".name" on https://docs.traefik.io/routing/entrypoints/ ? The provider's service name? In your docs you use 'web' sometimes and 'http' other times... I'm pulling my hair out now... Hoping for replies tomorrow morning.
Thanks :slight_smile:

It is very possible that I am stupid in comparison with the creators of Traefik. However, I wish you would use format that is more meaningful to non-experts in your docs! For example:
entryPoint.name-of-the-docker-service.transport(whatisthis?)...
or
traefik.http-is-traefik-related-or-a-variable.routers.name-of-docker-service.entrypoint-different-from-web-address-entrypoint=234234

Hello,

traefik.http.routers.docker-service.entrypoints=https is a lable for Traefik v2

traefik.frontend.entryPoints=https is a label for Traefik v1.


The labels are for defined the dynamic configuration

The CLI flags ("command") are for defined the static configuration


The dashboard allows to watch the relation between each element.


.name is the name of the entry point, an entry point is basically a port (80, 443, 8080, ...)

EntryPoints are the network entry points into Traefik. They define the port which will receive the requests (whether HTTP or TCP).

1 Like

So can an entire Traefik 2.0 configuration be done with a dynamic configuration? Or do all full Traefik configs require a TOML and/or YAML static file outside of the docker-compose.yml?

Roger that: "CLI" = "command" in docker world.

Thanks, I've since disabled 'frontend' labels in my Traefik 2.1.4 config.

I recommend to read my previous answer in details and the documentation behind the links that I provided.

To configure Traefik, you need dynamic configuration AND static configuration

version: '3.7'

services:
  traefik:
    image: traefik:v2.1.4
    container_name: traefik
    command:
      # Static configuration
      - --api
      - --log.level=INFO
      - --entryPoints.web.address=:80
      - --entryPoints.websecure.address=:443
      - --providers.docker.exposedByDefault=false
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

    labels:
      # Dynamic configuration
      traefik.enable: true

      traefik.http.routers.dashboard.rule: Host(`traefik.localhost`)
      traefik.http.routers.dashboard.service: api@internal
      traefik.http.routers.dashboard.entrypoints: web
  
  whoami:
    image: containous/whoami:v1.4.0

    labels:
      # Dynamic configuration
      traefik.enable: true

      traefik.http.routers.whoami.rule: Host(`example.localhost`)
      traefik.http.routers.whoami.entrypoints: websecure
      traefik.http.routers.whoami.tls: true

In addition to the links already referenced in the previous answer, I recommend that you read:

Great, I definitely read a lot of the docs, but I don't see where it says that... Thanks for answering the question directly. Now I'm off to figure out which are required in static - since I thought I had gotten all requirements into my dynamic config.

EDIT: now I realize from your example that "static configuration" doesn't necessarily mean a text file (TOML) but means the "static part" of the docker-compose.yml, which may actually have variables in it :slight_smile:
Perhaps a better differentiation would be 'runtime commands' and 'labels' instead of 'static' and 'dynamic' config - which all map to: docker-compose.yml, traefik.yml, and traefik.toml - right?
So in terms of how I was thinking: we don't actually need "both" (a TOML & a docker-compose.yml - the latter is enough). Whew!

@ldez OK, sorry, but I'm still stuck so I'm posting my config & debug output:

Here's my docker-compose.yml - its other 5 services have setup similarly as SERVICE 1:

version: "3.7"
services:
#SERVICE 1 -- Mainapp (on port 2000)
  dt:
    container_name: mainapp
    restart: always
    build: '.'
    ports:
      - "2000:2000"
    logging:
      driver: journald
      options:
        tag: "mainapp"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dt.rule=Host(`${DT_VHOST}`,`${DT_WWW_VHOST}`)"
      - "traefik.http.routers.dt.entrypoints=web,websecure"
#      - "traefik.http.middlewares.dt.compress=web"
#      - "traefik.docker.network=traefik"
      - "traefik.http.routers.dt.tls.certresolver=le"
      - "traefik.http.routers.dt.tls=true"
#      - "traefik.port=2000"
### I don't use swarm - only docker-compose, so not sure if 'loadbalancer' is necessary:
      - "traefik.http.services.dt.loadbalancer.server.port=2000"

#SERVICE 7 -- TRAEFIK
  traefik:
    image: "traefik:v2.1.4"
    restart: always
    container_name: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--accesslog=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--api=true"
      - "--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.le.acme.email=emailrep@gmail.com"
      - "--certificatesresolvers.le.acme.storage=/acme.json"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    logging:
      driver: journald
      options:
        tag: "traefik"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./acme.json:/acme.json"
    labels:
      # Dashboard
      - "traefik.http.routers.traefik.rule=Host(`${DASHBOARD_VHOST}`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=le"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.entrypoints=https"
      - "traefik.http.routers.traefik.middlewares=dashboard"
      - "traefik.http.middlewares.dashboard.basicauth.users=user:pass"
      - "traefik.http.middlewares.dashboard.compress=true"
      - "traefik.docker.network=traefik"

networks:
  default:
   external:
     name: traefik
volumes:
  acme.json:

I have no other config files (i.e. TOML) being used currently. And here is the Traefik debug output:

traefik     | time="2020-02-13T12:39:58Z" level=info msg="Account URI does not match the current CAServer. The account will be reset." providerName=le.acme
traefik     | time="2020-02-13T12:39:58Z" level=info msg="Starting provider aggregator.ProviderAggregator {}"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Start TCP Server" entryPointName=web
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Start TCP Server" entryPointName=websecure
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Start TCP Server" entryPointName=traefik
traefik     | time="2020-02-13T12:39:58Z" level=info msg="Starting provider *acme.Provider {\"email\":\"emailrep@gmail.com\",\"caServer\":\"https://acme-v02.api.letsencrypt.org/directory\",\"storage\":\"/acme.json\",\"keyType\":\"RSA4096\",\"tlsChallenge\":{},\"ResolverName\":\"le\",\"store\":{},\"ChallengeStore\":{}}"
traefik     | time="2020-02-13T12:39:58Z" level=info msg="Testing certificate renew..." providerName=le.acme
traefik     | time="2020-02-13T12:39:58Z" level=info msg="Starting provider *docker.Provider {\"watch\":true,\"endpoint\":\"unix:///var/run/docker.sock\",\"defaultRule\":\"Host(`{{ normalize .Name }}`)\",\"swarmModeRefreshSeconds\":15000000000}"
traefik     | time="2020-02-13T12:39:58Z" level=info msg="Starting provider *traefik.Provider {}"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Configuration received from provider le.acme: {\"http\":{},\"tls\":{}}" providerName=le.acme
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Configuration received from provider internal: {\"http\":{\"routers\":{\"api\":{\"entryPoints\":[\"traefik\"],\"service\":\"api@internal\",\"rule\":\"PathPrefix(`/api`)\",\"priority\":2147483646},\"dashboard\":{\"entryPoints\":[\"traefik\"],\"middlewares\":[\"dashboard_redirect@internal\",\"dashboard_stripprefix@internal\"],\"service\":\"dashboard@internal\",\"rule\":\"PathPrefix(`/`)\",\"priority\":2147483645}},\"middlewares\":{\"dashboard_redirect\":{\"redirectRegex\":{\"regex\":\"^(http:\\\\/\\\\/[^:\\\\/]+(:\\\\d+)?)\\\\/$\",\"replacement\":\"${1}/dashboard/\",\"permanent\":true}},\"dashboard_stripprefix\":{\"stripPrefix\":{\"prefixes\":[\"/dashboard/\",\"/dashboard\"]}}},\"services\":{\"api\":{},\"dashboard\":{}}},\"tcp\":{},\"tls\":{}}" providerName=internal
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Provider connection established with docker 19.03.5-ce (API 1.40)" providerName=docker
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Adding certificate for domain(s) ghost.domain.com"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Adding certificate for domain(s) services.domain.com"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Adding certificate for domain(s) admin.domain.com"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Adding certificate for domain(s) gql.domain.com"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Adding certificate for domain(s) domain.com,www.domain.com"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Adding certificate for domain(s) dashboard.domain.com"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="No default certificate, generating one"
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Filtering disabled container" providerName=docker container=mongo-emailrep-ee6fa3dd712a437946a4f81814841fad3ac68c065c1f704393dc34dd252896b8
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Filtering disabled container" providerName=docker container=traefik-emailrep-cc86222c38bf244adf9a78814b6b7756c647bfdc8625526027c6b7b4ab1ca74d
traefik     | time="2020-02-13T12:39:58Z" level=debug msg="Configuration received from provider docker: {\"http\":{\"routers\":{\"admin\":{\"entryPoints\":[\"websecure\"],\"service\":\"admin\",\"rule\":\"Host(`admin.domain.com`)\",\"tls\":{\"certResolver\":\"le\"}},\"dt\":{\"entryPoints\":[\"websecure\"],\"service\":\"dt\",\"rule\":\"Host(`domain.com`,`www.domain.com`)\",\"tls\":{\"certResolver\":\"le\"}},\"ghost\":{\"entryPoints\":[\"https\"],\"service\":\"ghost\",\"rule\":\"Host(`ghost.domain.com`)\",\"tls\":{\"certResolver\":\"le\"}},\"gql\":{\"entryPoints\":[\"websecure\"],\"service\":\"gql\",\"rule\":\"Host(`gql.domain.com`)\",\"tls\":{\"certResolver\":\"le\"}},\"services\":{\"entryPoints\":[\"websecure\"],\"service\":\"services\",\"rule\":\"Host(`services.domain.com`)\",\"tls\":{\"certResolver\":\"le\"}}},\"services\":{\"admin\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://172.22.0.6:5002\"}],\"passHostHeader\":true}},\"dt\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://172.22.0.2:2000\"}],\"passHostHeader\":true}},\"ghost\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://172.22.0.5:2368\"}],\"passHostHeader\":true}},\"gql\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://172.22.0.7:5000\"}],\"passHostHeader\":true}},\"services\":{\"loadBalancer\":{\"servers\":[{\"url\":\"http://172.22.0.3:5001\"}],\"passHostHeader\":true}}}},\"tcp\":{}}" providerName=docker
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="Adding certificate for domain(s) ghost.domain.com"
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="Adding certificate for domain(s) services.domain.com"
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="Adding certificate for domain(s) admin.domain.com"
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="Adding certificate for domain(s) gql.domain.com"
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="Adding certificate for domain(s) domain.com,www.domain.com"
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="Adding certificate for domain(s) dashboard.domain.com"
traefik     | time="2020-02-13T12:39:59Z" level=debug msg="No default certificate, generating one"

traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Added outgoing tracing middleware api@internal" middlewareName=tracing middlewareType=TracingForwarder entryPointName=traefik routerName=api@internal
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Added outgoing tracing middleware dashboard@internal" routerName=dashboard@internal entryPointName=traefik middlewareType=TracingForwarder middlewareName=tracing
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Creating middleware" middlewareType=StripPrefix entryPointName=traefik routerName=dashboard@internal middlewareName=dashboard_stripprefix@internal
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding tracing to middleware" routerName=dashboard@internal middlewareName=dashboard_stripprefix@internal entryPointName=traefik
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Creating middleware" entryPointName=traefik routerName=dashboard@internal middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Setting up redirection from ^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$ to ${1}/dashboard/" middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex entryPointName=traefik routerName=dashboard@internal
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding tracing to middleware" middlewareName=dashboard_redirect@internal entryPointName=traefik routerName=dashboard@internal
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Creating middleware" middlewareType=Recovery entryPointName=traefik middlewareName=traefik-internal-recovery
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding certificate for domain(s) ghost.domain.com"
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding certificate for domain(s) services.domain.com"
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding certificate for domain(s) admin.domain.com"
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding certificate for domain(s) gql.domain.com"
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding certificate for domain(s) domain.com,www.domain.com"
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="Adding certificate for domain(s) dashboard.domain.com"
traefik     | time="2020-02-13T12:40:00Z" level=debug msg="No default certificate, generating one"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Added outgoing tracing middleware api@internal" routerName=api@internal middlewareName=tracing middlewareType=TracingForwarder entryPointName=traefik
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Added outgoing tracing middleware dashboard@internal" entryPointName=traefik routerName=dashboard@internal middlewareName=tracing middlewareType=TracingForwarder
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" entryPointName=traefik routerName=dashboard@internal middlewareName=dashboard_stripprefix@internal middlewareType=StripPrefix
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Adding tracing to middleware" entryPointName=traefik routerName=dashboard@internal middlewareName=dashboard_stripprefix@internal
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" entryPointName=traefik routerName=dashboard@internal middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Setting up redirection from ^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$ to ${1}/dashboard/" routerName=dashboard@internal middlewareName=dashboard_redirect@internal middlewareType=RedirectRegex entryPointName=traefik
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Adding tracing to middleware" entryPointName=traefik routerName=dashboard@internal middlewareName=dashboard_redirect@internal
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=traefik
traefik     | time="2020-02-13T12:40:01Z" level=error msg="entryPoint \"https\" doesn't exist" routerName=ghost@docker entryPointName=https
traefik     | time="2020-02-13T12:40:01Z" level=error msg="no valid entryPoint for this router" routerName=ghost@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" middlewareName=pipelining entryPointName=websecure routerName=dt@docker serviceName=dt middlewareType=Pipelining
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating load-balancer" entryPointName=websecure routerName=dt@docker serviceName=dt
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating server 0 http://172.22.0.2:2000" routerName=dt@docker serverName=0 serviceName=dt entryPointName=websecure
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Added outgoing tracing middleware dt" routerName=dt@docker middlewareName=tracing middlewareType=TracingForwarder entryPointName=websecure
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" entryPointName=websecure routerName=gql@docker serviceName=gql middlewareName=pipelining middlewareType=Pipelining
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating load-balancer" entryPointName=websecure routerName=gql@docker serviceName=gql
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating server 0 http://172.22.0.7:5000" serverName=0 entryPointName=websecure routerName=gql@docker serviceName=gql
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Added outgoing tracing middleware gql" entryPointName=websecure routerName=gql@docker middlewareName=tracing middlewareType=TracingForwarder
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" serviceName=services middlewareName=pipelining middlewareType=Pipelining entryPointName=websecure routerName=services@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating load-balancer" entryPointName=websecure routerName=services@docker serviceName=services
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating server 0 http://172.22.0.3:5001" entryPointName=websecure routerName=services@docker serviceName=services serverName=0
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Added outgoing tracing middleware services" entryPointName=websecure routerName=services@docker middlewareName=tracing middlewareType=TracingForwarder
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" entryPointName=websecure routerName=admin@docker serviceName=admin middlewareName=pipelining middlewareType=Pipelining
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating load-balancer" serviceName=admin entryPointName=websecure routerName=admin@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating server 0 http://172.22.0.6:5002" serviceName=admin serverName=0 entryPointName=websecure routerName=admin@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Added outgoing tracing middleware admin" entryPointName=websecure routerName=admin@docker middlewareName=tracing middlewareType=TracingForwarder
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Creating middleware" middlewareName=traefik-internal-recovery middlewareType=Recovery entryPointName=websecure
traefik     | time="2020-02-13T12:40:01Z" level=error msg="entryPoint \"https\" doesn't exist" routerName=ghost@docker entryPointName=https
traefik     | time="2020-02-13T12:40:01Z" level=error msg="no valid entryPoint for this router" routerName=ghost@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Try to challenge certificate for domain [gql.domain.com] found in HostSNI rule" providerName=le.acme routerName=gql@docker rule="Host(`gql.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Try to challenge certificate for domain [services.domain.com] found in HostSNI rule" providerName=le.acme rule="Host(`services.domain.com`)" routerName=services@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Try to challenge certificate for domain [admin.domain.com] found in HostSNI rule" providerName=le.acme routerName=admin@docker rule="Host(`admin.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Try to challenge certificate for domain [domain.com www.domain.com] found in HostSNI rule" providerName=le.acme routerName=dt@docker rule="Host(`domain.com`,`www.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Try to challenge certificate for domain [ghost.domain.com] found in HostSNI rule" providerName=le.acme routerName=ghost@docker rule="Host(`ghost.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Looking for provided certificate(s) to validate [\"ghost.domain.com\"]..." providerName=le.acme routerName=ghost@docker rule="Host(`ghost.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Looking for provided certificate(s) to validate [\"gql.domain.com\"]..." rule="Host(`gql.domain.com`)" providerName=le.acme routerName=gql@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="No ACME certificate generation required for domains [\"gql.domain.com\"]." routerName=gql@docker rule="Host(`gql.domain.com`)" providerName=le.acme
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Looking for provided certificate(s) to validate [\"services.domain.com\"]..." providerName=le.acme rule="Host(`services.domain.com`)" routerName=services@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="No ACME certificate generation required for domains [\"services.domain.com\"]." providerName=le.acme rule="Host(`services.domain.com`)" routerName=services@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Looking for provided certificate(s) to validate [\"admin.domain.com\"]..." providerName=le.acme routerName=admin@docker rule="Host(`admin.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="No ACME certificate generation required for domains [\"admin.domain.com\"]." rule="Host(`admin.domain.com`)" providerName=le.acme routerName=admin@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="Looking for provided certificate(s) to validate [\"domain.com\" \"www.domain.com\"]..." rule="Host(`domain.com`,`www.domain.com`)" providerName=le.acme routerName=dt@docker
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="No ACME certificate generation required for domains [\"domain.com\" \"www.domain.com\"]." providerName=le.acme routerName=dt@docker rule="Host(`domain.com`,`www.domain.com`)"
traefik     | time="2020-02-13T12:40:01Z" level=debug msg="No ACME certificate generation required for domains [\"ghost.domain.com\"]." rule="Host(`ghost.domain.com`)" providerName=le.acme routerName=ghost@docker

And the error, when I try to visit the server from my browser:

traefik     | time="2020-02-13T12:40:21Z" level=debug msg="http: TLS handshake error from 37.83.100.1:50912: remote error: tls: unknown certificate"
traefik     | time="2020-02-13T12:40:22Z" level=debug msg="http: TLS handshake error from 37.83.100.1:50914: remote error: tls: unknown certificate"

Nothing else in my env except for .env which supplies ${DT_VHOST} - is anything else needed to figure this out? In terms of resolvers, we only need either DNS or TLS or HTTP challenge, right?

Thanks a lot for your help!

version: "3.7"

services:
#SERVICE 1 -- Mainapp (on port 2000)
  dt:
    container_name: mainapp
    restart: always
    build: '.'
    ports:
      - "2000:2000"
    logging:
      driver: journald
      options:
        tag: "mainapp"
    labels:
      - "traefik.enable=true"

      - "traefik.http.routers.dt.rule=Host(`${DT_VHOST}`,`${DT_WWW_VHOST}`)"
      - "traefik.http.routers.dt.entrypoints=websecure"
      - "traefik.http.routers.dt.tls.certresolver=le"
      - "traefik.http.services.dt.loadbalancer.server.port=2000"

#SERVICE 7 -- TRAEFIK
  traefik:
    image: "traefik:v2.1.4"
    restart: always
    container_name: "traefik"
    command:
      - "--log.level=INFO"
      - "--accesslog=true"
      - "--api=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.le.acme.email=emailrep@gmail.com"
      - "--certificatesresolvers.le.acme.storage=/acme.json"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
    ports:
      - "80:80"
      - "443:443"
    logging:
      driver: journald
      options:
        tag: "traefik"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./acme.json:/acme.json"
    labels:
      - "traefik.enable=true"

      # Dashboard
      - "traefik.http.routers.traefik.rule=Host(`${DASHBOARD_VHOST}`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=le"
      - "traefik.http.routers.traefik.middlewares=api_auth"

      - "traefik.http.middlewares.api_auth.basicauth.users=user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/" # user / password

networks:
  default:
   external:
     name: traefik

I don't know what did it exactly, but that seems to have solved it! I think I was also not changing the staging acme.json when moving to production acme.json certs - and then wondering why it wasn't working in my browser too... (This helped me realize that issue: Account URI does not match the current CAServer. The account will be reset )

One thing I'm concerned about is the Traefik logs show internal IPs. In my production instance, which is still running nginx-proxy, the access logs all show my domain name(s).
But it is working! Thanks a lot!