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

https://docs.traefik.io/v2.1/routing/providers/docker/#routers

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

https://docs.traefik.io/v1.7/configuration/backends/docker/#on-containers


https://docs.traefik.io/v2.1/getting-started/configuration-overview/

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.

https://docs.traefik.io/v2.1/operations/dashboard/


.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!